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

[Minios-devel] [UNIKRAFT PATCH v2 07/12] plat/xen/drivers/net: Configure netfront tx queue


  • To: minios-devel@xxxxxxxxxxxxx
  • From: Costin Lupu <costin.lupu@xxxxxxxxx>
  • Date: Mon, 1 Apr 2019 16:42:47 +0300
  • Cc: felipe.huici@xxxxxxxxx, Razvan Cojocaru <razvan.cojocaru93@xxxxxxxxx>, Florian.Schmidt@xxxxxxxxx, sharan.santhanam@xxxxxxxxx, simon.kuenzer@xxxxxxxxx, yuri.volchkov@xxxxxxxxx
  • Delivery-date: Mon, 01 Apr 2019 13:43:07 +0000
  • Ironport-phdr: 9a23:OV+unR018NFe6pr5smDT+DRfVm0co7zxezQtwd8ZsesXIv7xwZ3uMQTl6Ol3ixeRBMOHsqoC2rad7fyocFdDyK7JiGoFfp1IWk1NouQttCtkPvS4D1bmJuXhdS0wEZcKflZk+3amLRodQ56mNBXdrXKo8DEdBAj0OxZrKeTpAI7SiNm82/yv95HJbAhEmSaxbal2IRi5ognct8YbipZ+J6gszRfEvmFGcPlMy2NyIlKTkRf85sOu85Nm7i9dpfEv+dNeXKvjZ6g3QqBWAzogM2Au+c3krgLDQheV5nsdSWoZjBxFCBXY4R7gX5fxtiz6tvdh2CSfIMb7Q6w4VSik4qx2UxLjljsJOCAl/2HWksxwjbxUoBS9pxxk3oXYZJiZOOdicq/BeN8XQ3dKUMRMWCxbGo6yb5UBAfcPM+hbqIfypVUOoACiCQWwHu7j1iVFimPq0aA8zu8vERvG3AslH98WrnnUq871NLsTUeCz0aLGyyjDb+tL2Tzg74XHbhchoeqQXbJxd8rd000vFx7djlWNsoHqIyiV2v4Vs2iG9OVsT/ivi2k+pgx3vzOhxd8sh5HUio8a11zI7yZ0zYYvKdGmVkJ2Y8SoHZVIuy2HOIZ6X9kuTmJotSog1LELt5C2cDIXxJko2RLSbeGMfZKS7RL5TumRJC91hHdieL2imRm/6VOgyujgVsms11ZKszZFnsHMtn8T0xzT7dCKSuV4/ki72DaP0xrf5f1fIUwujarbNoUuzqQqlpoUqUjDHyn2l1vqjKKOa0kp9fWk5/7kb7jmvJOQKZF4hwPkPqkggsC/BP43MgkKX2iV4+S807jj8FXlT7VNlf02jqjZsJbAKcQfu665GxJV350/5BakFTumyMkYkmIdIFJffxKLl5LpNE3WIPDkEfe/hEyhkC1xyPHHIL3uGJPNImLfn7fmf7Z97FJTxxApzdBC459ZBKoMIP32WkDrtdzYCgU1PBCzw+biEN99zJ8RWXqTAq+FN6PfqVqI5uMpI+mNY48Voy/xJOU76P7wk3A5nUQQfa2o3ZsMdHC4Be5qIkqHbnrqmNsBFn0KvgUmRuzwlFKCSSJTZ2q1X68k5j87DIWmDZ3CRo+3hryNxjq1EYFWZmBDC1CDDGvoep6CW/gSdC2SJtVunSceWbe/Vo8rzQuuuxPiy7p7MurU/TUVtZz929hx5u3TjQ89+SZ0D8SA0mGCU2B0k3gORzAowK9/pVZyxUyZ3admnvxSDcZT6O9RUgcmKZ7cyPR3C8vyWg3bZNeGUlCmTs+9AT4rSNIx398ObFx7G9q4ixDOxCyqDKEJmLyPHpM76bjQ0GbsJ8xl0XbJyLEhj0U6QstILWCmna9/9w3UB47PiUmZlLuqeroa3C/M6miD13GDvEdGXwFsVaXKR2sQalHIotTk/knCVaOhCaw7Mgtdzs6PMqtLasDzjVVHXvvjJtPeY2atlGewBhaIwa2MYZHse2oDwCrdDFILnBsJ8XmYKAhtThum9mffCj1pDhfjbl3h9cF6qWinVQkkwgfMaFduhJSv/RtArvuHV/IVlpYZoDpp/z5zB0q82ZTSFsKdjwF6Or1Ba5Un5wEUhiriqwVhM8n4fOhZjVkEflEy5hu22g==
  • Ironport-sdr: +ddlj70RuxqYfW/8icm7viGnOa0iJ9HVjm0Vks3SR/30LCCLxkzRdJauUyIEXhqonGvRy2yAkm ByEwNAHzvfHw==
  • List-id: Mini-os development list <minios-devel.lists.xenproject.org>

