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

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



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>
Reviewed-by: Felipe Huici <felipe.huici@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®.