[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Minios-devel] [UNIKRAFT/CLICK PATCH 06/11] Initial public release: FromDevice and ToDevice



Hi Florian,

This patch looks good.

Thanks,

-- Felipe

Reviewed-by: Felipe Huici <felipe.huici@xxxxxxxxx>

On 02.06.19, 07:53, "Florian Schmidt" <Florian.Schmidt@xxxxxxxxx> wrote:

    The rough concept is taken from kohler/click/elements/minios, but is
    then adapted to use unikraft instead of Mini-OS.
    
    Signed-off-by: Florian Schmidt <florian.schmidt@xxxxxxxxx>
    ---
     unikraft/fromdevice.cc | 203 +++++++++++++++++++++++++++++++++++++++++
     unikraft/fromdevice.hh |  79 ++++++++++++++++
     unikraft/todevice.cc   | 131 ++++++++++++++++++++++++++
     unikraft/todevice.hh   |  76 +++++++++++++++
     4 files changed, 489 insertions(+)
     create mode 100644 unikraft/fromdevice.cc
     create mode 100644 unikraft/fromdevice.hh
     create mode 100644 unikraft/todevice.cc
     create mode 100644 unikraft/todevice.hh
    
    diff --git a/unikraft/fromdevice.cc b/unikraft/fromdevice.cc
    new file mode 100644
    index 0000000..d50ff4f
    --- /dev/null
    +++ b/unikraft/fromdevice.cc
    @@ -0,0 +1,203 @@
    +/* SPDX-License-Identifier: BSD-3-Clause */
    +/*
    + * Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation.
    + *               All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + *
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + * 3. Neither the name of the copyright holder nor the names of its
    + *    contributors may be used to endorse or promote products derived from
    + *    this software without specific prior written permission.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
IS"
    + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
THE
    + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
PURPOSE
    + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
BE
    + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
THE
    + * POSSIBILITY OF SUCH DAMAGE.
    + *
    + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
    + */
    +
    +#include "fromdevice.hh"
    +
    +#include <click/args.hh>
    +#include <click/deque.hh>
    +#include <click/error.hh>
    +#include <click/standard/scheduleinfo.hh>
    +#include <click/task.hh>
    +#include <uk/netdev.h>
    +
    +#ifdef xmit
    +#undef xmit
    +#endif
    +#ifdef recv
    +#undef recv
    +#endif
    +
    +#include <uk/alloc.h>
    +#include <uk/netdev.h>
    +
    +CLICK_DECLS
    +
    +#define DESC_COUNT 0x100
    +#define BUFSIZE 2048
    +
    +FromDevice::FromDevice()
    +   : _task(this)
    +{
    +}
    +
    +FromDevice::~FromDevice()
    +{
    +}
    +
    +int
    +FromDevice::configure(Vector<String> &conf, ErrorHandler *errh)
    +{
    +   _devid = 0;
    +
    +   uk_pr_info("FromDevice::configure %p\n", this);
    +   if (Args(conf, this, errh)
    +                   .read_p("DEVID", IntArg(), _devid)
    +                   .complete() < 0)
    +           return -1;
    +
    +   if (_devid < 0)
    +           return errh->error("Device ID must be >= 0");
    +
    +   _dev = uk_netdev_get((unsigned int) _devid);
    +   if (!_dev)
    +           return errh->error("No such device %d", _devid);
    +   uk_netdev_info_get(_dev, &_dev_info);
    +
    +   return 0;
    +}
    +
    +extern "C" void
    +click_fromdevice_rx_callback(struct uk_netdev *dev __unused, /* we have all
    +                           the information we need via the cookie */
    +           uint16_t queue_id, void *cookie)
    +{
    +   FromDevice *fromdevice = (FromDevice *)cookie;
    +
    +   uk_pr_debug("FromDevice %p queue %u callback\n", cookie, queue_id);
    +   fromdevice->take_packets();
    +}
    +
    +uint16_t
    +FromDevice::netdev_alloc_rxpkts(void *argp, struct uk_netbuf *pkts[],
    +           uint16_t count)
    +{
    +   int i;
    +
    +   FromDevice *fd = static_cast<FromDevice *>(argp);
    +   for (i = 0; i < count; ++i) {
    +           pkts[i] = uk_netbuf_alloc_buf(uk_alloc_get_default(),
    +                           BUFSIZE, fd->_dev_info.nb_encap_rx, 0, NULL);
    +           if (!pkts[i])
    +                   return i;
    +           pkts[i]->len = BUFSIZE;
    +   }
    +   return count;
    +}
    +
    +int
    +FromDevice::initialize(ErrorHandler *errh)
    +{
    +   struct uk_netdev_info dinf;
    +   struct uk_netdev_rxqueue_conf rx_conf;
    +   struct uk_netdev_txqueue_conf tx_conf;
    +   int rc;
    +
    +   uk_pr_info("FromDevice::initialize %p device %p state %d\n",
    +                   this, _dev, _dev->_data->state);
    +   uk_netdev_info_get(_dev, &dinf);
    +   rx_conf.s = uk_sched_get_default();
    +   rx_conf.a = uk_alloc_get_default();
    +   rx_conf.callback = click_fromdevice_rx_callback;
    +   rx_conf.callback_cookie = (void *)(this);
    +   rx_conf.alloc_rxpkts = &FromDevice::netdev_alloc_rxpkts;
    +   rx_conf.alloc_rxpkts_argp = this;
    +   if (uk_netdev_rxq_configure(_dev, 0, DESC_COUNT, &rx_conf))
    +           return errh->error("Failed to set up RX queue for device %d", 
_devid);
    +   tx_conf.a = uk_alloc_get_default();
    +   if (uk_netdev_txq_configure(_dev, 0, DESC_COUNT, &tx_conf))
    +           return errh->error("Failed to set up TX queue for device %d", 
_devid);
    +   if (uk_netdev_start(_dev))
    +           return errh->error("Failed to start device %d", _devid);
    +   rc = uk_netdev_rxq_intr_enable(_dev, 0);
    +           if (rc < 0)
    +                   return errh->error("Failed to set up RX queue interrupt 
for device %d", _devid);
    +           else if (rc > 0)
    +                   take_packets(); // empty the queue to enable interrupt
    +   ScheduleInfo::initialize_task(this, &_task, errh);
    +   _task.reschedule();
    +   return 0;
    +
    +}
    +
    +void
    +FromDevice::cleanup(CleanupStage stage)
    +{
    +   if (stage >= CLEANUP_INITIALIZED) {
    +           uk_netdev_rxq_intr_disable(_dev, 0);
    +   }
    +}
    +
    +void
    +FromDevice::take_packets()
    +{
    +   int ret;
    +   int i = 0;
    +   struct uk_netbuf *buf = NULL;
    +   Packet *p;
    +
    +   do {
    +           ret = uk_netdev_rx_one(_dev, 0, &buf);
    +           if (ret < 0)
    +                   UK_CRASH("error receiving packets in FromDevice");
    +           if (uk_netdev_status_notready(ret)) {
    +                   /* No (more) packets received */
    +                   break;
    +           }
    +
    +           ++i;
    +           p = Packet::make(0, buf->data, buf->len, 0);
    +           p->set_timestamp_anno(Timestamp::now());
    +           output(0).push(p); /* memcpy's pkt */
    +           uk_netbuf_free(buf);
    +   } while (uk_netdev_status_more(ret));
    +   if (i)
    +           uk_pr_debug("took %d packets from the queue\n", i);
    +}
    +
    +bool
    +FromDevice::run_task(Task *)
    +{
    +   /* if you're really desperate for less CPU usage
    +    * until we have a proper blocking select()...
    +   struct timespec req;
    +   req.tv_sec = 0;
    +   req.tv_nsec = 1000000;
    +   nanosleep(&req, NULL);
    +   */
    +   uk_sched_yield();
    +   _task.reschedule();
    +   return false;
    +}
    +
    +CLICK_ENDDECLS
    +EXPORT_ELEMENT(FromDevice)
    diff --git a/unikraft/fromdevice.hh b/unikraft/fromdevice.hh
    new file mode 100644
    index 0000000..8d62a95
    --- /dev/null
    +++ b/unikraft/fromdevice.hh
    @@ -0,0 +1,79 @@
    +/* SPDX-License-Identifier: BSD-3-Clause */
    +/*
    + * Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation.
    + *               All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + *
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + * 3. Neither the name of the copyright holder nor the names of its
    + *    contributors may be used to endorse or promote products derived from
    + *    this software without specific prior written permission.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
IS"
    + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
THE
    + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
PURPOSE
    + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
BE
    + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
THE
    + * POSSIBILITY OF SUCH DAMAGE.
    + *
    + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
    + */
    +
    +#ifndef CLICK_FROMDEVICE_HH
    +#define CLICK_FROMDEVICE_HH
    +
    +#include <click/config.h>
    +#include <click/deque.hh>
    +#include <click/element.hh>
    +#include <click/error.hh>
    +#include <click/task.hh>
    +
    +#include <uk/netdev.h>
    +
    +CLICK_DECLS
    +
    +extern "C" {
    +    struct uk_netdev;
    +}
    +
    +class FromDevice : public Element {
    +public:
    +    FromDevice();
    +    ~FromDevice();
    +
    +    const char *class_name() const { return "FromDevice"; }
    +    const char *port_count() const { return "0/1"; }
    +    const char *processing() const { return "/h"; }
    +    int configure_phase() const { return CONFIGURE_PHASE_FIRST; }
    +
    +    int configure(Vector<String> &, ErrorHandler *);
    +    int initialize(ErrorHandler *);
    +    void cleanup(CleanupStage);
    +
    +    bool run_task(Task *);
    +    void take_packets();
    +
    +private:
    +    static uint16_t netdev_alloc_rxpkts(void *argp, struct uk_netbuf 
*pkts[], uint16_t count);
    +
    +    Task _task;
    +    Deque<Packet*> _deque;
    +    int _devid;
    +    struct uk_netdev *_dev;
    +    struct uk_netdev_info _dev_info;
    +};
    +
    +CLICK_ENDDECLS
    +#endif
    diff --git a/unikraft/todevice.cc b/unikraft/todevice.cc
    new file mode 100644
    index 0000000..f5d750d
    --- /dev/null
    +++ b/unikraft/todevice.cc
    @@ -0,0 +1,131 @@
    +/* SPDX-License-Identifier: BSD-3-Clause */
    +/*
    + * Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation.
    + *               All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + *
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + * 3. Neither the name of the copyright holder nor the names of its
    + *    contributors may be used to endorse or promote products derived from
    + *    this software without specific prior written permission.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
IS"
    + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
THE
    + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
PURPOSE
    + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
BE
    + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
THE
    + * POSSIBILITY OF SUCH DAMAGE.
    + *
    + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
    + */
    +
    +#include "todevice.hh"
    +
    +#include <click/args.hh>
    +#include <click/error.hh>
    +#include <click/router.hh>
    +#include <click/standard/scheduleinfo.hh>
    +#include <click/task.hh>
    +#include <stdio.h>
    +
    +#ifdef xmit
    +#undef xmit
    +#endif
    +#ifdef recv
    +#undef recv
    +#endif
    +
    +#include <uk/alloc.h>
    +#include <uk/netdev.h>
    +
    +CLICK_DECLS
    +
    +ToDevice::ToDevice()
    +   : _task(this)
    +{
    +}
    +
    +ToDevice::~ToDevice()
    +{
    +}
    +
    +int
    +ToDevice::configure(Vector<String> &conf, ErrorHandler *errh)
    +{
    +   _devid = 0;
    +
    +   uk_pr_info("ToDevice::configure %p\n", this);
    +   if (Args(conf, this, errh)
    +                   .read_p("DEVID", IntArg(), _devid)
    +                   .complete() < 0)
    +           return -1;
    +
    +   if (_devid < 0)
    +           return errh->error("Device ID must be >= 0");
    +
    +   _dev = uk_netdev_get((unsigned int) _devid);
    +   if (!_dev)
    +           return errh->error("No such device %d", _devid);
    +   uk_netdev_info_get(_dev, &_dev_info);
    +
    +   return 0;
    +}
    +
    +int
    +ToDevice::initialize(ErrorHandler *errh __unused)
    +{
    +   /* uk netdev is initialized in the corresponding FromDevice */
    +   return 0;
    +}
    +
    +void
    +ToDevice::cleanup(CleanupStage stage __unused)
    +{
    +   /* any potentially necessary uk netdev cleanup is done in the
    +    * corresponding FromDevice
    +    */
    +}
    +
    +void
    +ToDevice::push(int port, Packet *p)
    +{
    +   int ret;
    +   struct uk_netbuf *buf;
    +
    +   uk_pr_debug("push() packet %p (len %u) -> %d\n", p, p->length(), port);
    +   buf = uk_netbuf_alloc_buf(uk_alloc_get_default(),
    +                   p->length()+_dev_info.nb_encap_rx,
    +                   _dev_info.nb_encap_rx, 0, NULL);
    +   if (!buf) {
    +           uk_pr_crit("Failed to allocate netbuf for sending");
    +           return;
    +   }
    +   memcpy(buf->data, p->data(), p->length());
    +   buf->len = p->length();
    +   do {
    +           ret = uk_netdev_tx_one(_dev, 0, buf);
    +   } while (uk_netdev_status_notready(ret));
    +   checked_output_push(port, p);
    +}
    +
    +bool
    +ToDevice::run_task(Task *)
    +{
    +   /* no regular task scheduling needed, all work is done in push () */
    +   return false;
    +}
    +
    +CLICK_ENDDECLS
    +EXPORT_ELEMENT(ToDevice)
    diff --git a/unikraft/todevice.hh b/unikraft/todevice.hh
    new file mode 100644
    index 0000000..38ef7bb
    --- /dev/null
    +++ b/unikraft/todevice.hh
    @@ -0,0 +1,76 @@
    +/* SPDX-License-Identifier: BSD-3-Clause */
    +/*
    + * Copyright (c) 2019, NEC Laboratories Europe GmbH, NEC Corporation.
    + *               All rights reserved.
    + *
    + * Redistribution and use in source and binary forms, with or without
    + * modification, are permitted provided that the following conditions
    + * are met:
    + *
    + * 1. Redistributions of source code must retain the above copyright
    + *    notice, this list of conditions and the following disclaimer.
    + * 2. Redistributions in binary form must reproduce the above copyright
    + *    notice, this list of conditions and the following disclaimer in the
    + *    documentation and/or other materials provided with the distribution.
    + * 3. Neither the name of the copyright holder nor the names of its
    + *    contributors may be used to endorse or promote products derived from
    + *    this software without specific prior written permission.
    + *
    + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
IS"
    + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
THE
    + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
PURPOSE
    + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
BE
    + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
THE
    + * POSSIBILITY OF SUCH DAMAGE.
    + *
    + * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
    + */
    +
    +#ifndef CLICK_TODEVICE_HH
    +#define CLICK_TODEVICE_HH
    +
    +#include <click/config.h>
    +#include <click/element.hh>
    +#include <click/error.hh>
    +#include <click/task.hh>
    +
    +#include <uk/netdev.h>
    +
    +CLICK_DECLS
    +
    +extern "C" {
    +    struct uk_netdev;
    +}
    +
    +class ToDevice : public Element {
    +public:
    +    ToDevice();
    +    ~ToDevice();
    +
    +    const char *class_name() const { return "ToDevice"; }
    +    const char *port_count() const { return "1/0-1"; }
    +    const char *processing() const { return "a/h"; }
    +    int configure_phase() const { return CONFIGURE_PHASE_FIRST; }
    +
    +    int configure(Vector<String> &, ErrorHandler *);
    +    int initialize(ErrorHandler *);
    +    void cleanup(CleanupStage);
    +
    +    bool run_task(Task *);
    +    void push(int, Packet *p);
    +
    +private:
    +    Task _task;
    +
    +    int _devid;
    +    struct uk_netdev *_dev;
    +    struct uk_netdev_info _dev_info;
    +};
    +
    +CLICK_ENDDECLS
    +#endif
    -- 
    2.21.0
    
    

_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.