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-ppc-devel

[XenPPC] [linux-ppc-2.6] [XEN][POWERPC] Driver refresh

To: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Subject: [XenPPC] [linux-ppc-2.6] [XEN][POWERPC] Driver refresh
From: Xen patchbot-linux-ppc-2.6 <patchbot-linux-ppc-2.6@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 09 Nov 2006 00:02:48 +0000
Delivery-date: Wed, 08 Nov 2006 16:04:37 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ppc-devel-request@lists.xensource.com?subject=help>
List-id: Xen PPC development <xen-ppc-devel.lists.xensource.com>
List-post: <mailto:xen-ppc-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Node ID 15c1ca41a412014e942f72c908861c963a35e306
# Parent  39d3d1cfe7146a6542a7708bace0ab38f11e48b5
[XEN][POWERPC] Driver refresh

This fixes the problem with inter-domain networking.

Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
---
 drivers/xen/netback/common.h       |    2 
 drivers/xen/netback/interface.c    |   29 +++----
 drivers/xen/netback/netback.c      |   74 +++++++++++---------
 drivers/xen/netback/xenbus.c       |   89 ++++++------------------
 drivers/xen/netfront/netfront.c    |  135 ++++++++++++++++---------------------
 drivers/xen/xenbus/xenbus_client.c |    3 
 drivers/xen/xenbus/xenbus_probe.c  |    2 
 7 files changed, 143 insertions(+), 191 deletions(-)

diff -r 39d3d1cfe714 -r 15c1ca41a412 drivers/xen/netback/common.h
--- a/drivers/xen/netback/common.h      Wed Nov 08 15:44:19 2006 -0500
+++ b/drivers/xen/netback/common.h      Wed Nov 08 18:58:23 2006 -0500
@@ -106,7 +106,7 @@ typedef struct netif_st {
 
 void netif_disconnect(netif_t *netif);
 
-netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
+netif_t *netif_alloc(domid_t domid, unsigned int handle);
 int netif_map(netif_t *netif, unsigned long tx_ring_ref,
              unsigned long rx_ring_ref, unsigned int evtchn);
 
diff -r 39d3d1cfe714 -r 15c1ca41a412 drivers/xen/netback/interface.c
--- a/drivers/xen/netback/interface.c   Wed Nov 08 15:44:19 2006 -0500
+++ b/drivers/xen/netback/interface.c   Wed Nov 08 18:58:23 2006 -0500
@@ -126,9 +126,9 @@ static struct ethtool_ops network_ethtoo
        .get_link = ethtool_op_get_link,
 };
 
