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

[Xen-changelog] [linux-2.6.18-xen] netfront accel: simplify locking



# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1193765693 0
# Node ID 1e34e96bc3ec1552f6965376b6a1a84f280d5011
# Parent  c807b5387fbba317b03bc0e5787edf3b2d4d2c52
netfront accel: simplify locking
Signed-off-by <kmansley@xxxxxxxxxxxxxx>
---
 drivers/xen/netfront/accel.c    |  518 +++++++++++-----------------------------
 drivers/xen/netfront/netfront.h |   22 -
 2 files changed, 151 insertions(+), 389 deletions(-)

diff -r c807b5387fbb -r 1e34e96bc3ec drivers/xen/netfront/accel.c
--- a/drivers/xen/netfront/accel.c      Tue Oct 30 17:34:26 2007 +0000
+++ b/drivers/xen/netfront/accel.c      Tue Oct 30 17:34:53 2007 +0000
@@ -31,7 +31,7 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/list.h>
-#include <linux/kref.h>
+#include <linux/mutex.h>
 
 #include <xen/xenbus.h>
 
@@ -45,29 +45,17 @@
 #define WPRINTK(fmt, args...)                          \
        printk(KERN_WARNING "netfront/accel: " fmt, ##args)
 
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 5)
-#define kref_init(x,y) kref_init(x,y)
-#define kref_put(x,y)  kref_put(x)
-#else
-#define kref_init(x,y) kref_init(x)
-#define kref_put(x,y)  kref_put(x,y)
-#endif
-
 /*
  * List of all netfront accelerator plugin modules available.  Each
  * list entry is of type struct netfront_accelerator.
  */ 
 static struct list_head accelerators_list;
 
-/*
- * Lock to protect access to accelerators_list
- */
+/* Lock to protect access to accelerators_list */
 static spinlock_t accelerators_lock;
 
-/* Forward declaration of kref cleanup functions */
-static void accel_kref_release(struct kref *ref);
-static void vif_kref_release(struct kref *ref);
-
+/* Mutex to prevent concurrent loads and suspends, etc. */
+DEFINE_MUTEX(accelerator_mutex);
 
 void netif_init_accel(void)
 {
@@ -105,9 +93,6 @@ 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;
-
-       np->accel_vif_state.ready_for_probe = 1;
-       np->accel_vif_state.need_probe = NULL;
 }
 
 