Netfront tx queues use Xen shared rings. The ids for each request issued
by netfront for netback are retrieved from a limited sized list of
free ids.

Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
Signed-off-by: Razvan Cojocaru <razvan.cojocaru93@xxxxxxxxx>
---
 plat/xen/drivers/net/netfront.c | 107 ++++++++++++++++++++++++++++++++++++++++
 plat/xen/drivers/net/netfront.h |  30 +++++++++++
 2 files changed, 137 insertions(+)

diff --git a/plat/xen/drivers/net/netfront.c b/plat/xen/drivers/net/netfront.c
index dff667af..e810aefd 100644
--- a/plat/xen/drivers/net/netfront.c
+++ b/plat/xen/drivers/net/netfront.c
@@ -33,10 +33,12 @@
  * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
  */
 
+#include <string.h>
 #include <uk/assert.h>
 #include <uk/print.h>
 #include <uk/alloc.h>
 #include <uk/netdev_driver.h>
+#include <xen-x86/mm.h>
 #include <xenbus/xenbus.h>
 #include "netfront.h"
 #include "netfront_xb.h"
@@ -49,6 +51,83 @@
 
 static struct uk_alloc *drv_allocator;
 
+
+static void add_id_to_freelist(uint16_t id, uint16_t *freelist)
+{
+       freelist[id + 1] = freelist[0];
+       freelist[0]  = id;
+}
+
+static uint16_t get_id_from_freelist(uint16_t *freelist)
+{
+       uint16_t id;
+
+       id = freelist[0];
+       freelist[0] = freelist[id + 1];
+       return id;
+}
+
+static struct uk_netdev_tx_queue *netfront_txq_setup(struct uk_netdev *n,
+               uint16_t queue_id,
+               uint16_t nb_desc __unused,
+               struct uk_netdev_txqueue_conf *conf __unused)
+{
+       int rc;
+       struct netfront_dev *nfdev;
+       struct uk_netdev_tx_queue *txq;
+       netif_tx_sring_t *sring;
+
+       UK_ASSERT(n != NULL);
+
+       nfdev = to_netfront_dev(n);
+       if (queue_id >= nfdev->max_queue_pairs) {
+               uk_pr_err("Invalid queue identifier: %"__PRIu16"\n", queue_id);
+               return ERR2PTR(-EINVAL);
+       }
+
+       txq  = &nfdev->txqs[queue_id];
+       UK_ASSERT(!txq->initialized);
+       txq->netfront_dev = nfdev;
+       txq->lqueue_id = queue_id;
+
+       /* Setup shared ring */
+       sring = uk_malloc_page(drv_allocator);
+       if (!sring)
+               return ERR2PTR(-ENOMEM);
+       memset(sring, 0, PAGE_SIZE);
+       SHARED_RING_INIT(sring);
+       FRONT_RING_INIT(&txq->ring, sring, PAGE_SIZE);
+       txq->ring_size = NET_TX_RING_SIZE;
+       txq->ring_ref = gnttab_grant_access(nfdev->xendev->otherend_id,
+               virt_to_mfn(sring), 0);
+       UK_ASSERT(txq->ring_ref != GRANT_INVALID_REF);
+
+       /* Setup event channel */
+       rc = evtchn_alloc_unbound(nfdev->xendev->otherend_id,
+                       NULL, NULL,
+                       &txq->evtchn);
+       if (rc) {
+               uk_pr_err("Error creating event channel: %d\n", rc);
+               gnttab_end_access(txq->ring_ref);
+               uk_free_page(drv_allocator, sring);
+               return ERR2PTR(-rc);
+       }
+       /* Events are always disabled for tx queue */
+       mask_evtchn(txq->evtchn);
+
+       /* Initialize list of request ids */
+       uk_semaphore_init(&txq->sem, NET_TX_RING_SIZE);
+       for (uint16_t i = 0; i < NET_TX_RING_SIZE; i++) {
+               add_id_to_freelist(i, txq->freelist);
+               txq->gref[i] = GRANT_INVALID_REF;
+       }
+
+       txq->initialized = true;
+       nfdev->txqs_num++;
+
+       return txq;
+}
+
 static int netfront_rxtx_alloc(struct netfront_dev *nfdev,
                const struct uk_netdev_conf *conf)
 {
@@ -90,6 +169,32 @@ err_free_txrx:
        return rc;
 }
 
