]> xenbits.xensource.com Git - legacy/linux-2.6.18-xen.git/commitdiff
Netfront accelerator bug fix
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 23 Nov 2007 16:26:56 +0000 (16:26 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 23 Nov 2007 16:26:56 +0000 (16:26 +0000)
In testing Xen for the upcoming 3.2.0 release, we've found a bug in
the netfront accelerator support where if an accelerator was removed
before it had properly initialised it wasn't handled correctly.

Signed-off-by: Kieran Mansley <kmansley@solarflare.com>
drivers/xen/netfront/accel.c

index 6796ccc6e8f5fcb1e776fb48c78a06645806f105..925981d514c4220a331da2665616ab4f04bfa7bf 100644 (file)
@@ -465,15 +465,18 @@ static void accelerator_remove_hooks(struct netfront_accelerator *accelerator)
                                 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);
+               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);
 
-               /* Last chance to get statistics from the accelerator */
-               hooks->get_stats(vif_state->np->netdev, &vif_state->np->stats);
-               hooks->remove(vif_state->dev);
+               accelerator->hooks->remove(vif_state->dev);
        }
        
        accelerator->hooks = NULL;
@@ -530,15 +533,16 @@ static int do_remove(struct netfront_info *np, struct xenbus_device *dev,
 
                /* 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 = hooks->remove(dev);
+               rc = accelerator->hooks->remove(dev);
 
                spin_lock_irqsave(&accelerator->vif_states_lock, *lock_flags);
        }
-
  
        return rc;
 }