summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-03-03 09:36:15 -0800
committerDavid S. Miller <davem@davemloft.net>2017-03-03 09:36:15 -0800
commit2ddbcea75a36dac2ff62ee33a0a8df37e994201e (patch)
treedda0845041f4823dd34c32ae1e974aeff896055d
parentf7bb3d86a64775e0a7636d211dbd80cbeea6e618 (diff)
parenta254d8f9a8a928772ef4608342125ccb35b79d5d (diff)
Merge branch 'xen-netback-fixes'
Paul Durrant says: ==================== xen-netback: update memory leak fix to avoid BUG Commit 9a6cdf52b85e "xen-netback: fix memory leaks on XenBus disconnect" added missing code to fix a memory leak by calling vfree() in the appropriate place. Unfortunately subsequent commit f16f1df65f1c "xen-netback: protect resource cleaning on XenBus disconnect" then wrapped this call to vfree() in a spin lock, leading to a BUG due to incorrect context. Patch #1 makes the existing code more readable Patch #2 fixes the problem ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/xen-netback/xenbus.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index bb854f9..d2d7cd9 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -492,24 +492,31 @@ static int backend_create_xenvif(struct backend_info *be)
static void backend_disconnect(struct backend_info *be)
{
- if (be->vif) {
+ struct xenvif *vif = be->vif;
+
+ if (vif) {
unsigned int queue_index;
+ struct xenvif_queue *queues;
- xen_unregister_watchers(be->vif);
+ xen_unregister_watchers(vif);
#ifdef CONFIG_DEBUG_FS
- xenvif_debugfs_delif(be->vif);
+ xenvif_debugfs_delif(vif);
#endif /* CONFIG_DEBUG_FS */
- xenvif_disconnect_data(be->vif);
- for (queue_index = 0; queue_index < be->vif->num_queues; ++queue_index)
- xenvif_deinit_queue(&be->vif->queues[queue_index]);
+ xenvif_disconnect_data(vif);
+ for (queue_index = 0;
+ queue_index < vif->num_queues;
+ ++queue_index)
+ xenvif_deinit_queue(&vif->queues[queue_index]);
+
+ spin_lock(&vif->lock);
+ queues = vif->queues;
+ vif->num_queues = 0;
+ vif->queues = NULL;
+ spin_unlock(&vif->lock);
- spin_lock(&be->vif->lock);
- vfree(be->vif->queues);
- be->vif->num_queues = 0;
- be->vif->queues = NULL;
- spin_unlock(&be->vif->lock);
+ vfree(queues);
- xenvif_disconnect_ctrl(be->vif);
+ xenvif_disconnect_ctrl(vif);
}
}