WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] minios: support several netfronts

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] minios: support several netfronts
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 17 Jan 2008 15:20:38 -0800
Delivery-date: Thu, 17 Jan 2008 15:21:49 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1200585048 0
# Node ID 95558b4a6714c37ebd6db0fccc68f7f1197dd622
# Parent  6fdb108db46ca08700beb09a2189c6e6c124dc23
minios: support several netfronts

Signed-off-by: Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>
---
 extras/mini-os/include/netfront.h |    9 -
 extras/mini-os/kernel.c           |    2 
 extras/mini-os/netfront.c         |  328 ++++++++++++++++++++------------------
 3 files changed, 185 insertions(+), 154 deletions(-)

diff -r 6fdb108db46c -r 95558b4a6714 extras/mini-os/include/netfront.h
--- a/extras/mini-os/include/netfront.h Thu Jan 17 15:23:47 2008 +0000
+++ b/extras/mini-os/include/netfront.h Thu Jan 17 15:50:48 2008 +0000
@@ -1,2 +1,7 @@ void init_netfront(void*);
-void init_netfront(void*);
-void netfront_xmit(unsigned char* data,int len);
+#include <wait.h>
+struct netfront_dev;
+struct netfront_dev *init_netfront(char *nodename, void (*netif_rx)(unsigned 
char *data, int len), unsigned char rawmac[6]);
+void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len);
+void shutdown_netfront(struct netfront_dev *dev);
+
+extern struct wait_queue_head netfront_queue;
diff -r 6fdb108db46c -r 95558b4a6714 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Thu Jan 17 15:23:47 2008 +0000
+++ b/extras/mini-os/kernel.c   Thu Jan 17 15:50:48 2008 +0000
@@ -82,7 +82,7 @@ static void periodic_thread(void *p)
 
 static void netfront_thread(void *p)
 {
-    init_netfront(&start_info);
+    init_netfront(NULL, NULL, NULL);
 }
 
 /* This should be overridden by the application we are linked against. */
diff -r 6fdb108db46c -r 95558b4a6714 extras/mini-os/netfront.c
--- a/extras/mini-os/netfront.c Thu Jan 17 15:23:47 2008 +0000
+++ b/extras/mini-os/netfront.c Thu Jan 17 15:50:48 2008 +0000
@@ -13,19 +13,13 @@
 #include <gnttab.h>
 #include <xmalloc.h>
 #include <time.h>
+#include <netfront.h>
+#include <lib.h>
 #include <semaphore.h>
 
-void init_rx_buffers(void);
-
-struct net_info {
-    struct netif_tx_front_ring tx;
-    struct netif_rx_front_ring rx;
-    int tx_ring_ref;
-    int rx_ring_ref;
-    unsigned int evtchn, local_port;
-
-} net_info;
-
+DECLARE_WAIT_QUEUE_HEAD(netfront_queue);
+
+#define NETIF_SELECT_RX ((void*)-1)
 
 
 #define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE)