-netif_t *netif_alloc(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
-{
-       int err = 0, i;
+netif_t *netif_alloc(domid_t domid, unsigned int handle)
+{
+       int err = 0;
        struct net_device *dev;
        netif_t *netif;
        char name[IFNAMSIZ] = {};
@@ -169,20 +169,14 @@ netif_t *netif_alloc(domid_t domid, unsi
                printk(KERN_WARNING "netbk: WARNING: device '%s' has non-zero "
                       "queue length (%lu)!\n", dev->name, dev->tx_queue_len);
 
-       for (i = 0; i < ETH_ALEN; i++)
-               if (be_mac[i] != 0)
-                       break;
-       if (i == ETH_ALEN) {
-               /*
-                * Initialise a dummy MAC address. We choose the numerically
-                * largest non-broadcast address to prevent the address getting
-                * stolen by an Ethernet bridge for STP purposes.
-                * (FE:FF:FF:FF:FF:FF)
-                */ 
-               memset(dev->dev_addr, 0xFF, ETH_ALEN);
-               dev->dev_addr[0] &= ~0x01;
-       } else
-               memcpy(dev->dev_addr, be_mac, ETH_ALEN);
+       /*
+        * Initialise a dummy MAC address. We choose the numerically
+        * largest non-broadcast address to prevent the address getting
+        * stolen by an Ethernet bridge for STP purposes.
+        * (FE:FF:FF:FF:FF:FF)
+        */ 
+       memset(dev->dev_addr, 0xFF, ETH_ALEN);
+       dev->dev_addr[0] &= ~0x01;
 
        rtnl_lock();
        err = register_netdevice(dev);
@@ -225,6 +219,7 @@ static int map_frontend_pages(
 
        lock_vm_area(netif->rx_comms_area);
        ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1);
+       unlock_vm_area(netif->rx_comms_area);
        BUG_ON(ret);
 
        if (op.status) {
diff -r 39d3d1cfe714 -r 15c1ca41a412 drivers/xen/netback/netback.c
--- a/drivers/xen/netback/netback.c     Wed Nov 08 15:44:19 2006 -0500
+++ b/drivers/xen/netback/netback.c     Wed Nov 08 18:58:23 2006 -0500
@@ -78,7 +78,7 @@ static inline unsigned long idx_to_kaddr
 
 #define PKT_PROT_LEN 64
 
-static struct {
+static struct pending_tx_info {
        netif_tx_request_t req;
        netif_t *netif;
 } pending_tx_info[MAX_PENDING_REQS];
@@ -374,14 +374,22 @@ static u16 netbk_gop_frag(netif_t *netif
                   flipped. */
                meta->copy = 1;
                copy_gop = npo->copy + npo->copy_prod++;
-               copy_gop->source.domid = DOMID_SELF;
+               copy_gop->flags = GNTCOPY_dest_gref;
+               if (PageForeign(page)) {
+                       struct pending_tx_info *src_pend =
+                               &pending_tx_info[page->index];
+                       copy_gop->source.domid = src_pend->netif->domid;
+                       copy_gop->source.u.ref = src_pend->req.gref;
+                       copy_gop->flags |= GNTCOPY_source_gref;
+               } else {
+                       copy_gop->source.domid = DOMID_SELF;
+                       copy_gop->source.u.gmfn = old_mfn;
+               }
                copy_gop->source.offset = offset;
-               copy_gop->source.u.gmfn = old_mfn;
                copy_gop->dest.domid = netif->domid;
                copy_gop->dest.offset = 0;
                copy_gop->dest.u.ref = req->gref;
                copy_gop->len = size;
-               copy_gop->flags = GNTCOPY_dest_gref;
        } else {
                meta->copy = 0;
                if (!xen_feature(XENFEAT_auto_translated_physmap)) {
@@ -875,20 +883,28 @@ static void netbk_tx_err(netif_t *netif,
        netif_put(netif);
 }
 
-static int netbk_count_requests(netif_t *netif, netif_tx_request_t *txp,
-                               int work_to_do)
-{
-       netif_tx_request_t *first = txp;
+static int netbk_count_requests(netif_t *netif, netif_tx_request_t *first,
+                               netif_tx_request_t *txp, int work_to_do)
+{
        RING_IDX cons = netif->tx.req_cons;
        int frags = 0;
 
-       while (txp->flags & NETTXF_more_data) {
+       if (!(first->flags & NETTXF_more_data))
+               return 0;
+
+       do {
                if (frags >= work_to_do) {
                        DPRINTK("Need more frags\n");
                        return -frags;
                }
 
-               txp = RING_GET_REQUEST(&netif->tx, cons + frags);
+               if (unlikely(frags >= MAX_SKB_FRAGS)) {
+                       DPRINTK("Too many frags\n");
+                       return -frags;
+               }
+
+               memcpy(txp, RING_GET_REQUEST(&netif->tx, cons + frags),
+                      sizeof(*txp));
                if (txp->size > first->size) {
                        DPRINTK("Frags galore\n");
                        return -frags;
@@ -902,27 +918,25 @@ static int netbk_count_requests(netif_t 
                                txp->offset, txp->size);
                        return -frags;
                }
-       }
+       } while ((txp++)->flags & NETTXF_more_data);
 
        return frags;
 }
 
 static gnttab_map_grant_ref_t *netbk_get_requests(netif_t *netif,
                                                  struct sk_buff *skb,
+                                                 netif_tx_request_t *txp,
                                                  gnttab_map_grant_ref_t *mop)
 {
        struct skb_shared_info *shinfo = skb_shinfo(skb);
        skb_frag_t *frags = shinfo->frags;
-       netif_tx_request_t *txp;
        unsigned long pending_idx = *((u16 *)skb->data);
-       RING_IDX cons = netif->tx.req_cons;
        int i, start;
 
        /* Skip first skb fragment if it is on same page as header fragment. */
        start = ((unsigned long)shinfo->frags[0].page == pending_idx);
 
-       for (i = start; i < shinfo->nr_frags; i++) {
-               txp = RING_GET_REQUEST(&netif->tx, cons++);
+       for (i = start; i < shinfo->nr_frags; i++, txp++) {
                pending_idx = pending_ring[MASK_PEND_IDX(pending_cons++)];
 
                gnttab_set_map_op(mop++, idx_to_kaddr(pending_idx),
@@ -1036,7 +1050,7 @@ int netbk_get_extras(netif_t *netif, str
 int netbk_get_extras(netif_t *netif, struct netif_extra_info *extras,
                     int work_to_do)
 {
-       struct netif_extra_info *extra;
+       struct netif_extra_info extra;
        RING_IDX cons = netif->tx.req_cons;
 
        do {
@@ -1045,18 +1059,18 @@ int netbk_get_extras(netif_t *netif, str
                        return -EBADR;
                }
 
-               extra = (struct netif_extra_info *)
-                       RING_GET_REQUEST(&netif->tx, cons);
-               if (unlikely(!extra->type ||
-                            extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
+               memcpy(&extra, RING_GET_REQUEST(&netif->tx, cons),
+                      sizeof(extra));
+               if (unlikely(!extra.type ||
+                            extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
                        netif->tx.req_cons = ++cons;
-                       DPRINTK("Invalid extra type: %d\n", extra->type);
+                       DPRINTK("Invalid extra type: %d\n", extra.type);
                        return -EINVAL;
                }
 
-               memcpy(&extras[extra->type - 1], extra, sizeof(*extra));
+               memcpy(&extras[extra.type - 1], &extra, sizeof(extra));
                netif->tx.req_cons = ++cons;
-       } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE);
+       } while (extra.flags & XEN_NETIF_EXTRA_FLAG_MORE);
 
        return work_to_do;
 }
@@ -1091,6 +1105,7 @@ static void net_tx_action(unsigned long 
        struct sk_buff *skb;
        netif_t *netif;
        netif_tx_request_t txreq;
+       netif_tx_request_t txfrags[MAX_SKB_FRAGS];
        struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1];
        u16 pending_idx;
        RING_IDX i;
@@ -1167,18 +1182,12 @@ static void net_tx_action(unsigned long 
                        }
                }
 
-               ret = netbk_count_requests(netif, &txreq, work_to_do);
+               ret = netbk_count_requests(netif, &txreq, txfrags, work_to_do);
                if (unlikely(ret < 0)) {
                        netbk_tx_err(netif, &txreq, i - ret);
                        continue;
                }
                i += ret;
-
-               if (unlikely(ret > MAX_SKB_FRAGS)) {
-                       DPRINTK("Too many frags\n");
-                       netbk_tx_err(netif, &txreq, i);
-                       continue;
-               }
 
                if (unlikely(txreq.size < ETH_HLEN)) {
                        DPRINTK("Bad packet size: %d\n", txreq.size);
@@ -1248,7 +1257,7 @@ static void net_tx_action(unsigned long 
 
                pending_cons++;
 
-               mop = netbk_get_requests(netif, skb, mop);
+               mop = netbk_get_requests(netif, skb, txfrags, mop);
 
                netif->tx.req_cons = i;
                netif_schedule_work(netif);
@@ -1338,6 +1347,7 @@ static void netif_page_release(struct pa
 {
        /* Ready for next use. */
        init_page_count(page);
+
        netif_idx_release(page->index);
 }
 
@@ -1464,11 +1474,13 @@ static int __init netback_init(void)
                printk("%s: out of memory\n", __FUNCTION__);
                return -ENOMEM;
        }
+
        for (i = 0; i < MAX_PENDING_REQS; i++) {
                page = mmap_pages[i];
                SetPageForeign(page, netif_page_release);
                page->index = i;
        }
+
        pending_cons = 0;
        pending_prod = MAX_PENDING_REQS;
        for (i = 0; i < MAX_PENDING_REQS; i++)
diff -r 39d3d1cfe714 -r 15c1ca41a412 drivers/xen/netback/xenbus.c
--- a/drivers/xen/netback/xenbus.c      Wed Nov 08 15:44:19 2006 -0500
+++ b/drivers/xen/netback/xenbus.c      Wed Nov 08 18:58:23 2006 -0500
@@ -28,29 +28,20 @@
     printk("netback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
 #endif
 
-struct backend_info
-{
+struct backend_info {
        struct xenbus_device *dev;
        netif_t *netif;
-       struct xenbus_watch backend_watch;
        enum xenbus_state frontend_state;
 };
 
 static int connect_rings(struct backend_info *);
 static void connect(struct backend_info *);
-static void maybe_connect(struct backend_info *);
-static void backend_changed(struct xenbus_watch *, const char **,
-                           unsigned int);
+static void backend_create_netif(struct backend_info *be);
 
 static int netback_remove(struct xenbus_device *dev)
 {
        struct backend_info *be = dev->dev.driver_data;
 
-       if (be->backend_watch.node) {
-               unregister_xenbus_watch(&be->backend_watch);
-               kfree(be->backend_watch.node);
-               be->backend_watch.node = NULL;
-       }
        if (be->netif) {
                netif_disconnect(be->netif);
                be->netif = NULL;
@@ -63,8 +54,7 @@ static int netback_remove(struct xenbus_
 
 /**
  * Entry point to this code when a new device is created.  Allocate the basic
- * structures, and watch the store waiting for the hotplug scripts to tell us
- * the device's handle.  Switch to InitWait.
+ * structures and switch to InitWait.
  */
 static int netback_probe(struct xenbus_device *dev,
                         const struct xenbus_device_id *id)
@@ -83,11 +73,6 @@ static int netback_probe(struct xenbus_d
        be->dev = dev;
        dev->dev.driver_data = be;
 
-       err = xenbus_watch_path2(dev, dev->nodename, "handle",
-                                &be->backend_watch, backend_changed);
-       if (err)
-               goto fail;
-
        do {
                err = xenbus_transaction_start(&xbt);
                if (err) {
@@ -108,7 +93,8 @@ static int netback_probe(struct xenbus_d
                        goto abort_transaction;
                }
 
-               err = xenbus_printf(xbt, dev->nodename, "feature-rx-copy", 
"%d", 1);
+               err = xenbus_printf(xbt, dev->nodename,
+                                   "feature-rx-copy", "%d", 1);
                if (err) {
                        message = "writing feature-copying";
                        goto abort_transaction;
@@ -123,9 +109,11 @@ static int netback_probe(struct xenbus_d
        }
 
        err = xenbus_switch_state(dev, XenbusStateInitWait);
-       if (err) {
+       if (err)
                goto fail;
-       }
+
+       /* This kicks hotplug scripts, so do it immediately. */
+       backend_create_netif(be);
 
        return 0;
 
@@ -175,48 +163,30 @@ static int netback_uevent(struct xenbus_
 }
 
 
-/**
- * Callback received when the hotplug scripts have placed the handle node.
- * Read it, and create a netif structure.  If the frontend is ready, connect.
- */
-static void backend_changed(struct xenbus_watch *watch,
-                           const char **vec, unsigned int len)
+static void backend_create_netif(struct backend_info *be)
 {
        int err;
        long handle;
-       struct backend_info *be
-               = container_of(watch, struct backend_info, backend_watch);
        struct xenbus_device *dev = be->dev;
 
-       DPRINTK("");
+       if (be->netif != NULL)
+               return;
 
        err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%li", &handle);
-       if (XENBUS_EXIST_ERR(err)) {
-               /* Since this watch will fire once immediately after it is
-                  registered, we expect this.  Ignore it, and wait for the
-                  hotplug scripts. */
-               return;
-       }
        if (err != 1) {
                xenbus_dev_fatal(dev, err, "reading handle");
                return;
        }
 
-       if (be->netif == NULL) {
-               u8 be_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
-
-               be->netif = netif_alloc(dev->otherend_id, handle, be_mac);
-               if (IS_ERR(be->netif)) {
-                       err = PTR_ERR(be->netif);
-                       be->netif = NULL;
-                       xenbus_dev_fatal(dev, err, "creating interface");
-                       return;
-               }
-
-               kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE);
-
-               maybe_connect(be);
-       }
+       be->netif = netif_alloc(dev->otherend_id, handle);
+       if (IS_ERR(be->netif)) {
+               err = PTR_ERR(be->netif);
+               be->netif = NULL;
+               xenbus_dev_fatal(dev, err, "creating interface");
+               return;
+       }
+
+       kobject_uevent(&dev->dev.kobj, KOBJ_ONLINE);
 }
 
 
@@ -249,11 +219,9 @@ static void frontend_changed(struct xenb
                break;
 
        case XenbusStateConnected:
-               if (!be->netif) {
-                       /* reconnect: setup be->netif */
-                       backend_changed(&be->backend_watch, NULL, 0);
-               }
-               maybe_connect(be);
+               backend_create_netif(be);
+               if (be->netif)
+                       connect(be);
                break;
 
        case XenbusStateClosing:
@@ -279,15 +247,6 @@ static void frontend_changed(struct xenb
 }
 
 
-/* ** Connection ** */
-
-
-static void maybe_connect(struct backend_info *be)
-{
-       if (be->netif && (be->frontend_state == XenbusStateConnected))
-               connect(be);
-}
-
 static void xen_net_read_rate(struct xenbus_device *dev,
                              unsigned long *bytes, unsigned long *usec)
 {
diff -r 39d3d1cfe714 -r 15c1ca41a412 drivers/xen/netfront/netfront.c
--- a/drivers/xen/netfront/netfront.c   Wed Nov 08 15:44:19 2006 -0500
+++ b/drivers/xen/netfront/netfront.c   Wed Nov 08 18:58:23 2006 -0500
@@ -141,7 +141,6 @@ struct netfront_info {
        spinlock_t   tx_lock;
        spinlock_t   rx_lock;
 
-       unsigned int handle;
        unsigned int evtchn, irq;
        unsigned int copying_receiver;
 
@@ -230,9 +229,8 @@ static inline grant_ref_t xennet_get_rx_
 #define WPRINTK(fmt, args...)                          \
        printk(KERN_WARNING "netfront: " fmt, ##args)
 
-static int talk_to_backend(struct xenbus_device *, struct netfront_info *);
 static int setup_device(struct xenbus_device *, struct netfront_info *);
-static struct net_device *create_netdev(int, int, struct xenbus_device *);
+static struct net_device *create_netdev(struct xenbus_device *);
 
 static void netfront_closing(struct xenbus_device *);
 
@@ -242,7 +240,7 @@ static void close_netdev(struct netfront
 static void close_netdev(struct netfront_info *);
 static void netif_free(struct netfront_info *);
 
-static void network_connect(struct net_device *);
+static int network_connect(struct net_device *);
 static void network_tx_buf_gc(struct net_device *);
 static void network_alloc_rx_buffers(struct net_device *);
 static int send_fake_arp(struct net_device *);
@@ -265,8 +263,7 @@ static inline int xennet_can_sg(struct n
 /**
  * Entry point to this code when a new device is created.  Allocate the basic
  * structures and the ring buffers for communication with the backend, and
- * inform the backend of the appropriate details for those.  Switch to
- * Connected state.
+ * inform the backend of the appropriate details for those.
  */
 static int __devinit netfront_probe(struct xenbus_device *dev,
                                    const struct xenbus_device_id *id)
@@ -274,36 +271,8 @@ static int __devinit netfront_probe(stru
        int err;
        struct net_device *netdev;
        struct netfront_info *info;
-       unsigned int handle, feature_rx_copy, feature_rx_flip, use_copy;
-
-       err = xenbus_scanf(XBT_NIL, dev->nodename, "handle", "%u", &handle);
-       if (err != 1) {
-               xenbus_dev_fatal(dev, err, "reading handle");
-               return err;
-       }
-
-       err = xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-copy", "%u",
-                          &feature_rx_copy);
-       if (err != 1)
-               feature_rx_copy = 0;
-       err = xenbus_scanf(XBT_NIL, dev->otherend, "feature-rx-flip", "%u",
-                          &feature_rx_flip);
-       if (err != 1)
-               feature_rx_flip = 1;
-
-       /*
-        * Copy packets on receive path if:
-        *  (a) This was requested by user, and the backend supports it; or
-        *  (b) Flipping was requested, but this is unsupported by the backend.
-        */
-       use_copy = (MODPARM_rx_copy && feature_rx_copy) ||
-               (MODPARM_rx_flip && !feature_rx_flip);
-
-#ifdef CONFIG_PPC_XEN
-       if (!use_copy)
-               panic("NetFront _must_ use rx copy feature on PowerPC\n");
-#endif
-       netdev = create_netdev(handle, use_copy, dev);
+
+       netdev = create_netdev(dev);
        if (IS_ERR(netdev)) {
                err = PTR_ERR(netdev);
                xenbus_dev_fatal(dev, err, "creating netdev");
@@ -313,23 +282,13 @@ static int __devinit netfront_probe(stru
        info = netdev_priv(netdev);
        dev->dev.driver_data = info;
 
-       err = talk_to_backend(dev, info);
-       if (err)
-               goto fail_backend;
-
        err = open_netdev(info);
        if (err)
-               goto fail_open;
-
-       IPRINTK("Created netdev %s with %sing receive path.\n",
-               netdev->name, info->copying_receiver ? "copy" : "flipp");
+               goto fail;
 
        return 0;
 
- fail_open:
-       xennet_sysfs_delif(info->netdev);
-       unregister_netdev(netdev);
- fail_backend:
+ fail:
        free_netdev(netdev);
        dev->dev.driver_data = NULL;
        return err;
@@ -349,7 +308,7 @@ static int netfront_resume(struct xenbus
        DPRINTK("%s\n", dev->nodename);
 
        netif_disconnect_backend(info);
-       return talk_to_backend(dev, info);
+       return 0;
 }
 
 static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
@@ -460,7 +419,7 @@ again:
        xenbus_transaction_end(xbt, 1);
        xenbus_dev_fatal(dev, err, "%s", message);
  destroy_ring:
-       netif_free(info);
+       netif_disconnect_backend(info);
  out:
        return err;
 }
@@ -550,7 +509,10 @@ static void backend_changed(struct xenbu
                break;
 
        case XenbusStateInitWait:
-               network_connect(netdev);
+               if (network_connect(netdev) != 0) {
+                       netif_free(np);
+                       break;
+               }
                xenbus_switch_state(dev, XenbusStateConnected);
                (void)send_fake_arp(netdev);
                break;
@@ -654,13 +616,6 @@ static void network_tx_buf_gc(struct net
                                       "-- grant still in use by backend "
                                       "domain.\n");
                                BUG();
-                       }
-                       if ((ulong)skb < 0xc000000000000000ULL) {
-                               printk(KERN_EMERG "%s: bad skb: %p id: %d "
-                                      "status: 0x%x\n", __func__,
-                                      skb, id, txrsp->status);
-                               continue;
-//                             asm volatile(".long 0x200;nop");
                        }
                        gnttab_end_foreign_access_ref(
                                np->grant_tx_ref[id], GNTMAP_readonly);
@@ -1131,6 +1086,7 @@ static int xennet_get_responses(struct n
                        if (net_ratelimit())
                                WPRINTK("rx->offset: %x, size: %u\n",
                                        rx->offset, rx->status);
+                       xennet_move_rx_slot(np, skb, ref);
                        err = -EINVAL;
                        goto next;
                }
@@ -1141,7 +1097,8 @@ static int xennet_get_responses(struct n
                 * situation to the system controller to reboot the backed.
                 */
                if (ref == GRANT_INVALID_REF) {
-                       WPRINTK("Bad rx response id %d.\n", rx->id);
+                       if (net_ratelimit())
+                               WPRINTK("Bad rx response id %d.\n", rx->id);
                        err = -EINVAL;
                        goto next;
                }
@@ -1212,6 +1169,9 @@ next:
                        WPRINTK("Too many frags\n");
                err = -E2BIG;
        }
+
+       if (unlikely(err))
+               np->rx.rsp_cons = cons + frags;
 
        *pages_flipped_p = pages_flipped;
 
@@ -1317,9 +1277,9 @@ static int netif_poll(struct net_device 
        rp = np->rx.sring->rsp_prod;
        rmb(); /* Ensure we see queued responses up to 'rp'. */
 
-       for (i = np->rx.rsp_cons, work_done = 0;
-            (i != rp) && (work_done < budget);
-            np->rx.rsp_cons = ++i, work_done++) {
+       i = np->rx.rsp_cons;
+       work_done = 0;
+       while ((i != rp) && (work_done < budget)) {
                memcpy(rx, RING_GET_RESPONSE(&np->rx, i), sizeof(*rx));
                memset(extras, 0, sizeof(extras));
 
@@ -1327,12 +1287,11 @@ static int netif_poll(struct net_device 
                                           &pages_flipped);
 
                if (unlikely(err)) {
-err:
-                       i = np->rx.rsp_cons + skb_queue_len(&tmpq) - 1;
-                       work_done--;
+err:   
                        while ((skb = __skb_dequeue(&tmpq)))
                                __skb_queue_tail(&errq, skb);
                        np->stats.rx_errors++;
+                       i = np->rx.rsp_cons;
                        continue;
                }
 
@@ -1344,6 +1303,7 @@ err:
 
                        if (unlikely(xennet_set_skb_gso(skb, gso))) {
                                __skb_queue_head(&tmpq, skb);
+                               np->rx.rsp_cons += skb_queue_len(&tmpq);
                                goto err;
                        }
                }
@@ -1407,6 +1367,9 @@ err:
                np->stats.rx_bytes += skb->len;
 
                __skb_queue_tail(&rxq, skb);
+
+               np->rx.rsp_cons = ++i;
+               work_done++;
        }
 
        if (pages_flipped) {
@@ -1654,15 +1617,40 @@ static void xennet_set_features(struct n
                xennet_set_tso(dev, 1);
 }
 
-static void network_connect(struct net_device *dev)
+static int network_connect(struct net_device *dev)
 {
        struct netfront_info *np = netdev_priv(dev);
-       int i, requeue_idx;
+       int i, requeue_idx, err;
        struct sk_buff *skb;
        grant_ref_t ref;
        netif_rx_request_t *req;
+       unsigned int feature_rx_copy, feature_rx_flip;
+
+       err = xenbus_scanf(XBT_NIL, np->xbdev->otherend,
+                          "feature-rx-copy", "%u", &feature_rx_copy);
+       if (err != 1)
+               feature_rx_copy = 0;
+       err = xenbus_scanf(XBT_NIL, np->xbdev->otherend,
+                          "feature-rx-flip", "%u", &feature_rx_flip);
+       if (err != 1)
+               feature_rx_flip = 1;
+
+       /*
+        * Copy packets on receive path if:
+        *  (a) This was requested by user, and the backend supports it; or
+        *  (b) Flipping was requested, but this is unsupported by the backend.
+        */
+       np->copying_receiver = ((MODPARM_rx_copy && feature_rx_copy) ||
+                               (MODPARM_rx_flip && !feature_rx_flip));
+
+       err = talk_to_backend(np->xbdev, np);
+       if (err)
+               return err;
 
        xennet_set_features(dev);
+
+       IPRINTK("device %s has %sing receive path.\n",
+               dev->name, np->copying_receiver ? "copy" : "flipp");
 
        spin_lock_irq(&np->tx_lock);
        spin_lock(&np->rx_lock);
@@ -1719,6 +1707,8 @@ static void network_connect(struct net_d
 
        spin_unlock(&np->rx_lock);
        spin_unlock_irq(&np->tx_lock);
+
+       return 0;
 }
 
 static void netif_uninit(struct net_device *dev)
@@ -1884,8 +1874,7 @@ static void network_set_multicast_list(s
 {
 }
 
-static struct net_device * __devinit
-create_netdev(int handle, int copying_receiver, struct xenbus_device *dev)
+static struct net_device * __devinit create_netdev(struct xenbus_device *dev)
 {
        int i, err = 0;
        struct net_device *netdev = NULL;
@@ -1899,9 +1888,7 @@ create_netdev(int handle, int copying_re
        }
 
        np                   = netdev_priv(netdev);
-       np->handle           = handle;
        np->xbdev            = dev;
-       np->copying_receiver = copying_receiver;
 
        netif_carrier_off(netdev);
 
@@ -2032,10 +2019,12 @@ static int open_netdev(struct netfront_i
 
        err = xennet_sysfs_addif(info->netdev);
        if (err) {
-               /* This can be non-fatal: it only means no tuning parameters */
+               unregister_netdev(info->netdev);
                printk(KERN_WARNING "%s: add sysfs failed err=%d\n",
                       __FUNCTION__, err);
-       }
+               return err;
+       }
+
        return 0;
 }
 
diff -r 39d3d1cfe714 -r 15c1ca41a412 drivers/xen/xenbus/xenbus_client.c
--- a/drivers/xen/xenbus/xenbus_client.c        Wed Nov 08 15:44:19 2006 -0500
+++ b/drivers/xen/xenbus/xenbus_client.c        Wed Nov 08 18:58:23 2006 -0500
@@ -34,9 +34,6 @@
 #include <xen/gnttab.h>
 #include <xen/xenbus.h>
 #include <xen/driver_util.h>
-
-#define DPRINTK(fmt, args...) \
-    pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, 
##args)
 
 char *xenbus_strstate(enum xenbus_state state)
 {
diff -r 39d3d1cfe714 -r 15c1ca41a412 drivers/xen/xenbus/xenbus_probe.c
--- a/drivers/xen/xenbus/xenbus_probe.c Wed Nov 08 15:44:19 2006 -0500
+++ b/drivers/xen/xenbus/xenbus_probe.c Wed Nov 08 18:58:23 2006 -0500
@@ -925,7 +925,7 @@ EXPORT_SYMBOL_GPL(register_xenstore_noti
 
 void unregister_xenstore_notifier(struct notifier_block *nb)
 {
-       blocking_notifier_chain_unregister(&xenstore_notifier_list, nb);
+       blocking_notifier_chain_register(&xenstore_notifier_list, nb);
 }
 EXPORT_SYMBOL_GPL(unregister_xenstore_notifier);
 

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

<Prev in Thread] Current Thread [Next in Thread>
  • [XenPPC] [linux-ppc-2.6] [XEN][POWERPC] Driver refresh, Xen patchbot-linux-ppc-2 . 6 <=