aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Liu <bob.liu@oracle.com>2015-12-09 20:16:48 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2016-01-04 12:21:26 -0500
commit93bb277f97a6d319361766bde228717faf4abdeb (patch)
tree6cfb401fa392a96867579ac36bf5eb05826056cb
parentdb6fbc106786f26d95889c50c18b1f28aa543a17 (diff)
xen/blkback: Fix two memory leaks.
This patch fixs two memleaks: backtrace: [<ffffffff817ba5e8>] kmemleak_alloc+0x28/0x50 [<ffffffff81205e3b>] kmem_cache_alloc+0xbb/0x1d0 [<ffffffff81534028>] xen_blkbk_probe+0x58/0x230 [<ffffffff8146adb6>] xenbus_dev_probe+0x76/0x130 [<ffffffff81511716>] driver_probe_device+0x166/0x2c0 [<ffffffff815119bc>] __device_attach_driver+0xac/0xb0 [<ffffffff8150fa57>] bus_for_each_drv+0x67/0x90 [<ffffffff81511ab7>] __device_attach+0xc7/0x120 [<ffffffff81511b23>] device_initial_probe+0x13/0x20 [<ffffffff8151059a>] bus_probe_device+0x9a/0xb0 [<ffffffff8150f0a1>] device_add+0x3b1/0x5c0 [<ffffffff8150f47e>] device_register+0x1e/0x30 [<ffffffff8146a9e8>] xenbus_probe_node+0x158/0x170 [<ffffffff8146abaf>] xenbus_dev_changed+0x1af/0x1c0 [<ffffffff8146b1bb>] backend_changed+0x1b/0x20 [<ffffffff81468ca6>] xenwatch_thread+0xb6/0x160 unreferenced object 0xffff880007ba8ef8 (size 224): backtrace: [<ffffffff817ba5e8>] kmemleak_alloc+0x28/0x50 [<ffffffff81205c73>] __kmalloc+0xd3/0x1e0 [<ffffffff81534d87>] frontend_changed+0x2c7/0x580 [<ffffffff8146af12>] xenbus_otherend_changed+0xa2/0xb0 [<ffffffff8146b2c0>] frontend_changed+0x10/0x20 [<ffffffff81468ca6>] xenwatch_thread+0xb6/0x160 [<ffffffff810d3e97>] kthread+0xd7/0xf0 [<ffffffff817c4a9f>] ret_from_fork+0x3f/0x70 [<ffffffffffffffff>] 0xffffffffffffffff unreferenced object 0xffff8800048dcd38 (size 224): The first leak is caused by not put() the be->blkif reference which we had gotten in xen_blkif_alloc(), while the second is us not freeing blkif->rings in the right place. Signed-off-by: Bob Liu <bob.liu@oracle.com> Reported-and-Tested-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-rw-r--r--drivers/block/xen-blkback/xenbus.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index 44396b8a0cb2..876763f7f13e 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -297,8 +297,16 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
297 BUG_ON(ring->free_pages_num != 0); 297 BUG_ON(ring->free_pages_num != 0);
298 BUG_ON(ring->persistent_gnt_c != 0); 298 BUG_ON(ring->persistent_gnt_c != 0);
299 WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages)); 299 WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages));
300 xen_blkif_put(blkif);
300 } 301 }
301 blkif->nr_ring_pages = 0; 302 blkif->nr_ring_pages = 0;
303 /*
304 * blkif->rings was allocated in connect_ring, so we should free it in
305 * here.
306 */
307 kfree(blkif->rings);
308 blkif->rings = NULL;
309 blkif->nr_rings = 0;
302 310
303 return 0; 311 return 0;
304} 312}
@@ -310,7 +318,6 @@ static void xen_blkif_free(struct xen_blkif *blkif)
310 xen_vbd_free(&blkif->vbd); 318 xen_vbd_free(&blkif->vbd);
311 319
312 /* Make sure everything is drained before shutting down */ 320 /* Make sure everything is drained before shutting down */
313 kfree(blkif->rings);
314 kmem_cache_free(xen_blkif_cachep, blkif); 321 kmem_cache_free(xen_blkif_cachep, blkif);
315} 322}
316 323
@@ -484,7 +491,6 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle,
484static int xen_blkbk_remove(struct xenbus_device *dev) 491static int xen_blkbk_remove(struct xenbus_device *dev)
485{ 492{
486 struct backend_info *be = dev_get_drvdata(&dev->dev); 493 struct backend_info *be = dev_get_drvdata(&dev->dev);
487 unsigned int i;
488 494
489 pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id); 495 pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id);
490 496
@@ -499,12 +505,11 @@ static int xen_blkbk_remove(struct xenbus_device *dev)
499 505
500 dev_set_drvdata(&dev->dev, NULL); 506 dev_set_drvdata(&dev->dev, NULL);
501 507
502 if (be->blkif) { 508 if (be->blkif)
503 xen_blkif_disconnect(be->blkif); 509 xen_blkif_disconnect(be->blkif);
504 for (i = 0; i < be->blkif->nr_rings; i++)
505 xen_blkif_put(be->blkif);
506 }
507 510
511 /* Put the reference we set in xen_blkif_alloc(). */
512 xen_blkif_put(be->blkif);
508 kfree(be->mode); 513 kfree(be->mode);
509 kfree(be); 514 kfree(be);
510 return 0; 515 return 0;