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] [linux-2.6.18-xen] net accel: Allow network accelerators

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] net accel: Allow network accelerators to deal with hot-plug/unplug on
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 19 Dec 2007 12:40:20 -0800
Delivery-date: Wed, 19 Dec 2007 12:42:16 -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 1198075661 0
# Node ID 41e34ec8d24908a77d514415a26e3304c914cc98
# Parent  7db9c653b4f97250e38744a21df099f7ffc0e4a4
net accel: Allow network accelerators to deal with hot-plug/unplug on
physical devices. Add watch for acceleration configuration in frontend.

Signed-off-by: Kieran Mansley <kmansley@xxxxxxxxxxxxxx>
---
 drivers/xen/netback/accel.c     |  116 ++++++++--------
 drivers/xen/netback/common.h    |    2 
 drivers/xen/netfront/accel.c    |  290 ++++++++++++++++++++++++++--------------
 drivers/xen/netfront/netfront.c |   20 --
 drivers/xen/netfront/netfront.h |   26 +--
 5 files changed, 271 insertions(+), 183 deletions(-)

diff -r 7db9c653b4f9 -r 41e34ec8d249 drivers/xen/netback/accel.c
--- a/drivers/xen/netback/accel.c       Mon Dec 17 13:41:07 2007 -0700
+++ b/drivers/xen/netback/accel.c       Wed Dec 19 14:47:41 2007 +0000
@@ -76,12 +76,27 @@ static int match_accelerator(struct xenb
        }
 }
 
-/*
- * Notify all suitable backends that a new accelerator is available
- * and connected.  This will also notify the accelerator plugin module
+
+static void do_probe(struct backend_info *be, 
+                    struct netback_accelerator *accelerator,
+                    struct xenbus_device *xendev) 
+{
+       be->accelerator = accelerator;
+       atomic_inc(&be->accelerator->use_count);
+       if (be->accelerator->hooks->probe(xendev) != 0) {
+               atomic_dec(&be->accelerator->use_count);
+               module_put(be->accelerator->hooks->owner);
+               be->accelerator = NULL;
+       }
+}
+
+
+/*
+ * Notify suitable backends that a new accelerator is available and
+ * connected.  This will also notify the accelerator plugin module
  * that it is being used for a device through the probe hook.
  */
-static int netback_accelerator_tell_backend(struct device *dev, void *arg)
+static int netback_accelerator_probe_backend(struct device *dev, void *arg)
 {
        struct netback_accelerator *accelerator = 
                (struct netback_accelerator *)arg;
@@ -90,14 +105,37 @@ static int netback_accelerator_tell_back
        if (!strcmp("vif", xendev->devicetype)) {
                struct backend_info *be = xendev->dev.driver_data;
 
-               if (match_accelerator(xendev, be, accelerator)) {
-                       be->accelerator = accelerator;
-                       atomic_inc(&be->accelerator->use_count);
-                       be->accelerator->hooks->probe(xendev);
-               }
-       }
-       return 0;
-}
+               if (match_accelerator(xendev, be, accelerator) &&
+                   try_module_get(accelerator->hooks->owner)) {
+                       do_probe(be, accelerator, xendev);
+               }
+       }
+       return 0;
+}
+
+
+/*
+ * Notify suitable backends that an accelerator is unavailable.
+ */
+static int netback_accelerator_remove_backend(struct device *dev, void *arg)
+{
+       struct xenbus_device *xendev = to_xenbus_device(dev);
+       struct netback_accelerator *accelerator = 
+               (struct netback_accelerator *)arg;
+       
+       if (!strcmp("vif", xendev->devicetype)) {
+               struct backend_info *be = xendev->dev.driver_data;
+
+               if (be->accelerator == accelerator) {
+                       be->accelerator->hooks->remove(xendev);
+                       atomic_dec(&be->accelerator->use_count);
+                       module_put(be->accelerator->hooks->owner);
+                       be->accelerator = NULL;
+               }
+       }
+       return 0;
+}
+
 
 
 /*
@@ -133,7 +171,6 @@ int netback_connect_accelerator(unsigned
                return -ENOMEM;
        }
 
-
        new_accelerator->id = id;
        
        eth_name_len = strlen(eth_name)+1;
@@ -152,44 +189,22 @@ int netback_connect_accelerator(unsigned
        
        mutex_lock(&accelerators_mutex);
        list_add(&new_accelerator->link, &accelerators_list);
-       mutex_unlock(&accelerators_mutex);
        
        /* tell existing backends about new plugin */
        xenbus_for_each_backend(new_accelerator, 
-                               netback_accelerator_tell_backend);
+                               netback_accelerator_probe_backend);
+
+       mutex_unlock(&accelerators_mutex);
 
        return 0;
 
 }
 EXPORT_SYMBOL_GPL(netback_connect_accelerator);