@@ -33,16 +27,31 @@ struct net_info {
 #define GRANT_INVALID_REF 0
 
 
-unsigned short rx_freelist[NET_RX_RING_SIZE];
-unsigned short tx_freelist[NET_TX_RING_SIZE];
-__DECLARE_SEMAPHORE_GENERIC(tx_sem, NET_TX_RING_SIZE);
-
 struct net_buffer {
     void* page;
-    int gref;
+    grant_ref_t gref;
 };
-struct net_buffer rx_buffers[NET_RX_RING_SIZE];
-struct net_buffer tx_buffers[NET_TX_RING_SIZE];
+
+struct netfront_dev {
+    unsigned short tx_freelist[NET_TX_RING_SIZE];
+    struct semaphore tx_sem;
+
+    struct net_buffer rx_buffers[NET_RX_RING_SIZE];
+    struct net_buffer tx_buffers[NET_TX_RING_SIZE];
+
+    struct netif_tx_front_ring tx;
+    struct netif_rx_front_ring rx;
+    grant_ref_t tx_ring_ref;
+    grant_ref_t rx_ring_ref;
+    evtchn_port_t evtchn, local_port;
+
+    char *nodename;
+    char *backend;
+
+    void (*netif_rx)(unsigned char* data, int len);
+};
+
+void init_rx_buffers(struct netfront_dev *dev);
 
 static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist)
 {
@@ -69,17 +78,16 @@ static inline int xennet_rxidx(RING_IDX 
     return idx & (NET_RX_RING_SIZE - 1);
 }
 
-void network_rx(void)
-{
-    struct net_info *np = &net_info;
+void network_rx(struct netfront_dev *dev)
+{
     RING_IDX rp,cons;
     struct netif_rx_response *rx;
 
 
 moretodo:
-    rp = np->rx.sring->rsp_prod;
+    rp = dev->rx.sring->rsp_prod;
     rmb(); /* Ensure we see queued responses up to 'rp'. */
-    cons = np->rx.rsp_cons;
+    cons = dev->rx.rsp_cons;
 
     int nr_consumed=0;
     while ((cons != rp))
@@ -87,7 +95,7 @@ moretodo:
         struct net_buffer* buf;
         unsigned char* page;
 
-        rx = RING_GET_RESPONSE(&np->rx, cons);
+        rx = RING_GET_RESPONSE(&dev->rx, cons);
 
         if (rx->flags & NETRXF_extra_info)
         {
@@ -100,28 +108,26 @@ moretodo:
 
         int id = rx->id;
 
-        buf = &rx_buffers[id];
+        buf = &dev->rx_buffers[id];
         page = (unsigned char*)buf->page;
         gnttab_end_access(buf->gref);
 
         if(rx->status>0)
         {
-            netif_rx(page+rx->offset,rx->status);
+            dev->netif_rx(page+rx->offset,rx->status);
         }
 
-        add_id_to_freelist(id,rx_freelist);
-
         nr_consumed++;
 
         ++cons;
     }
-    np->rx.rsp_cons=rp;
+    dev->rx.rsp_cons=cons;
 
     int more;
-    RING_FINAL_CHECK_FOR_RESPONSES(&np->rx,more);
+    RING_FINAL_CHECK_FOR_RESPONSES(&dev->rx,more);
     if(more) goto moretodo;
 
-    RING_IDX req_prod = np->rx.req_prod_pvt;
+    RING_IDX req_prod = dev->rx.req_prod_pvt;
 
     int i;
     netif_rx_request_t *req;
@@ -129,8 +135,8 @@ moretodo:
     for(i=0; i<nr_consumed; i++)
     {
         int id = xennet_rxidx(req_prod + i);
-        req = RING_GET_REQUEST(&np->rx, req_prod + i);
-        struct net_buffer* buf = &rx_buffers[id];
+        req = RING_GET_REQUEST(&dev->rx, req_prod + i);
+        struct net_buffer* buf = &dev->rx_buffers[id];
         void* page = buf->page;
 
         /* We are sure to have free gnttab entries since they got released 
above */
@@ -142,45 +148,44 @@ moretodo:
 
     wmb();
 
-    np->rx.req_prod_pvt = req_prod + i;
+    dev->rx.req_prod_pvt = req_prod + i;
     
     int notify;
-    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify);
+    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->rx, notify);
     if (notify)
-        notify_remote_via_evtchn(np->evtchn);
-
-}
-
-void network_tx_buf_gc(void)
+        notify_remote_via_evtchn(dev->evtchn);
+
+}
+
+void network_tx_buf_gc(struct netfront_dev *dev)
 {
 
 
     RING_IDX cons, prod;
     unsigned short id;
-    struct net_info *np = &net_info;
 
     do {
-        prod = np->tx.sring->rsp_prod;
+        prod = dev->tx.sring->rsp_prod;
         rmb(); /* Ensure we see responses up to 'rp'. */
 
-        for (cons = np->tx.rsp_cons; cons != prod; cons++) 
+        for (cons = dev->tx.rsp_cons; cons != prod; cons++) 
         {
             struct netif_tx_response *txrsp;
 
-            txrsp = RING_GET_RESPONSE(&np->tx, cons);
+            txrsp = RING_GET_RESPONSE(&dev->tx, cons);
             if (txrsp->status == NETIF_RSP_NULL)
                 continue;
 
             id  = txrsp->id;
-            struct net_buffer* buf = &tx_buffers[id];
+            struct net_buffer* buf = &dev->tx_buffers[id];
             gnttab_end_access(buf->gref);
             buf->gref=GRANT_INVALID_REF;
 
-            add_id_to_freelist(id,tx_freelist);
-            up(&tx_sem);
+           add_id_to_freelist(id,dev->tx_freelist);
+           up(&dev->tx_sem);
         }
 
-        np->tx.rsp_cons = prod;
+        dev->tx.rsp_cons = prod;
 
         /*
          * Set a new event, then check for race with update of tx_cons.
@@ -190,10 +195,10 @@ void network_tx_buf_gc(void)
          * data is outstanding: in such cases notification from Xen is
          * likely to be the only kick that we'll get.
          */
-        np->tx.sring->rsp_event =
-            prod + ((np->tx.sring->req_prod - prod) >> 1) + 1;
+        dev->tx.sring->rsp_event =
+            prod + ((dev->tx.sring->req_prod - prod) >> 1) + 1;
         mb();
-    } while ((cons == prod) && (prod != np->tx.sring->rsp_prod));
+    } while ((cons == prod) && (prod != dev->tx.sring->rsp_prod));
 
 
 }