+static int netfront_txq_info_get(struct uk_netdev *n,
+               uint16_t queue_id,
+               struct uk_netdev_queue_info *qinfo)
+{
+       struct netfront_dev *nfdev;
+       struct uk_netdev_tx_queue *txq;
+       int rc = 0;
+
+       UK_ASSERT(n != NULL);
+       UK_ASSERT(qinfo != NULL);
+
+       nfdev = to_netfront_dev(n);
+       if (unlikely(queue_id >= nfdev->txqs_num)) {
+               uk_pr_err("Invalid queue_id %"__PRIu16"\n", queue_id);
+               rc = -EINVAL;
+               goto exit;
+       }
+       txq = &nfdev->txqs[queue_id];
+       qinfo->nb_min = txq->ring_size;
+       qinfo->nb_max = txq->ring_size;
+       qinfo->nb_is_power_of_two = 1;
+
+exit:
+       return rc;
+}
+
 static int netfront_configure(struct uk_netdev *n,
                const struct uk_netdev_conf *conf)
 {
@@ -180,6 +285,8 @@ static unsigned int netfront_promisc_get(struct uk_netdev 
*n)
 
 static const struct uk_netdev_ops netfront_ops = {
        .configure = netfront_configure,
+       .txq_configure = netfront_txq_setup,
+       .txq_info_get = netfront_txq_info_get,
        .info_get = netfront_info_get,
        .einfo_get = netfront_einfo_get,
        .hwaddr_get = netfront_mac_get,
diff --git a/plat/xen/drivers/net/netfront.h b/plat/xen/drivers/net/netfront.h
index 15dd3f42..05514cfc 100644
--- a/plat/xen/drivers/net/netfront.h
+++ b/plat/xen/drivers/net/netfront.h
@@ -37,11 +37,40 @@
 #define __NETFRONT_H__
 
 #include <uk/netdev.h>
+#include <uk/semaphore.h>
+#include <xen/io/netif.h>
+#include <common/gnttab.h>
+#include <common/events.h>
+
+
+#define NET_TX_RING_SIZE __CONST_RING_SIZE(netif_tx, PAGE_SIZE)
 
 /**
  * internal structure to represent the transmit queue.
  */
 struct uk_netdev_tx_queue {
+       /* The netfront device */
+       struct netfront_dev *netfront_dev;
+       /* The libuknet queue identifier */
+       uint16_t lqueue_id;
+       /* True if initialized */
+       bool initialized;
+
+       /* Shared ring size */
+       uint16_t ring_size;
+       /* Shared ring */
+       netif_tx_front_ring_t ring;
+       /* Shared ring grant ref */
+       grant_ref_t ring_ref;
+       /* Queue event channel */
+       evtchn_port_t evtchn;
+
+       /* Free list protecting semaphore */
+       struct uk_semaphore sem;
+       /* Free list of transmitting request IDs */
+       uint16_t freelist[NET_TX_RING_SIZE + 1];
+       /* Grants for transmit buffers */
+       grant_ref_t gref[NET_TX_RING_SIZE];
 };
 
 /**
@@ -63,6 +92,7 @@ struct netfront_dev {
        struct uk_netdev netdev;
 
        /* List of the Rx/Tx queues */
+       uint16_t txqs_num;
        struct uk_netdev_tx_queue *txqs;
        struct uk_netdev_rx_queue *rxqs;
        /* Maximum number of queue pairs */
-- 
2.11.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®.