@@ -130,6 +115,11 @@ static void add_accelerator_vif(struct n
 static void add_accelerator_vif(struct netfront_accelerator *accelerator,
                                struct netfront_info *np)
 {
+       unsigned flags;
+
+       /* Need lock to write list */
+       spin_lock_irqsave(&accelerator->vif_states_lock, flags);
+
        if (np->accelerator == NULL) {
                np->accelerator = accelerator;
                
@@ -142,6 +132,8 @@ static void add_accelerator_vif(struct n
                 */
                BUG_ON(np->accelerator != accelerator);
        }
+
+       spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
 }
 
 
@@ -175,9 +167,6 @@ static int init_accelerator(const char *
 
        accelerator->hooks = hooks;
 
-       accelerator->ready_for_probe = 1;
-       accelerator->need_probe = NULL;
-
        list_add(&accelerator->link, &accelerators_list);
 
        *result = accelerator;
@@ -193,17 +182,9 @@ static void
 static void 
 accelerator_set_vif_state_hooks(struct netfront_accel_vif_state *vif_state)
 {
-       /* This function must be called with the vif_state_lock held */
+       /* This function must be called with the vif_states_lock held */
 
        DPRINTK("%p\n",vif_state);
-
-       /*
-        * Take references to stop hooks disappearing.
-        * This persists until vif_kref gets to zero.
-        */
-       kref_get(&vif_state->np->accelerator->accel_kref);
-       /* This persists until vif_state->hooks are cleared */
-       kref_init(&vif_state->vif_kref, vif_kref_release);
 
        /* Make sure there are no data path operations going on */
        netif_poll_disable(vif_state->np->netdev);
@@ -221,47 +202,22 @@ static void accelerator_probe_new_vif(st
                                      struct netfront_accelerator *accelerator)
 {
        struct netfront_accel_hooks *hooks;
-       unsigned flags;
-       
+
        DPRINTK("\n");
 
-       spin_lock_irqsave(&accelerator->vif_states_lock, flags);
-       
-       /*
-        * Include this frontend device on the accelerator's list
-        */
+       /* Include this frontend device on the accelerator's list */
        add_accelerator_vif(accelerator, np);
        
        hooks = accelerator->hooks;
        
        if (hooks) {
-               if (np->accel_vif_state.ready_for_probe) {
-                       np->accel_vif_state.ready_for_probe = 0;
-                       
-                       kref_get(&accelerator->accel_kref);
-                       
-                       spin_unlock_irqrestore(&accelerator->vif_states_lock,
-                                              flags);
-                       
-                       hooks->new_device(np->netdev, dev);
-                       
-                       kref_put(&accelerator->accel_kref,
-                                accel_kref_release);
-                       /* 
-                        * Hooks will get linked into vif_state by a
-                        * future call by the accelerator to
-                        * netfront_accelerator_ready()
-                        */
-                       return;
-               } else {
-                       if (np->accel_vif_state.need_probe != NULL)
-                               DPRINTK("Probe request on vif awaiting 
probe\n");
-                       np->accel_vif_state.need_probe = hooks;
-               }
-       }
-               
-       spin_unlock_irqrestore(&accelerator->vif_states_lock,
-                              flags);
+               hooks->new_device(np->netdev, dev);
+               /* 
+                * Hooks will get linked into vif_state by a future
+                * call by the accelerator to netfront_accelerator_ready()
+                */
+       }
+
        return;
 }
 
@@ -275,10 +231,12 @@ int netfront_load_accelerator(struct net
                              const char *frontend)
 {
        struct netfront_accelerator *accelerator;
-       int rc;
+       int rc = 0;
        unsigned flags;
 
        DPRINTK(" %s\n", frontend);
+
+       mutex_lock(&accelerator_mutex);
 
        spin_lock_irqsave(&accelerators_lock, flags);
 
@@ -292,6 +250,7 @@ int netfront_load_accelerator(struct net
 
                        accelerator_probe_new_vif(np, dev, accelerator);
 
+                       mutex_unlock(&accelerator_mutex);
                        return 0;
                }
        }
@@ -299,15 +258,16 @@ 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;
        }
 
        spin_unlock_irqrestore(&accelerators_lock, flags);
 
        /* Include this frontend device on the accelerator's list */
-       spin_lock_irqsave(&accelerator->vif_states_lock, flags);
        add_accelerator_vif(accelerator, np);
-       spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
+
+       mutex_unlock(&accelerator_mutex);
 
        DPRINTK("requesting module %s\n", frontend);
 
@@ -319,7 +279,7 @@ int netfront_load_accelerator(struct net
         * it's up and running, and we can continue from there 
         */
 
-       return 0;
+       return rc;
 }
 
 
@@ -331,21 +291,11 @@ int netfront_load_accelerator(struct net
  */
 static void 
 accelerator_probe_vifs(struct netfront_accelerator *accelerator,
-                      struct netfront_accel_hooks *hooks,
-                      unsigned *lock_flags)
+                      struct netfront_accel_hooks *hooks)
 {
        struct netfront_accel_vif_state *vif_state, *tmp;
 
-       /* Calling function must have taken the vif_states_lock */
-
        DPRINTK("%p\n", accelerator);
-
-       /* 
-        * kref_init() takes a single reference to the hooks that will
-        * persist until the accelerator hooks are removed (e.g. by
-        * accelerator module unload)
-        */
-       kref_init(&accelerator->accel_kref, accel_kref_release);
 
        /* 
         * Store the hooks for future calls to probe a new device, and
@@ -354,72 +304,23 @@ accelerator_probe_vifs(struct netfront_a
         */
        BUG_ON(hooks == NULL);
        accelerator->hooks = hooks;
-       
+
+       /* 
+        *  currently hold accelerator_mutex, so don't need
+        *  vif_states_lock to read the list
+        */
        list_for_each_entry_safe(vif_state, tmp, &accelerator->vif_states,
                                 link) {
                struct netfront_info *np = vif_state->np;
-
-               if (vif_state->ready_for_probe) {
-                       vif_state->ready_for_probe = 0;
-                       kref_get(&accelerator->accel_kref);
-
-                       /* 
-                        * drop lock before calling hook.  hooks are
-                        * protected by the kref
-                        */
-                       spin_unlock_irqrestore(&accelerator->vif_states_lock,
-                                              (*lock_flags));
-                       
-                       hooks->new_device(np->netdev, vif_state->dev);
-                       
-                       kref_put(&accelerator->accel_kref, accel_kref_release);
-
-                       /* Retake lock for next go round the loop */
-                       spin_lock_irqsave(&accelerator->vif_states_lock,
-                                         (*lock_flags));
-                       
-                       /*
-                        * Hooks will get linked into vif_state by a call to
-                        * netfront_accelerator_ready() once accelerator
-                        * plugin is ready for action
-                        */
-               } else {
-                       if (vif_state->need_probe != NULL)
-                               DPRINTK("Probe request on vif awaiting 
probe\n");
-                       vif_state->need_probe = hooks;
-               }
-       }
-       
-       /* Return with vif_states_lock held, as on entry */
-}
-
-
-/* 
- * Wrapper for accelerator_probe_vifs that checks now is a good time
- * to do the probe, and postpones till previous state cleared up if
- * necessary
- */
-static void 
-accelerator_probe_vifs_on_load(struct netfront_accelerator *accelerator,
-                              struct netfront_accel_hooks *hooks)
-{
-       unsigned flags;
-
-       DPRINTK("\n");
-
-       spin_lock_irqsave(&accelerator->vif_states_lock, flags);
-       
-       if (accelerator->ready_for_probe) {
-               accelerator->ready_for_probe = 0;
-               accelerator_probe_vifs(accelerator, hooks, &flags);
-       } else {
-               if (accelerator->need_probe)
-                       DPRINTK("Probe request on accelerator awaiting 
probe\n");
-               accelerator->need_probe = hooks;
-       }
-
-       spin_unlock_irqrestore(&accelerator->vif_states_lock,
-                              flags);
+               
+               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
+                */
+       }
 }
 
 
@@ -447,6 +348,8 @@ int netfront_accelerator_loaded(int vers
                }
        }
 
+       mutex_lock(&accelerator_mutex);
+
        spin_lock_irqsave(&accelerators_lock, flags);
 
        /* 
@@ -457,9 +360,9 @@ int netfront_accelerator_loaded(int vers
                if (match_accelerator(frontend, accelerator)) {
                        spin_unlock_irqrestore(&accelerators_lock, flags);
 
-                       accelerator_probe_vifs_on_load(accelerator, hooks);
-
-                       return 0;
+                       accelerator_probe_vifs(accelerator, hooks);
+
+                       goto out;
                }
        }
 
@@ -474,6 +377,8 @@ int netfront_accelerator_loaded(int vers
 
        spin_unlock_irqrestore(&accelerators_lock, flags);
 
+ out:
+       mutex_unlock(&accelerator_mutex);
        return 0;
 }
 EXPORT_SYMBOL_GPL(netfront_accelerator_loaded);
@@ -497,6 +402,10 @@ void netfront_accelerator_ready(const ch
 
        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);
 
@@ -509,11 +418,9 @@ void netfront_accelerator_ready(const ch
 
                        spin_unlock_irqrestore
                                (&accelerator->vif_states_lock, flags1);
-                       goto done;
+                       break;
                }
        }
-
- done:
        spin_unlock_irqrestore(&accelerators_lock, flags);
 }
 EXPORT_SYMBOL_GPL(netfront_accelerator_ready);
@@ -552,38 +459,24 @@ static void accelerator_remove_hooks(str
        struct netfront_accel_vif_state *vif_state, *tmp;
        unsigned flags;
 
-       spin_lock_irqsave(&accelerator->vif_states_lock, flags);
-
+       /* Mutex is held so don't need vif_states_lock to iterate list */
        list_for_each_entry_safe(vif_state, tmp,
                                 &accelerator->vif_states,
                                 link) {
+               spin_lock_irqsave(&accelerator->vif_states_lock, flags);
+
                BUG_ON(vif_state->hooks == NULL);
                hooks = vif_state->hooks;
                accelerator_remove_single_hook(accelerator, vif_state);
 
-               /* 
-                * Tell accelerator that this device is being removed,
-                * and remove the reference taken when the vif_state
-                * hooks were set; both must be called without lock
-                * held
-                */
                spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
 
                /* Last chance to get statistics from the accelerator */
                hooks->get_stats(vif_state->np->netdev, &vif_state->np->stats);
                hooks->remove(vif_state->dev);
-
-               kref_put(&vif_state->vif_kref, vif_kref_release);
-
-               spin_lock_irqsave(&accelerator->vif_states_lock, flags);
        }
        
        accelerator->hooks = NULL;
-
-       spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
-
-       /* Remove the reference taken when module loaded */ 
-       kref_put(&accelerator->accel_kref, accel_kref_release);
 }
 
 
@@ -597,82 +490,33 @@ void netfront_accelerator_stop(const cha
        struct netfront_accelerator *accelerator;
        unsigned flags;
 
+       mutex_lock(&accelerator_mutex);
        spin_lock_irqsave(&accelerators_lock, flags);
 
        list_for_each_entry(accelerator, &accelerators_list, link) {
                if (match_accelerator(frontend, accelerator)) {
                        spin_unlock_irqrestore(&accelerators_lock, flags);
 
-                       /* 
-                        * Use semaphore to ensure we know when all
-                        * uses of hooks are complete
-                        */
-                       sema_init(&accelerator->exit_semaphore, 0);
-
                        accelerator_remove_hooks(accelerator);
 
-                       /* Wait for hooks to be unused, then return */
-                       down(&accelerator->exit_semaphore);
-                       
-                       return;
+                       goto out;
                }
        }
        spin_unlock_irqrestore(&accelerators_lock, flags);
+ out:
+       mutex_unlock(&accelerator_mutex);
 }
 EXPORT_SYMBOL_GPL(netfront_accelerator_stop);
-
-
-
-int netfront_check_accelerator_queue_ready(struct net_device *dev,
-                                          struct netfront_info *np)
-{
-       struct netfront_accelerator *accelerator;
-       struct netfront_accel_hooks *hooks;
-       int rc = 1;
-       unsigned flags;
-
-       accelerator = np->accelerator;
-
-       /*
-        * Call the check ready accelerator hook. The use count for the
-        * accelerator's hooks is incremented for the duration of the
-        * call to prevent the accelerator being able to modify the
-        * hooks in the middle (by, for example, unloading)
-        */ 
-       if (np->accel_vif_state.hooks && accelerator) {
-               spin_lock_irqsave(&accelerator->vif_states_lock, flags); 
-               hooks = np->accel_vif_state.hooks;
-               if (hooks && np->accelerator == accelerator) {
-                       kref_get(&np->accel_vif_state.vif_kref);
-                       spin_unlock_irqrestore
-                               (&accelerator->vif_states_lock, flags);
-
-                       rc = np->accel_vif_state.hooks->check_ready(dev);
-                       
-                       kref_put(&np->accel_vif_state.vif_kref,
-                                vif_kref_release);
-               } else {
-                       spin_unlock_irqrestore
-                               (&accelerator->vif_states_lock, flags);
-               }
-       }
-
-       return rc;
-}
 
 
 /* Helper for call_remove and do_suspend */
 static int do_remove(struct netfront_info *np, struct xenbus_device *dev,
-                    unsigned lock_flags, int clear_accelerator)
+                    unsigned *lock_flags)
 {
        struct netfront_accelerator *accelerator = np->accelerator;
        struct netfront_accel_hooks *hooks;
-       unsigned flags;
        int rc = 0;
  
-       if(clear_accelerator)
-               np->accelerator = NULL;
-
        if (np->accel_vif_state.hooks) {
                hooks = np->accel_vif_state.hooks;
 
@@ -684,27 +528,15 @@ static int do_remove(struct netfront_inf
                accelerator_remove_single_hook(accelerator, 
                                               &np->accel_vif_state);
 
-               spin_unlock_irqrestore(&accelerator->vif_states_lock, 
-                                      lock_flags);
-
-               /* 
-                * No need to do kref_get before calling these hooks as we
-                * can borrow the one we have to drop after this call 
-                */ 
-
                /* Last chance to get statistics from the accelerator */
                hooks->get_stats(np->netdev, &np->stats);
 
+               spin_unlock_irqrestore(&accelerator->vif_states_lock, 
+                                      *lock_flags);
+
                rc = hooks->remove(dev);
-               
-               /* 
-                * Remove the reference taken when the vif_state hooks
-                * were set, must be called without lock held
-                */
-               kref_put(&np->accel_vif_state.vif_kref, vif_kref_release);
-       } else {
-               spin_unlock_irqrestore(&accelerator->vif_states_lock, 
-                                      lock_flags);     
+
+               spin_lock_irqsave(&accelerator->vif_states_lock, *lock_flags);
        }
 
  
@@ -715,16 +547,22 @@ int netfront_accelerator_call_remove(str
 int netfront_accelerator_call_remove(struct netfront_info *np,
                                     struct xenbus_device *dev)
 {
+       struct netfront_accelerator *accelerator;
        struct netfront_accel_vif_state *tmp_vif_state;
        unsigned flags;
+       int rc = 0; 
+
+       mutex_lock(&accelerator_mutex);
 
        /* Check that we've got a device that was accelerated */
        if (np->accelerator == NULL)
-               return 0;
-
-       spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
-
-       list_for_each_entry(tmp_vif_state, &np->accelerator->vif_states,
+               goto out;
+
+       accelerator = np->accelerator;
+
+       spin_lock_irqsave(&accelerator->vif_states_lock, flags); 
+
+       list_for_each_entry(tmp_vif_state, &accelerator->vif_states,
                            link) {
                if (tmp_vif_state == &np->accel_vif_state) {
                        list_del(&np->accel_vif_state.link);
@@ -732,8 +570,14 @@ int netfront_accelerator_call_remove(str
                }
        }
 
-       /* do_remove drops the lock for us */
-       return do_remove(np, dev, flags, 1);
+       rc = do_remove(np, dev, &flags);
+
+       np->accelerator = NULL;
+
+       spin_unlock_irqrestore(&accelerator->vif_states_lock, flags); 
+ out:
+       mutex_unlock(&accelerator_mutex);
+       return rc;
 }
   
   
@@ -741,21 +585,26 @@ int netfront_accelerator_suspend(struct 
                                 struct xenbus_device *dev)
 {
        unsigned flags;
-
+       int rc = 0;
+
+       mutex_lock(&accelerator_mutex);
 
        /* Check that we've got a device that was accelerated */
        if (np->accelerator == NULL)
-               return 0;
+               goto out;
 
        /* 
         * Call the remove accelerator hook, but leave the vif_state
         * on the accelerator's list in case there is a suspend_cancel.
         */
-       spin_lock_irqsave(&np->accelerator->vif_states_lock,
-                         flags); 
+       spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
        
-       /* do_remove drops the lock for us */
-       return do_remove(np, dev, flags, 0);
+       rc = do_remove(np, dev, &flags);
+
+       spin_unlock_irqrestore(&np->accelerator->vif_states_lock, flags); 
+ out:
+       mutex_unlock(&accelerator_mutex);
+       return rc;
 }
   
   
@@ -763,21 +612,18 @@ int netfront_accelerator_suspend_cancel(
                                        struct xenbus_device *dev)
 {
        struct netfront_accel_vif_state *accel_vif_state = NULL;
-       unsigned flags1, flags2;
- 
+ 
+       mutex_lock(&accelerator_mutex);
+
        /* Check that we've got a device that was accelerated */
        if (np->accelerator == NULL)
-               return 0;
-
-       spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
+               goto out;
+
        /* Find the vif_state from the accelerator's list */
        list_for_each_entry(accel_vif_state, &np->accelerator->vif_states,
                            link) {
                if (accel_vif_state->dev == dev) {
                        BUG_ON(accel_vif_state != &np->accel_vif_state);
-                       
-                       
spin_unlock_irqrestore(&np->accelerator->vif_states_lock,
-                                              flags); 
  
                        /*
                         * Kick things off again to restore
@@ -785,12 +631,12 @@ int netfront_accelerator_suspend_cancel(
                         */
                        accelerator_probe_new_vif(np, dev, np->accelerator);
  
-                       return 0;
+                       break;
                }
        }
        
-       spin_unlock_irqrestore(&np->accelerator->vif_states_lock, flags); 
- 
+ out:
+       mutex_unlock(&accelerator_mutex);
        return 0;
 }
  
@@ -802,17 +648,20 @@ void netfront_accelerator_resume(struct 
        spinlock_t *vif_states_lock;
        unsigned flags;
  
-       /* Check that we've got a device that was accelerated */
+       mutex_lock(&accelerator_mutex);
+
+       /* Check that we've got a device that was accelerated */
        if(np->accelerator == NULL)
-               return;
- 
-       spin_lock_irqsave(&np->accelerator->vif_states_lock, flags); 
- 
+               goto out;
+
        /* Find the vif_state from the accelerator's list */
        list_for_each_entry(accel_vif_state, &np->accelerator->vif_states, 
                            link) {
                if (accel_vif_state->dev == dev) {
                        BUG_ON(accel_vif_state != &np->accel_vif_state);
+ 
+                       vif_states_lock = &np->accelerator->vif_states_lock;
+                       spin_lock_irqsave(vif_states_lock, flags); 
  
                        /* 
                         * Remove it from the accelerator's list so
@@ -820,15 +669,40 @@ void netfront_accelerator_resume(struct 
                         * when they get connected
                         */
                        list_del(&accel_vif_state->link);
-                       vif_states_lock = &np->accelerator->vif_states_lock;
                        np->accelerator = NULL;
  
                        spin_unlock_irqrestore(vif_states_lock, flags); 
                        
-                       return;
+                       break;
                }
        }
-       spin_unlock_irqrestore(&np->accelerator->vif_states_lock, flags); 
+
+ out:
+       mutex_unlock(&accelerator_mutex);
+       return;
+}
+
+
+int netfront_check_accelerator_queue_ready(struct net_device *dev,
+                                          struct netfront_info *np)
+{
+       struct netfront_accelerator *accelerator;
+       struct netfront_accel_hooks *hooks;
+       int rc = 1;
+       unsigned flags;
+
+       accelerator = np->accelerator;
+
+       /* Call the check_ready accelerator hook. */ 
+       if (np->accel_vif_state.hooks && accelerator) {
+               spin_lock_irqsave(&accelerator->vif_states_lock, flags); 
+               hooks = np->accel_vif_state.hooks;
+               if (hooks && np->accelerator == accelerator)
+                       rc = np->accel_vif_state.hooks->check_ready(dev);
+               spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
+       }
+
+       return rc;
 }
 
 
@@ -841,30 +715,13 @@ void netfront_accelerator_call_stop_napi
 
        accelerator = np->accelerator;
 
-       /* 
-        * Call the stop_napi_interrupts accelerator hook.  The use
-        * count for the accelerator's hooks is incremented for the
-        * duration of the call to prevent the accelerator being able
-        * to modify the hooks in the middle (by, for example,
-        * unloading)
-        */
-
+       /* Call the stop_napi_interrupts accelerator hook. */
        if (np->accel_vif_state.hooks && accelerator != NULL) {
                spin_lock_irqsave(&accelerator->vif_states_lock, flags); 
                hooks = np->accel_vif_state.hooks;
-               if (hooks && np->accelerator == accelerator) {
-                       kref_get(&np->accel_vif_state.vif_kref);
-                       spin_unlock_irqrestore
-                               (&accelerator->vif_states_lock, flags);
-
+               if (hooks && np->accelerator == accelerator)
                        np->accel_vif_state.hooks->stop_napi_irq(dev);
-               
-                       kref_put(&np->accel_vif_state.vif_kref,
-                                vif_kref_release);
-               } else {
-                       spin_unlock_irqrestore
-                               (&accelerator->vif_states_lock, flags);
-               }
+               spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
        }
 }
 
@@ -879,90 +736,15 @@ int netfront_accelerator_call_get_stats(
 
        accelerator = np->accelerator;
 
-       /* 
-        * Call the get_stats accelerator hook.  The use count for the
-        * accelerator's hooks is incremented for the duration of the
-        * call to prevent the accelerator being able to modify the
-        * hooks in the middle (by, for example, unloading)
-        */
-
+       /* Call the get_stats accelerator hook. */
        if (np->accel_vif_state.hooks && accelerator != NULL) {
-               spin_lock_irqsave(accelerator->vif_states_lock, flags); 
+               spin_lock_irqsave(&accelerator->vif_states_lock, flags); 
                hooks = np->accel_vif_state.hooks;
-               if (hooks && np->accelerator == accelerator) {
-                       kref_get(&np->accel_vif_state.vif_kref);
-                       spin_unlock_irqrestore
-                               (&accelerator->vif_states_lock, flags);
-
+               if (hooks && np->accelerator == accelerator)
                        rc = np->accel_vif_state.hooks->get_stats(dev,
                                                                  &np->stats);
-               
-                       kref_put(&np->accel_vif_state.vif_kref,
-                                vif_kref_release);
-               } else {
-                       spin_unlock_irqrestore
-                               (&accelerator->vif_states_lock, flags);
-               }
+               spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
        }
        return rc;
 }
 
-
-/* 
- * Once all users of hooks have kref_put()'d we can signal that it's
- * safe to unload
- */ 
-static void accel_kref_release(struct kref *ref)
-{
-       struct netfront_accelerator *accelerator =
-               container_of(ref, struct netfront_accelerator, accel_kref);
-       struct netfront_accel_hooks *hooks;
-       unsigned flags;
-
-       DPRINTK("%p\n", accelerator);
-
-       /* Signal that all users of hooks are done */
-       up(&accelerator->exit_semaphore);
-
-       spin_lock_irqsave(&accelerator->vif_states_lock, flags);
-       if (accelerator->need_probe) {
-               hooks = accelerator->need_probe;
-               accelerator->need_probe = NULL;
-               accelerator_probe_vifs(accelerator, hooks, &flags);
-       } 
-       else
-               accelerator->ready_for_probe = 1;
-
-       spin_unlock_irqrestore(&accelerator->vif_states_lock, flags);
-}
-
-
-static void vif_kref_release(struct kref *ref)
-{
-       struct netfront_accel_vif_state *vif_state = 
-               container_of(ref, struct netfront_accel_vif_state, vif_kref);
-       struct netfront_accel_hooks *hooks;
-       unsigned flags;
-
-       DPRINTK("%p\n", vif_state);
-
-       /* 
-        * Now that this vif has finished using the hooks, it can
-        * decrement the accelerator's global copy ref count 
-        */
-       kref_put(&vif_state->np->accelerator->accel_kref, accel_kref_release);
-
-       spin_lock_irqsave(&vif_state->np->accelerator->vif_states_lock, flags);
-       if (vif_state->need_probe) {
-               hooks = vif_state->need_probe;
-               vif_state->need_probe = NULL;
-               spin_unlock_irqrestore
-                       (&vif_state->np->accelerator->vif_states_lock, flags);
-               hooks->new_device(vif_state->np->netdev, vif_state->dev);
-       } else {
-               vif_state->ready_for_probe = 1;
-               spin_unlock_irqrestore
-                       (&vif_state->np->accelerator->vif_states_lock, flags);
-       }
-}
-
diff -r c807b5387fbb -r 1e34e96bc3ec drivers/xen/netfront/netfront.h
--- a/drivers/xen/netfront/netfront.h   Tue Oct 30 17:34:26 2007 +0000
+++ b/drivers/xen/netfront/netfront.h   Tue Oct 30 17:34:53 2007 +0000
@@ -37,7 +37,6 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/list.h>
-#include <linux/kref.h>
 
 #define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE)
 #define NET_RX_RING_SIZE __RING_SIZE((struct netif_rx_sring *)0, PAGE_SIZE)
@@ -109,14 +108,6 @@ struct netfront_accel_vif_state {
        struct xenbus_device *dev;
        struct netfront_info *np;
        struct netfront_accel_hooks *hooks;
-
-       /* 
-        * Protect against removal of hooks while in use.  
-        */
-       struct kref vif_kref;
-
-       unsigned ready_for_probe;
-       struct netfront_accel_hooks *need_probe;
 }; 
 
 /* 
@@ -137,10 +128,7 @@ struct netfront_accelerator {
        char *frontend;
        /* The hooks into the accelerator plugin module */
        struct netfront_accel_hooks *hooks;
-       /* 
-        * Protect against removal of hooks while in use.  
-        */
-       struct kref accel_kref;
+
        /* 
         * List of per-netfront device state (struct
         * netfront_accel_vif_state) for each netfront device that is
@@ -148,14 +136,6 @@ struct netfront_accelerator {
         */
        struct list_head vif_states;
        spinlock_t vif_states_lock;
-       /* 
-        * Semaphore to signal that all users of this accelerator have
-        * finished using it before module is unloaded
-        */
-       struct semaphore exit_semaphore; 
-
-       unsigned ready_for_probe;
-       struct netfront_accel_hooks *need_probe;
 };
 
 struct netfront_info {

_______________________________________________
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®.