@@ -201,24 +206,21 @@ void netfront_handler(evtchn_port_t port
 void netfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
 {
     int flags;
+    struct netfront_dev *dev = data;
 
     local_irq_save(flags);
 
-    network_tx_buf_gc();
-    network_rx();
+    network_tx_buf_gc(dev);
+    network_rx(dev);
 
     local_irq_restore(flags);
 }
 
-char* backend;
-
-void init_netfront(void* si)
+struct netfront_dev *init_netfront(char *nodename, void 
(*thenetif_rx)(unsigned char* data, int len), unsigned char rawmac[6])
 {
     xenbus_transaction_t xbt;
-    struct net_info* info = &net_info;
     char* err;
     char* message=NULL;
-    char nodename[] = "device/vif/0";
     struct netif_tx_sring *txs;
     struct netif_rx_sring *rxs;
     int retry=0;
@@ -226,18 +228,34 @@ void init_netfront(void* si)
     char* mac;
     char* msg;
 
-    printk("************************ NETFRONT **********\n\n\n");
-
+    struct netfront_dev *dev;
+
+    if (!nodename)
+       nodename = "device/vif/0";
+
+    char path[strlen(nodename) + 1 + 10 + 1];
+
+    if (!thenetif_rx)
+       thenetif_rx = netif_rx;
+
+    printk("************************ NETFRONT for %s **********\n\n\n", 
nodename);
+
+    dev = malloc(sizeof(*dev));
+    dev->nodename = strdup(nodename);
+
+    printk("net TX ring size %d\n", NET_TX_RING_SIZE);
+    printk("net RX ring size %d\n", NET_RX_RING_SIZE);
+    init_SEMAPHORE(&dev->tx_sem, NET_TX_RING_SIZE);
     for(i=0;i<NET_TX_RING_SIZE;i++)
     {
-        add_id_to_freelist(i,tx_freelist);
-        tx_buffers[i].page = (char*)alloc_page();
+       add_id_to_freelist(i,dev->tx_freelist);
+        dev->tx_buffers[i].page = NULL;
     }
 
     for(i=0;i<NET_RX_RING_SIZE;i++)
     {
-        add_id_to_freelist(i,rx_freelist);
-        rx_buffers[i].page = (char*)alloc_page();
+       /* TODO: that's a lot of memory */
+        dev->rx_buffers[i].page = (char*)alloc_page();
     }
 
     txs = (struct netif_tx_sring*) alloc_page();
@@ -248,20 +266,24 @@ void init_netfront(void* si)
 
     SHARED_RING_INIT(txs);
     SHARED_RING_INIT(rxs);
-    FRONT_RING_INIT(&info->tx, txs, PAGE_SIZE);
-    FRONT_RING_INIT(&info->rx, rxs, PAGE_SIZE);
-
-    info->tx_ring_ref = gnttab_grant_access(0,virt_to_mfn(txs),0);
-    info->rx_ring_ref = gnttab_grant_access(0,virt_to_mfn(rxs),0);
+    FRONT_RING_INIT(&dev->tx, txs, PAGE_SIZE);
+    FRONT_RING_INIT(&dev->rx, rxs, PAGE_SIZE);
+
+    dev->tx_ring_ref = gnttab_grant_access(0,virt_to_mfn(txs),0);
+    dev->rx_ring_ref = gnttab_grant_access(0,virt_to_mfn(rxs),0);
 
     evtchn_alloc_unbound_t op;
     op.dom = DOMID_SELF;
-    op.remote_dom = 0;
+    snprintf(path, sizeof(path), "%s/backend-id", nodename);
+    op.remote_dom = xenbus_read_integer(path);
     HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
     clear_evtchn(op.port);        /* Without, handler gets invoked now! */
-    info->local_port = bind_evtchn(op.port, netfront_handler, NULL);
-    info->evtchn=op.port;
-
+    dev->local_port = bind_evtchn(op.port, netfront_handler, dev);
+    dev->evtchn=op.port;
+
+    dev->netif_rx = thenetif_rx;
+
+    // FIXME: proper frees on failures
 again:
     err = xenbus_transaction_start(&xbt);
     if (err) {
@@ -269,19 +291,19 @@ again:
     }
 
     err = xenbus_printf(xbt, nodename, "tx-ring-ref","%u",
-                info->tx_ring_ref);
+                dev->tx_ring_ref);
     if (err) {
         message = "writing tx ring-ref";
         goto abort_transaction;
     }
     err = xenbus_printf(xbt, nodename, "rx-ring-ref","%u",
-                info->rx_ring_ref);
+                dev->rx_ring_ref);
     if (err) {
         message = "writing rx ring-ref";
         goto abort_transaction;
     }
     err = xenbus_printf(xbt, nodename,
-                "event-channel", "%u", info->evtchn);
+                "event-channel", "%u", dev->evtchn);
     if (err) {
         message = "writing event-channel";
         goto abort_transaction;
@@ -308,40 +330,45 @@ again:
 
 abort_transaction:
     xenbus_transaction_end(xbt, 1, &retry);
+    return NULL;
 
 done:
 
-    msg = xenbus_read(XBT_NIL, "device/vif/0/backend", &backend);
-    msg = xenbus_read(XBT_NIL, "device/vif/0/mac", &mac);
-
-    if ((backend == NULL) || (mac == NULL)) {
-        struct evtchn_close op = { info->local_port };
+    snprintf(path, sizeof(path), "%s/backend", nodename);
+    msg = xenbus_read(XBT_NIL, path, &dev->backend);
+    snprintf(path, sizeof(path), "%s/mac", nodename);
+    msg = xenbus_read(XBT_NIL, path, &mac);
+
+    if ((dev->backend == NULL) || (mac == NULL)) {
+        struct evtchn_close op = { dev->local_port };
         printk("%s: backend/mac failed\n", __func__);
-        unbind_evtchn(info->local_port);
+        unbind_evtchn(dev->local_port);
         HYPERVISOR_event_channel_op(EVTCHNOP_close, &op);
-        return;
-    }
-
-    printk("backend at %s\n",backend);
+        return NULL;
+    }
+
+    printk("backend at %s\n",dev->backend);
     printk("mac is %s\n",mac);
 
-    char path[256];
-    sprintf(path,"%s/state",backend);
-
-    xenbus_watch_path(XBT_NIL, path);
-
-    xenbus_wait_for_value(path,"4");
-
-    //free(backend);
+    {
+        char path[strlen(dev->backend) + 1 + 5 + 1];
+        snprintf(path, sizeof(path), "%s/state", dev->backend);
+
+        xenbus_watch_path(XBT_NIL, path);
+
+        xenbus_wait_for_value(path,"4");
+
+        xenbus_unwatch_path(XBT_NIL, path);
+    }
 
     printk("**************************\n");
 
-    init_rx_buffers();
-
-    unsigned char rawmac[6];
+    init_rx_buffers(dev);
+
         /* Special conversion specifier 'hh' needed for __ia64__. Without
            this mini-os panics with 'Unaligned reference'. */
-    sscanf(mac,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+    if (rawmac)
+       sscanf(mac,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
             &rawmac[0],
             &rawmac[1],
             &rawmac[2],
@@ -349,37 +376,35 @@ done:
             &rawmac[4],
             &rawmac[5]);
 
-    net_app_main(si,rawmac);
-}
-
-void shutdown_netfront(void)
-{
-    //xenbus_transaction_t xbt;
+    return dev;
+}
+
+void shutdown_netfront(struct netfront_dev *dev)
+{
     char* err;
-    char nodename[] = "device/vif/0";
-
-    char path[256];
-
-    printk("close network: backend at %s\n",backend);
-
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); /* closing */
-    sprintf(path,"%s/state",backend);
-
+    char *nodename = dev->nodename;
+
+    char path[strlen(dev->backend) + 1 + 5 + 1];
+
+    printk("close network: backend at %s\n",dev->backend);
+
+    snprintf(path, sizeof(path), "%s/state", dev->backend);
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
+    xenbus_wait_for_value(path,"5");
+
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
     xenbus_wait_for_value(path,"6");
 
-    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
-
-    xenbus_wait_for_value(path,"2");
-
-    unbind_all_ports();
-
-    free(backend);
-}
-
-
-void init_rx_buffers(void)
-{
-    struct net_info* np = &net_info;
+    unbind_evtchn(dev->local_port);
+
+    free(nodename);
+    free(dev->backend);
+    free(dev);
+}
+
+
+void init_rx_buffers(struct netfront_dev *dev)
+{
     int i, requeue_idx;
     netif_rx_request_t *req;
     int notify;
@@ -387,8 +412,8 @@ void init_rx_buffers(void)
     /* Rebuild the RX buffer freelist and the RX ring itself. */
     for (requeue_idx = 0, i = 0; i < NET_RX_RING_SIZE; i++) 
     {
-        struct net_buffer* buf = &rx_buffers[requeue_idx];
-        req = RING_GET_REQUEST(&np->rx, requeue_idx);
+        struct net_buffer* buf = &dev->rx_buffers[requeue_idx];
+        req = RING_GET_REQUEST(&dev->rx, requeue_idx);
 
         buf->gref = req->gref = 
             gnttab_grant_access(0,virt_to_mfn(buf->page),0);
@@ -398,39 +423,40 @@ void init_rx_buffers(void)
         requeue_idx++;
     }
 
-    np->rx.req_prod_pvt = requeue_idx;
-
-    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->rx, notify);
+    dev->rx.req_prod_pvt = requeue_idx;
+
+    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->rx, notify);
 
     if (notify) 
