Signed-off-by: Kieran Mansley <kmansley@xxxxxxxxxxxxxx>
Cleanup vif_state on device removal
diff -r f992a517aba5 drivers/xen/netfront/accel.c
--- a/drivers/xen/netfront/accel.c Wed Oct 03 13:41:33 2007 +0100
+++ b/drivers/xen/netfront/accel.c Wed Oct 03 13:45:55 2007 +0100
@@ -500,6 +500,30 @@ EXPORT_SYMBOL_GPL(netfront_accelerator_r
/*
+ * Remove the hooks from a single vif state.
+ */
+static void
+accelerator_remove_single_hook(struct netfront_accelerator *accelerator,
+ struct netfront_accel_vif_state *vif_state)
+{
+ /* Make sure there are no data path operations going on */
+ netif_poll_disable(vif_state->np->netdev);
+ netif_tx_lock_bh(vif_state->np->netdev);
+
+ /*
+ * Remove the hooks, but leave the vif_state on the
+ * accelerator's list as that signifies this vif is
+ * interested in using that accelerator if it becomes
+ * available again
+ */
+ vif_state->hooks = NULL;
+
+ netif_tx_unlock_bh(vif_state->np->netdev);
+ netif_poll_enable(vif_state->np->netdev);
+}
+
+
+/*
* Safely remove the accelerator function hooks from a netfront state.
*/
static void accelerator_remove_hooks(struct netfront_accelerator *accelerator,
@@ -513,20 +537,7 @@ static void accelerator_remove_hooks(str
list_for_each_entry_safe(vif_state, tmp,
&accelerator->vif_states,
link) {
- /* Make sure there are no data path operations going on */
- netif_poll_disable(vif_state->np->netdev);
- netif_tx_lock_bh(vif_state->np->netdev);
-
- /*
- * Remove the hooks, but leave the vif_state on the
- * accelerator's list as that signifies this vif is
- * interested in using that accelerator if it becomes
- * available again
- */
- vif_state->hooks = NULL;
-
- netif_tx_unlock_bh(vif_state->np->netdev);
- netif_poll_enable(vif_state->np->netdev);
+ accelerator_remove_single_hook(accelerator, vif_state);
/*
* Remove the reference taken when the vif_state hooks
@@ -623,6 +634,8 @@ int netfront_accelerator_call_remove(str
int netfront_accelerator_call_remove(struct netfront_info *np,
struct xenbus_device *dev)
{
+ struct netfront_accelerator *accelerator = np->accelerator;
+ struct netfront_accel_vif_state *tmp_vif_state;
struct netfront_accel_hooks *hooks;
unsigned flags;
int rc = 0;
@@ -633,23 +646,53 @@ int netfront_accelerator_call_remove(str
* call to prevent the accelerator being able to modify the
* hooks in the middle (by, for example, unloading)
*/
- if (np->accel_vif_state.hooks) {
- spin_lock_irqsave(&np->accelerator->vif_states_lock, flags);
- hooks = np->accel_vif_state.hooks;
- if (hooks) {
- kref_get(&np->accel_vif_state.vif_kref);
- spin_unlock_irqrestore
- (&np->accelerator->vif_states_lock, flags);
-
- rc = np->accel_vif_state.hooks->remove(dev);
-
- kref_put(&np->accel_vif_state.vif_kref,
- vif_kref_release);
- } else {
- spin_unlock_irqrestore
- (&np->accelerator->vif_states_lock, flags);
- }
- }
+ spin_lock_irqsave(&np->accelerator->vif_states_lock, flags);
+ hooks = np->accel_vif_state.hooks;
+
+ /*
+ * Remove this vif_state from the accelerator's list
+ */
+ 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);
+ break;
+ }
+ }
+
+ if (hooks) {
+ kref_get(&np->accel_vif_state.vif_kref);
+ spin_unlock_irqrestore
+ (&np->accelerator->vif_states_lock, flags);
+
+ rc = np->accel_vif_state.hooks->remove(dev);
+
+ kref_put(&np->accel_vif_state.vif_kref,
+ vif_kref_release);
+
+ spin_lock_irqsave(&np->accelerator->vif_states_lock,
+ flags);
+
+ /*
+ * Try and do the opposite of accelerator_probe_new_vif
+ * to ensure there's no state pointing back at the
+ * netdev
+ */
+ accelerator_remove_single_hook(accelerator,
+ &np->accel_vif_state);
+
+ /*
+ * Remove the reference taken when the vif_state hooks
+ * were set, must be called without lock held
+ */
+ spin_unlock_irqrestore(&accelerator->vif_states_lock,
+ flags);
+ kref_put(&np->accel_vif_state.vif_kref,
+ vif_kref_release);
+ } else {
+ spin_unlock_irqrestore(&np->accelerator->vif_states_lock,
+ flags);
+ }
+
return rc;
}
netfront_cleanup_vifstate
Description: Text document
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|