diff options
author | David S. Miller <davem@davemloft.net> | 2017-03-03 12:36:15 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-03-03 12:36:15 -0500 |
commit | 2ddbcea75a36dac2ff62ee33a0a8df37e994201e (patch) | |
tree | dda0845041f4823dd34c32ae1e974aeff896055d | |
parent | f7bb3d86a64775e0a7636d211dbd80cbeea6e618 (diff) | |
parent | a254d8f9a8a928772ef4608342125ccb35b79d5d (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.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index bb854f92f5a5..d2d7cd9145b1 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) | |||
492 | 492 | ||
493 | static void backend_disconnect(struct backend_info *be) | 493 | static void backend_disconnect(struct backend_info *be) |
494 | { | 494 | { |
495 | if (be->vif) { | 495 | struct xenvif *vif = be->vif; |
496 | |||
497 | if (vif) { | ||
496 | unsigned int queue_index; | 498 | unsigned int queue_index; |
499 | struct xenvif_queue *queues; | ||
497 | 500 | ||
498 | xen_unregister_watchers(be->vif); | 501 | xen_unregister_watchers(vif); |
499 | #ifdef CONFIG_DEBUG_FS | 502 | #ifdef CONFIG_DEBUG_FS |
500 | xenvif_debugfs_delif(be->vif); | 503 | xenvif_debugfs_delif(vif); |
501 | #endif /* CONFIG_DEBUG_FS */ | 504 | #endif /* CONFIG_DEBUG_FS */ |
502 | xenvif_disconnect_data(be->vif); | 505 | xenvif_disconnect_data(vif); |
503 | for (queue_index = 0; queue_index < be->vif->num_queues; ++queue_index) | 506 | for (queue_index = 0; |
504 | xenvif_deinit_queue(&be->vif->queues[queue_index]); | 507 | queue_index < vif->num_queues; |
508 | ++queue_index) | ||
509 | xenvif_deinit_queue(&vif->queues[queue_index]); | ||
510 | |||
511 | spin_lock(&vif->lock); | ||
512 | queues = vif->queues; | ||
513 | vif->num_queues = 0; | ||
514 | vif->queues = NULL; | ||
515 | spin_unlock(&vif->lock); | ||
505 | 516 | ||
506 | spin_lock(&be->vif->lock); | 517 | vfree(queues); |
507 | vfree(be->vif->queues); | ||
508 | be->vif->num_queues = 0; | ||
509 | be->vif->queues = NULL; | ||
510 | spin_unlock(&be->vif->lock); | ||
511 | 518 | ||
512 | xenvif_disconnect_ctrl(be->vif); | 519 | xenvif_disconnect_ctrl(vif); |
513 | } | 520 | } |
514 | } | 521 | } |
515 | 522 | ||