-        notify_remote_via_evtchn(np->evtchn);
-
-    np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
-}
-
-
-void netfront_xmit(unsigned char* data,int len)
+        notify_remote_via_evtchn(dev->evtchn);
+
+    dev->rx.sring->rsp_event = dev->rx.rsp_cons + 1;
+}
+
+
+void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len)
 {
     int flags;
-    struct net_info* info = &net_info;
     struct netif_tx_request *tx;
     RING_IDX i;
     int notify;
-    int id;
+    unsigned short id;
     struct net_buffer* buf;
     void* page;
 
-    down(&tx_sem);
+    down(&dev->tx_sem);
 
     local_irq_save(flags);
-    id = get_id_from_freelist(tx_freelist);
+    id = get_id_from_freelist(dev->tx_freelist);
     local_irq_restore(flags);
 
-    buf = &tx_buffers[id];
+    buf = &dev->tx_buffers[id];
     page = buf->page;
-
-    i = info->tx.req_prod_pvt;
-    tx = RING_GET_REQUEST(&info->tx, i);
+    if (!page)
+       page = buf->page = (char*) alloc_page();
+
+    i = dev->tx.req_prod_pvt;
+    tx = RING_GET_REQUEST(&dev->tx, i);
 
     memcpy(page,data,len);
 
@@ -441,15 +467,15 @@ void netfront_xmit(unsigned char* data,i
     tx->size = len;
     tx->flags=0;
     tx->id = id;
-    info->tx.req_prod_pvt = i + 1;
+    dev->tx.req_prod_pvt = i + 1;
 
     wmb();
 
-    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->tx, notify);
-
-    if(notify) notify_remote_via_evtchn(info->evtchn);
+    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->tx, notify);
+
+    if(notify) notify_remote_via_evtchn(dev->evtchn);
 
     local_irq_save(flags);
-    network_tx_buf_gc();
+    network_tx_buf_gc(dev);
     local_irq_restore(flags);
 }

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] minios: support several netfronts, Xen patchbot-unstable <=