-
-
-/* 
- * Remove the link from backend state to a particular accelerator
- */ 
-static int netback_accelerator_cleanup_backend(struct device *dev, void *arg)
-{
-       struct netback_accelerator *accelerator = 
-               (struct netback_accelerator *)arg;
-       struct xenbus_device *xendev = to_xenbus_device(dev);
-
-       if (!strcmp("vif", xendev->devicetype)) {
-               struct backend_info *be = xendev->dev.driver_data;
-               if (be->accelerator == accelerator)
-                       be->accelerator = NULL;
-       }
-       return 0;
-}
 
 
 /* 
  * Disconnect an accelerator plugin module that has previously been
  * connected.
- *
- * This should only be allowed when there are no remaining users -
- * i.e. it is not necessary to go through and clear all the hooks, as
- * they should have already been removed.  This is enforced by taking
- * a module reference to the plugin while the interfaces are in use
  */
 void netback_disconnect_accelerator(int id, const char *eth_name)
 {
@@ -197,17 +212,14 @@ void netback_disconnect_accelerator(int 
 
        mutex_lock(&accelerators_mutex);
        list_for_each_entry_safe(accelerator, next, &accelerators_list, link) {
-               if (strcmp(eth_name, accelerator->eth_name)) {
+               if (!strcmp(eth_name, accelerator->eth_name)) {
+                       xenbus_for_each_backend
+                               (accelerator, 
netback_accelerator_remove_backend);
                        BUG_ON(atomic_read(&accelerator->use_count) != 0);
-                       list_del(&accelerator->link);
-                       mutex_unlock(&accelerators_mutex);
-
-                       xenbus_for_each_backend(accelerator, 
-                                               
netback_accelerator_cleanup_backend);
-                               
+                       list_del(&accelerator->link);                           
                        kfree(accelerator->eth_name);
                        kfree(accelerator);
-                       return;
+                       break;
                }
        }
        mutex_unlock(&accelerators_mutex);
@@ -228,9 +240,7 @@ void netback_probe_accelerators(struct b
        list_for_each_entry(accelerator, &accelerators_list, link) { 
                if (match_accelerator(dev, be, accelerator) &&
                    try_module_get(accelerator->hooks->owner)) {
-                       be->accelerator = accelerator;
-                       atomic_inc(&be->accelerator->use_count);
-                       be->accelerator->hooks->probe(dev);
+                       do_probe(be, accelerator, dev);
                        break;
                }
        }
@@ -241,13 +251,15 @@ void netback_remove_accelerators(struct 
 void netback_remove_accelerators(struct backend_info *be,
                                 struct xenbus_device *dev)
 {
+       mutex_lock(&accelerators_mutex);
        /* Notify the accelerator (if any) of this device's removal */
-       if (be->accelerator) {
+       if (be->accelerator != NULL) {
                be->accelerator->hooks->remove(dev);
                atomic_dec(&be->accelerator->use_count);
                module_put(be->accelerator->hooks->owner);
-       }
-       be->accelerator = NULL;
+               be->accelerator = NULL;
+       }
+       mutex_unlock(&accelerators_mutex);
 }
 
 
diff -r 7db9c653b4f9 -r 41e34ec8d249 drivers/xen/netback/common.h
--- a/drivers/xen/netback/common.h      Mon Dec 17 13:41:07 2007 -0700
+++ b/drivers/xen/netback/common.h      Wed Dec 19 14:47:41 2007 +0000
@@ -150,7 +150,7 @@ struct backend_info {
        struct netback_accelerator *accelerator;
 };
 
-#define NETBACK_ACCEL_VERSION 0x00010000
+#define NETBACK_ACCEL_VERSION 0x00010001
 
 /* 
  * Connect an accelerator plugin module to netback.  Returns zero on
diff -r 7db9c653b4f9 -r 41e34ec8d249 drivers/xen/netfront/accel.c
--- a/drivers/xen/netfront/accel.c      Mon Dec 17 13:41:07 2007 -0700
+++ b/drivers/xen/netfront/accel.c      Wed Dec 19 14:47:41 2007 +0000
@@ -45,6 +45,12 @@
 #define WPRINTK(fmt, args...)                          \
        printk(KERN_WARNING "netfront/accel: " fmt, ##args)
 
+static int netfront_remove_accelerator(struct netfront_info *np,
+                                      struct xenbus_device *dev);
+static int netfront_load_accelerator(struct netfront_info *np, 
+                                    struct xenbus_device *dev, 
+                                    const char *frontend);
+
 /*
  * List of all netfront accelerator plugin modules available.  Each
  * list entry is of type struct netfront_accelerator.
@@ -83,6 +89,120 @@ void netif_exit_accel(void)
 
 
 /* 
+ * Watch the configured accelerator and change plugin if it's modified 
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+static void accel_watch_work(struct work_struct *context)
+#else
+static void accel_watch_work(void *context)
+#endif
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+       struct netfront_accel_vif_state *vif_state = 
+               container_of(context, struct netfront_accel_vif_state, 
+                            accel_work);
+#else
+        struct netfront_accel_vif_state *vif_state = 
+               (struct netfront_accel_vif_state *)context;
+#endif
+       struct netfront_info *np = vif_state->np;
+       char *accel_frontend;
+       int accel_len, rc = -1;
+
+       mutex_lock(&accelerator_mutex);
+
+       accel_frontend = xenbus_read(XBT_NIL, np->xbdev->otherend, 
+                                    "accel-frontend", &accel_len);
+       if (IS_ERR(accel_frontend)) {
+               accel_frontend = NULL;
+               netfront_remove_accelerator(np, np->xbdev);
+       } else {
+               /* If this is the first time, request the accelerator,
+                  otherwise only request one if it has changed */
+               if (vif_state->accel_frontend == NULL) {
+                       rc = netfront_load_accelerator(np, np->xbdev, 
+                                                      accel_frontend);
+               } else {
+                       if (strncmp(vif_state->accel_frontend, accel_frontend,
+                                   accel_len)) {
+                               netfront_remove_accelerator(np, np->xbdev);
+                               rc = netfront_load_accelerator(np, np->xbdev, 
+                                                              accel_frontend);
+                       }
+               }
+       }
+
+       /* Get rid of previous state and replace with the new name */
+       if (vif_state->accel_frontend != NULL)
+               kfree(vif_state->accel_frontend);
+       vif_state->accel_frontend = accel_frontend;
+
+       mutex_unlock(&accelerator_mutex);
+
+       if (rc == 0) {
+               DPRINTK("requesting module %s\n", accel_frontend);
+               request_module("%s", accel_frontend);
+               /*
+                * Module should now call netfront_accelerator_loaded() once
+                * it's up and running, and we can continue from there 
+                */
+       }
+}
+
+
+static void accel_watch_changed(struct xenbus_watch *watch,
+                               const char **vec, unsigned int len)
+{
+       struct netfront_accel_vif_state *vif_state = 
+               container_of(watch, struct netfront_accel_vif_state,
+                            accel_watch);
+       schedule_work(&vif_state->accel_work);
+}
+
+
+void netfront_accelerator_add_watch(struct netfront_info *np)
+{
+       int err;
+       
+       /* Check we're not trying to overwrite an existing watch */
+       BUG_ON(np->accel_vif_state.accel_watch.node != NULL);
+
+       /* Get a watch on the accelerator plugin */
+       err = xenbus_watch_path2(np->xbdev, np->xbdev->otherend, 
+                                "accel-frontend", 
+                                &np->accel_vif_state.accel_watch,
+                                accel_watch_changed);
+       if (err) {
+               DPRINTK("%s: Failed to register accel watch: %d\n",
+                        __FUNCTION__, err);
+               np->accel_vif_state.accel_watch.node = NULL;
+        }
+}
+
+
+static
+void netfront_accelerator_remove_watch(struct netfront_info *np)
+{
+       struct netfront_accel_vif_state *vif_state = &np->accel_vif_state;
+
+       /* Get rid of watch on accelerator plugin */
+       if (vif_state->accel_watch.node != NULL) {
+               unregister_xenbus_watch(&vif_state->accel_watch);
+               kfree(vif_state->accel_watch.node);
+               vif_state->accel_watch.node = NULL;
+
+               flush_scheduled_work();
+
+               /* Clean up any state left from watch */
+               if (vif_state->accel_frontend != NULL) {
+                       kfree(vif_state->accel_frontend);
+                       vif_state->accel_frontend = NULL;
+               }
+       }       
+}
+
+
+/* 
  * Initialise the accel_vif_state field in the netfront state
  */ 
 void init_accelerator_vif(struct netfront_info *np,
@@ -93,6 +213,13 @@ void init_accelerator_vif(struct netfron
        /* It's assumed that these things don't change */
        np->accel_vif_state.np = np;
        np->accel_vif_state.dev = dev;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+       INIT_WORK(&np->accel_vif_state.accel_work, accel_watch_work);
+#else
+       INIT_WORK(&np->accel_vif_state.accel_work, accel_watch_work, 
+                 &np->accel_vif_state);
+#endif
 }
 
 
@@ -202,6 +329,7 @@ static void accelerator_probe_new_vif(st
                                      struct netfront_accelerator *accelerator)
 {
        struct netfront_accel_hooks *hooks;
+       unsigned long flags;
 
        DPRINTK("\n");
 
@@ -211,32 +339,35 @@ static void accelerator_probe_new_vif(st
        hooks = accelerator->hooks;
        
        if (hooks) {
-               hooks->new_device(np->netdev, dev);
-               /* 
-                * Hooks will get linked into vif_state by a future
-                * call by the accelerator to netfront_accelerator_ready()
-                */
+               if (hooks->new_device(np->netdev, dev) == 0) {
+                       spin_lock_irqsave
+                               (&accelerator->vif_states_lock, flags);
+
+                       accelerator_set_vif_state_hooks(&np->accel_vif_state);
+
+                       spin_unlock_irqrestore
+                               (&accelerator->vif_states_lock, flags);
+               }
        }
 
        return;
 }
+
 
 /*  
  * Request that a particular netfront accelerator plugin is loaded.
  * Usually called as a result of the vif configuration specifying
- * which one to use.
- */
-int netfront_load_accelerator(struct netfront_info *np, 
-                             struct xenbus_device *dev, 
-                             const char *frontend)
+ * which one to use. Must be called with accelerator_mutex held 
+ */
+static int netfront_load_accelerator(struct netfront_info *np, 
+                                    struct xenbus_device *dev, 
+                                    const char *frontend)
 {
        struct netfront_accelerator *accelerator;
        int rc = 0;
        unsigned long flags;
 
        DPRINTK(" %s\n", frontend);
-
-       mutex_lock(&accelerator_mutex);
 
        spin_lock_irqsave(&accelerators_lock, flags);
 
@@ -249,8 +380,6 @@ int netfront_load_accelerator(struct net
                        spin_unlock_irqrestore(&accelerators_lock, flags);
 
                        accelerator_probe_new_vif(np, dev, accelerator);
-
-                       mutex_unlock(&accelerator_mutex);
                        return 0;
                }
        }
@@ -258,7 +387,6 @@ int netfront_load_accelerator(struct net
        /* Couldn't find it, so create a new one and load the module */
        if ((rc = init_accelerator(frontend, &accelerator, NULL)) < 0) {
                spin_unlock_irqrestore(&accelerators_lock, flags);
-               mutex_unlock(&accelerator_mutex);
                return rc;
        }
 
@@ -266,18 +394,6 @@ int netfront_load_accelerator(struct net
 
        /* Include this frontend device on the accelerator's list */
        add_accelerator_vif(accelerator, np);
-
-       mutex_unlock(&accelerator_mutex);
-
-       DPRINTK("requesting module %s\n", frontend);
-
-       /* load module */
-       request_module("%s", frontend);
-
-       /*
-        * Module should now call netfront_accelerator_loaded() once
-        * it's up and running, and we can continue from there 
-        */
 
        return rc;
 }
@@ -294,6 +410,7 @@ accelerator_probe_vifs(struct netfront_a
                       struct netfront_accel_hooks *hooks)
 {
        struct netfront_accel_vif_state *vif_state, *tmp;
+       unsigned long flags;
 
        DPRINTK("%p\n", accelerator);
 
@@ -313,13 +430,15 @@ accelerator_probe_vifs(struct netfront_a
                                 link) {
                struct netfront_info *np = vif_state->np;
                
-               hooks->new_device(np->netdev, vif_state->dev);
-               
-               /*
-                * Hooks will get linked into vif_state by a call to
-                * netfront_accelerator_ready() once accelerator
-                * plugin is ready for action
-                */
+               if (hooks->new_device(np->netdev, vif_state->dev) == 0) {
+                       spin_lock_irqsave
+                               (&accelerator->vif_states_lock, flags);
+
+                       accelerator_set_vif_state_hooks(vif_state);
+
+                       spin_unlock_irqrestore
+                               (&accelerator->vif_states_lock, flags);
+               }
        }
 }
 
@@ -385,48 +504,6 @@ EXPORT_SYMBOL_GPL(netfront_accelerator_l
 
 
 /* 
- * Called by the accelerator module after it has been probed with a
- * network device to say that it is ready to start accelerating
- * traffic on that device
- */
-void netfront_accelerator_ready(const char *frontend,
-                               struct xenbus_device *dev)
-{
-       struct netfront_accelerator *accelerator;
-       struct netfront_accel_vif_state *accel_vif_state;
-       unsigned long flags, flags1;
-
-       DPRINTK("%s %p\n", frontend, dev);
-
-       spin_lock_irqsave(&accelerators_lock, flags);
-
-       list_for_each_entry(accelerator, &accelerators_list, link) {
-               if (match_accelerator(frontend, accelerator)) {
-                       /* 
-                        * Mutex not held so need vif_states_lock for
-                        * list
-                        */
-                       spin_lock_irqsave
-                               (&accelerator->vif_states_lock, flags1);
-
-                       list_for_each_entry(accel_vif_state,
-                                           &accelerator->vif_states, link) {
-                               if (accel_vif_state->dev == dev)
-                                       accelerator_set_vif_state_hooks
-                                               (accel_vif_state);
-                       }
-
-                       spin_unlock_irqrestore
-                               (&accelerator->vif_states_lock, flags1);
-                       break;
-               }
-       }
-       spin_unlock_irqrestore(&accelerators_lock, flags);
-}
-EXPORT_SYMBOL_GPL(netfront_accelerator_ready);
-
-
-/* 
  * Remove the hooks from a single vif state.
  */
 static void 
@@ -467,16 +544,21 @@ static void accelerator_remove_hooks(str
 
                if(vif_state->hooks) {
                        hooks = vif_state->hooks;
-                       accelerator_remove_single_hook(accelerator, vif_state);
                        
                        /* Last chance to get statistics from the accelerator */
                        hooks->get_stats(vif_state->np->netdev,
                                         &vif_state->np->stats);
-               }
-
-               spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
-
-               accelerator->hooks->remove(vif_state->dev);
+
+                       spin_unlock_irqrestore(&accelerator->vif_states_lock,
+                                              flags);
+
+                       accelerator_remove_single_hook(accelerator, vif_state);
+
+                       accelerator->hooks->remove(vif_state->dev);
+               } else {
+                       spin_unlock_irqrestore(&accelerator->vif_states_lock,
+                                              flags);
+               }
        }
        
        accelerator->hooks = NULL;
@@ -522,6 +604,12 @@ static int do_remove(struct netfront_inf
  
        if (np->accel_vif_state.hooks) {
                hooks = np->accel_vif_state.hooks;
+
+               /* Last chance to get statistics from the accelerator */
+               hooks->get_stats(np->netdev, &np->stats);
+
+               spin_unlock_irqrestore(&accelerator->vif_states_lock, 
+                                      *lock_flags);
 
                /* 
                 * Try and do the opposite of accelerator_probe_new_vif
@@ -531,14 +619,6 @@ static int do_remove(struct netfront_inf
                accelerator_remove_single_hook(accelerator, 
                                               &np->accel_vif_state);
 
-               /* Last chance to get statistics from the accelerator */
-               hooks->get_stats(np->netdev, &np->stats);
-       }
-
-       if (accelerator->hooks) {
-               spin_unlock_irqrestore(&accelerator->vif_states_lock, 
-                                      *lock_flags);
-
                rc = accelerator->hooks->remove(dev);
 
                spin_lock_irqsave(&accelerator->vif_states_lock, *lock_flags);
@@ -546,21 +626,19 @@ static int do_remove(struct netfront_inf
  
        return rc;
 }
- 
-  
-int netfront_accelerator_call_remove(struct netfront_info *np,
-                                    struct xenbus_device *dev)
+
+
+static int netfront_remove_accelerator(struct netfront_info *np,
+                                      struct xenbus_device *dev)
 {
        struct netfront_accelerator *accelerator;
        struct netfront_accel_vif_state *tmp_vif_state;
        unsigned long flags;
        int rc = 0; 
 
-       mutex_lock(&accelerator_mutex);
-
        /* Check that we've got a device that was accelerated */
        if (np->accelerator == NULL)
-               goto out;
+               return rc;
 
        accelerator = np->accelerator;
 
@@ -579,17 +657,30 @@ int netfront_accelerator_call_remove(str
        np->accelerator = NULL;
 
        spin_unlock_irqrestore(&accelerator->vif_states_lock, flags); 
- out:
+
+       return rc;
+}
+
+
+int netfront_accelerator_call_remove(struct netfront_info *np,
+                                    struct xenbus_device *dev)
+{
+       int rc;
+       netfront_accelerator_remove_watch(np);
+       mutex_lock(&accelerator_mutex);
+       rc = netfront_remove_accelerator(np, dev);
        mutex_unlock(&accelerator_mutex);
        return rc;
 }
-  
+
   
 int netfront_accelerator_suspend(struct netfront_info *np,
                                 struct xenbus_device *dev)
 {
        unsigned long flags;
        int rc = 0;
+       
+       netfront_accelerator_remove_watch(np);
 
        mutex_lock(&accelerator_mutex);
 
@@ -641,6 +732,7 @@ int netfront_accelerator_suspend_cancel(
        
  out:
        mutex_unlock(&accelerator_mutex);
+       netfront_accelerator_add_watch(np);
        return 0;
 }
  
diff -r 7db9c653b4f9 -r 41e34ec8d249 drivers/xen/netfront/netfront.c
--- a/drivers/xen/netfront/netfront.c   Mon Dec 17 13:41:07 2007 -0700
+++ b/drivers/xen/netfront/netfront.c   Wed Dec 19 14:47:41 2007 +0000
@@ -378,6 +378,10 @@ static int talk_to_backend(struct xenbus
        if (err)
                goto out;
 
+       /* This will load an accelerator if one is configured when the
+        * watch fires */
+       netfront_accelerator_add_watch(info);
+
 again:
        err = xenbus_transaction_start(&xbt);
        if (err) {
@@ -452,6 +456,7 @@ again:
        xenbus_transaction_end(xbt, 1);
        xenbus_dev_fatal(dev, err, "%s", message);
  destroy_ring:
+       netfront_accelerator_call_remove(info, dev);
        netif_disconnect_backend(info);
  out:
        return err;
@@ -1746,9 +1751,7 @@ static int network_connect(struct net_de
        struct sk_buff *skb;
        grant_ref_t ref;
        netif_rx_request_t *req;
-       unsigned int feature_rx_copy, feature_rx_flip, feature_accel;
-       char *accel_frontend;
-       int accel_len;
+       unsigned int feature_rx_copy, feature_rx_flip;
 
        err = xenbus_scanf(XBT_NIL, np->xbdev->otherend,
                           "feature-rx-copy", "%u", &feature_rx_copy);
@@ -1759,12 +1762,6 @@ static int network_connect(struct net_de
        if (err != 1)
                feature_rx_flip = 1;
 
-       feature_accel = 1;
-       accel_frontend = xenbus_read(XBT_NIL, np->xbdev->otherend, 
-                                    "accel-frontend", &accel_len);
-       if (IS_ERR(accel_frontend)) 
-               feature_accel = 0;
-
        /*
         * Copy packets on receive path if:
         *  (a) This was requested by user, and the backend supports it; or
@@ -1776,11 +1773,6 @@ static int network_connect(struct net_de
        err = talk_to_backend(np->xbdev, np);
        if (err)
                return err;
-
-       if (feature_accel) {
-               netfront_load_accelerator(np, np->xbdev, accel_frontend);
-               kfree(accel_frontend);
-       }
 
        xennet_set_features(dev);
 
diff -r 7db9c653b4f9 -r 41e34ec8d249 drivers/xen/netfront/netfront.h
--- a/drivers/xen/netfront/netfront.h   Mon Dec 17 13:41:07 2007 -0700
+++ b/drivers/xen/netfront/netfront.h   Wed Dec 19 14:47:41 2007 +0000
@@ -95,7 +95,7 @@ struct netfront_accel_hooks {
 
 /* Version of API/protocol for communication between netfront and
    acceleration plugin supported */
-#define NETFRONT_ACCEL_VERSION 0x00010002
+#define NETFRONT_ACCEL_VERSION 0x00010003
 
 /* 
  * Per-netfront device state for the accelerator.  This is used to
@@ -108,6 +108,13 @@ struct netfront_accel_vif_state {
        struct xenbus_device *dev;
        struct netfront_info *np;
        struct netfront_accel_hooks *hooks;
+
+       /* Watch on the accelerator configuration value */
+       struct xenbus_watch accel_watch;
+       /* Work item to process change in accelerator */
+       struct work_struct accel_work;
+       /* The string from xenbus last time accel_watch fired */
+       char *accel_frontend;
 }; 
 
 /* 
@@ -210,18 +217,6 @@ extern int netfront_accelerator_loaded(i
                                       struct netfront_accel_hooks *hooks);
 
 /* 
- * Called when an accelerator plugin is ready to accelerate a device *
- * that has been passed to it from netfront using the "new_device"
- * hook.
- *
- * frontend: the string describing the accelerator. Must match the
- * one passed to netfront_accelerator_loaded()
- * dev: the xenbus device the plugin was asked to accelerate
- */
-extern void netfront_accelerator_ready(const char *frontend,
-                                      struct xenbus_device *dev);
-
-/* 
  * Called by an accelerator plugin module when it is about to unload.
  *
  * frontend: the string describing the accelerator.  Must match the
@@ -235,7 +230,6 @@ extern void netfront_accelerator_stop(co
  * wake, false if still busy 
  */
 extern int netfront_check_queue_ready(struct net_device *net_dev);
-
 
 
 /* Internal-to-netfront Functions */
@@ -267,9 +261,7 @@ int netfront_accelerator_call_get_stats(
 int netfront_accelerator_call_get_stats(struct netfront_info *np,
                                        struct net_device *dev);
 extern
-int netfront_load_accelerator(struct netfront_info *np, 
-                             struct xenbus_device *dev, 
-                             const char *frontend);
+void netfront_accelerator_add_watch(struct netfront_info *np);
 
 extern
 void netif_init_accel(void);

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] net accel: Allow network accelerators to deal with hot-plug/unplug on, Xen patchbot-linux-2.6.18-xen <=