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

[Xen-changelog] [linux-2.6.18-xen] net accel: Allow network accelerators to deal with hot-plug/unplug on



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.