* xen-blkback: bug fixes
@ 2014-01-28 17:43 Roger Pau Monne
2014-01-28 17:43 ` [PATCH 1/3] xen-blkback: fix memory leak when persistent grants are used Roger Pau Monne
` (3 more replies)
0 siblings, 4 replies; 15+ messages in thread
From: Roger Pau Monne @ 2014-01-28 17:43 UTC (permalink / raw)
To: xen-devel, linux-kernel
blkback bug fixes for memory leaks (patches 1 and 2) and a race
(patch 3).
^ permalink raw reply [flat|nested] 15+ messages in thread* [PATCH 1/3] xen-blkback: fix memory leak when persistent grants are used 2014-01-28 17:43 xen-blkback: bug fixes Roger Pau Monne @ 2014-01-28 17:43 ` Roger Pau Monne 2014-01-28 17:43 ` [PATCH 2/3] xen-blkback: fix memory leaks Roger Pau Monne ` (2 subsequent siblings) 3 siblings, 0 replies; 15+ messages in thread From: Roger Pau Monne @ 2014-01-28 17:43 UTC (permalink / raw) To: xen-devel, linux-kernel Cc: Matt Rushton, Konrad Rzeszutek Wilk, Roger Pau Monné, Ian Campbell, David Vrabel, xen-devel, Anthony Liguori, Matt Wilson From: Matt Rushton <mrushton@amazon.com> Currently shrink_free_pagepool() is called before the pages used for persistent grants are released via free_persistent_gnts(). This results in a memory leak when a VBD that uses persistent grants is torn down. Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: "Roger Pau Monné" <roger.pau@citrix.com> Cc: Ian Campbell <Ian.Campbell@citrix.com> Cc: David Vrabel <david.vrabel@citrix.com> Cc: linux-kernel@vger.kernel.org Cc: xen-devel@lists.xen.org Cc: Anthony Liguori <aliguori@amazon.com> Signed-off-by: Matt Rushton <mrushton@amazon.com> Signed-off-by: Matt Wilson <msw@amazon.com> --- drivers/block/xen-blkback/blkback.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 6620b73..30ef7b3 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -625,9 +625,6 @@ purge_gnt_list: print_stats(blkif); } - /* Since we are shutting down remove all pages from the buffer */ - shrink_free_pagepool(blkif, 0 /* All */); - /* Free all persistent grant pages */ if (!RB_EMPTY_ROOT(&blkif->persistent_gnts)) free_persistent_gnts(blkif, &blkif->persistent_gnts, @@ -636,6 +633,9 @@ purge_gnt_list: BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts)); blkif->persistent_gnt_c = 0; + /* Since we are shutting down remove all pages from the buffer */ + shrink_free_pagepool(blkif, 0 /* All */); + if (log_stats) print_stats(blkif); -- 1.7.7.5 (Apple Git-26) ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 2/3] xen-blkback: fix memory leaks 2014-01-28 17:43 xen-blkback: bug fixes Roger Pau Monne 2014-01-28 17:43 ` [PATCH 1/3] xen-blkback: fix memory leak when persistent grants are used Roger Pau Monne @ 2014-01-28 17:43 ` Roger Pau Monne 2014-01-28 17:43 ` [PATCH 3/3] xen-blkback: fix shutdown race Roger Pau Monne 2014-01-28 19:38 ` [Xen-devel] xen-blkback: bug fixes Konrad Rzeszutek Wilk 3 siblings, 0 replies; 15+ messages in thread From: Roger Pau Monne @ 2014-01-28 17:43 UTC (permalink / raw) To: xen-devel, linux-kernel Cc: Roger Pau Monne, Konrad Rzeszutek Wilk, David Vrabel, Boris Ostrovsky, Matt Rushton, Matt Wilson, Ian Campbell I've at least identified two possible memory leaks in blkback, both related to the shutdown path of a VBD: - blkback doesn't wait for any pending purge work to finish before cleaning the list of free_pages. The purge work will call put_free_pages and thus we might end up with pages being added to the free_pages list after we have emptied it. Fix this by making sure there's no pending purge work before exiting xen_blkif_schedule, and moving the free_page cleanup code to xen_blkif_free. - blkback doesn't wait for pending requests to end before cleaning persistent grants and the list of free_pages. Again this can add pages to the free_pages list or persistent grants to the persistent_gnts red-black tree. Fixed by moving the persistent grants and free_pages cleanup code to xen_blkif_free. Also, add some checks in xen_blkif_free to make sure we are cleaning everything. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: David Vrabel <david.vrabel@citrix.com> Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> Cc: Matt Rushton <mrushton@amazon.com> Cc: Matt Wilson <msw@amazon.com> Cc: Ian Campbell <Ian.Campbell@citrix.com> --- drivers/block/xen-blkback/blkback.c | 27 ++++++++++++++++++--------- drivers/block/xen-blkback/common.h | 1 + drivers/block/xen-blkback/xenbus.c | 12 ++++++++++++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 30ef7b3..dcfe49f 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -375,7 +375,7 @@ static void purge_persistent_gnt(struct xen_blkif *blkif) pr_debug(DRV_PFX "Going to purge %u persistent grants\n", num_clean); - INIT_LIST_HEAD(&blkif->persistent_purge_list); + BUG_ON(!list_empty(&blkif->persistent_purge_list)); root = &blkif->persistent_gnts; purge_list: foreach_grant_safe(persistent_gnt, n, root, node) { @@ -625,6 +625,23 @@ purge_gnt_list: print_stats(blkif); } + /* Drain pending purge work */ + flush_work(&blkif->persistent_purge_work); + + if (log_stats) + print_stats(blkif); + + blkif->xenblkd = NULL; + xen_blkif_put(blkif); + + return 0; +} + +/* + * Remove persistent grants and empty the pool of free pages + */ +void xen_blkbk_free_caches(struct xen_blkif *blkif) +{ /* Free all persistent grant pages */ if (!RB_EMPTY_ROOT(&blkif->persistent_gnts)) free_persistent_gnts(blkif, &blkif->persistent_gnts, @@ -635,14 +652,6 @@ purge_gnt_list: /* Since we are shutting down remove all pages from the buffer */ shrink_free_pagepool(blkif, 0 /* All */); - - if (log_stats) - print_stats(blkif); - - blkif->xenblkd = NULL; - xen_blkif_put(blkif); - - return 0; } /* diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 8d88075..f733d76 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -376,6 +376,7 @@ int xen_blkif_xenbus_init(void); irqreturn_t xen_blkif_be_int(int irq, void *dev_id); int xen_blkif_schedule(void *arg); int xen_blkif_purge_persistent(void *arg); +void xen_blkbk_free_caches(struct xen_blkif *blkif); int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt, struct backend_info *be, int state); diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index c2014a0..8afef67 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -125,6 +125,7 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) blkif->persistent_gnts.rb_node = NULL; spin_lock_init(&blkif->free_pages_lock); INIT_LIST_HEAD(&blkif->free_pages); + INIT_LIST_HEAD(&blkif->persistent_purge_list); blkif->free_pages_num = 0; atomic_set(&blkif->persistent_gnt_in_use, 0); @@ -259,6 +260,17 @@ static void xen_blkif_free(struct xen_blkif *blkif) if (!atomic_dec_and_test(&blkif->refcnt)) BUG(); + /* Remove all persistent grants and the cache of ballooned pages. */ + xen_blkbk_free_caches(blkif); + + /* Make sure everything is drained before shutting down */ + BUG_ON(blkif->persistent_gnt_c != 0); + BUG_ON(atomic_read(&blkif->persistent_gnt_in_use) != 0); + BUG_ON(blkif->free_pages_num != 0); + BUG_ON(!list_empty(&blkif->persistent_purge_list)); + BUG_ON(!list_empty(&blkif->free_pages)); + BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts)); + /* Check that there is no request in use */ list_for_each_entry_safe(req, n, &blkif->pending_free, free_list) { list_del(&req->free_list); -- 1.7.7.5 (Apple Git-26) ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 3/3] xen-blkback: fix shutdown race 2014-01-28 17:43 xen-blkback: bug fixes Roger Pau Monne 2014-01-28 17:43 ` [PATCH 1/3] xen-blkback: fix memory leak when persistent grants are used Roger Pau Monne 2014-01-28 17:43 ` [PATCH 2/3] xen-blkback: fix memory leaks Roger Pau Monne @ 2014-01-28 17:43 ` Roger Pau Monne 2014-01-29 8:52 ` [Xen-devel] " Jan Beulich 2014-01-28 19:38 ` [Xen-devel] xen-blkback: bug fixes Konrad Rzeszutek Wilk 3 siblings, 1 reply; 15+ messages in thread From: Roger Pau Monne @ 2014-01-28 17:43 UTC (permalink / raw) To: xen-devel, linux-kernel Cc: Roger Pau Monne, Konrad Rzeszutek Wilk, David Vrabel, Boris Ostrovsky, Matt Rushton, Matt Wilson, Ian Campbell Move the call to xen_blkif_put after we have freed the request, otherwise we have a race between the release of the request and the cleanup done in xen_blkif_free. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: David Vrabel <david.vrabel@citrix.com> Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> Cc: Matt Rushton <mrushton@amazon.com> Cc: Matt Wilson <msw@amazon.com> Cc: Ian Campbell <Ian.Campbell@citrix.com> --- drivers/block/xen-blkback/blkback.c | 28 +++++++++++++++++++++------- 1 files changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index dcfe49f..8200aa0 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -985,17 +985,31 @@ static void __end_block_io_op(struct pending_req *pending_req, int error) * the proper response on the ring. */ if (atomic_dec_and_test(&pending_req->pendcnt)) { - xen_blkbk_unmap(pending_req->blkif, + struct xen_blkif *blkif = pending_req->blkif; + + xen_blkbk_unmap(blkif, pending_req->segments, pending_req->nr_pages); - make_response(pending_req->blkif, pending_req->id, + make_response(blkif, pending_req->id, pending_req->operation, pending_req->status); - xen_blkif_put(pending_req->blkif); - if (atomic_read(&pending_req->blkif->refcnt) <= 2) { - if (atomic_read(&pending_req->blkif->drain)) - complete(&pending_req->blkif->drain_complete); + free_req(blkif, pending_req); + /* + * Make sure the request is freed before releasing blkif, + * or there could be a race between free_req and the + * cleanup done in xen_blkif_free during shutdown. + * + * NB: The fact that we might try to wake up pending_free_wq + * before drain_complete (in case there's a drain going on) + * it's not a problem with our current implementation + * because we can assure there's no thread waiting on + * pending_free_wq if there's a drain going on, but it has + * to be taken into account if the current model is changed. + */ + xen_blkif_put(blkif); + if (atomic_read(&blkif->refcnt) <= 2) { + if (atomic_read(&blkif->drain)) + complete(&blkif->drain_complete); } - free_req(pending_req->blkif, pending_req); } } -- 1.7.7.5 (Apple Git-26) ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [Xen-devel] [PATCH 3/3] xen-blkback: fix shutdown race 2014-01-28 17:43 ` [PATCH 3/3] xen-blkback: fix shutdown race Roger Pau Monne @ 2014-01-29 8:52 ` Jan Beulich 2014-01-29 11:30 ` Roger Pau Monné 2014-02-03 16:58 ` Roger Pau Monné 0 siblings, 2 replies; 15+ messages in thread From: Jan Beulich @ 2014-01-29 8:52 UTC (permalink / raw) To: Roger Pau Monne Cc: Matt Rushton, Matt Wilson, David Vrabel, Ian Campbell, xen-devel, Boris Ostrovsky, linux-kernel >>> On 28.01.14 at 18:43, Roger Pau Monne <roger.pau@citrix.com> wrote: > --- a/drivers/block/xen-blkback/blkback.c > +++ b/drivers/block/xen-blkback/blkback.c > @@ -985,17 +985,31 @@ static void __end_block_io_op(struct pending_req > *pending_req, int error) > * the proper response on the ring. > */ > if (atomic_dec_and_test(&pending_req->pendcnt)) { > - xen_blkbk_unmap(pending_req->blkif, > + struct xen_blkif *blkif = pending_req->blkif; > + > + xen_blkbk_unmap(blkif, > pending_req->segments, > pending_req->nr_pages); > - make_response(pending_req->blkif, pending_req->id, > + make_response(blkif, pending_req->id, > pending_req->operation, pending_req->status); > - xen_blkif_put(pending_req->blkif); > - if (atomic_read(&pending_req->blkif->refcnt) <= 2) { > - if (atomic_read(&pending_req->blkif->drain)) > - complete(&pending_req->blkif->drain_complete); > + free_req(blkif, pending_req); > + /* > + * Make sure the request is freed before releasing blkif, > + * or there could be a race between free_req and the > + * cleanup done in xen_blkif_free during shutdown. > + * > + * NB: The fact that we might try to wake up pending_free_wq > + * before drain_complete (in case there's a drain going on) > + * it's not a problem with our current implementation > + * because we can assure there's no thread waiting on > + * pending_free_wq if there's a drain going on, but it has > + * to be taken into account if the current model is changed. > + */ > + xen_blkif_put(blkif); > + if (atomic_read(&blkif->refcnt) <= 2) { > + if (atomic_read(&blkif->drain)) > + complete(&blkif->drain_complete); > } > - free_req(pending_req->blkif, pending_req); > } > } The put is still too early imo - you're explicitly accessing field in the structure immediately afterwards. This may not be an issue at present, but I think it's at least a latent one. Apart from that, the two if()s would - at least to me - be more clear if combined into one. Jan ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Xen-devel] [PATCH 3/3] xen-blkback: fix shutdown race 2014-01-29 8:52 ` [Xen-devel] " Jan Beulich @ 2014-01-29 11:30 ` Roger Pau Monné 2014-02-03 16:58 ` Roger Pau Monné 1 sibling, 0 replies; 15+ messages in thread From: Roger Pau Monné @ 2014-01-29 11:30 UTC (permalink / raw) To: Jan Beulich Cc: Matt Rushton, Matt Wilson, David Vrabel, Ian Campbell, xen-devel, Boris Ostrovsky, linux-kernel On 29/01/14 08:52, Jan Beulich wrote: >>>> On 28.01.14 at 18:43, Roger Pau Monne <roger.pau@citrix.com> wrote: >> --- a/drivers/block/xen-blkback/blkback.c >> +++ b/drivers/block/xen-blkback/blkback.c >> @@ -985,17 +985,31 @@ static void __end_block_io_op(struct pending_req >> *pending_req, int error) >> * the proper response on the ring. >> */ >> if (atomic_dec_and_test(&pending_req->pendcnt)) { >> - xen_blkbk_unmap(pending_req->blkif, >> + struct xen_blkif *blkif = pending_req->blkif; >> + >> + xen_blkbk_unmap(blkif, >> pending_req->segments, >> pending_req->nr_pages); >> - make_response(pending_req->blkif, pending_req->id, >> + make_response(blkif, pending_req->id, >> pending_req->operation, pending_req->status); >> - xen_blkif_put(pending_req->blkif); >> - if (atomic_read(&pending_req->blkif->refcnt) <= 2) { >> - if (atomic_read(&pending_req->blkif->drain)) >> - complete(&pending_req->blkif->drain_complete); >> + free_req(blkif, pending_req); >> + /* >> + * Make sure the request is freed before releasing blkif, >> + * or there could be a race between free_req and the >> + * cleanup done in xen_blkif_free during shutdown. >> + * >> + * NB: The fact that we might try to wake up pending_free_wq >> + * before drain_complete (in case there's a drain going on) >> + * it's not a problem with our current implementation >> + * because we can assure there's no thread waiting on >> + * pending_free_wq if there's a drain going on, but it has >> + * to be taken into account if the current model is changed. >> + */ >> + xen_blkif_put(blkif); >> + if (atomic_read(&blkif->refcnt) <= 2) { >> + if (atomic_read(&blkif->drain)) >> + complete(&blkif->drain_complete); >> } >> - free_req(pending_req->blkif, pending_req); >> } >> } > > The put is still too early imo - you're explicitly accessing field in the > structure immediately afterwards. This may not be an issue at > present, but I think it's at least a latent one. Yes, thanks for catching that one, it's an issue that we should solve now on this patch or else I would just be solving a race by introducing a new one. > Apart from that, the two if()s would - at least to me - be more > clear if combined into one. Ack, will see how the patch ends up looking after getting rid of the new race. Roger. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Xen-devel] [PATCH 3/3] xen-blkback: fix shutdown race 2014-01-29 8:52 ` [Xen-devel] " Jan Beulich 2014-01-29 11:30 ` Roger Pau Monné @ 2014-02-03 16:58 ` Roger Pau Monné 2014-02-04 8:02 ` Jan Beulich 1 sibling, 1 reply; 15+ messages in thread From: Roger Pau Monné @ 2014-02-03 16:58 UTC (permalink / raw) To: Jan Beulich Cc: Matt Rushton, Matt Wilson, David Vrabel, Ian Campbell, xen-devel, Boris Ostrovsky, linux-kernel On 29/01/14 09:52, Jan Beulich wrote: >>>> On 28.01.14 at 18:43, Roger Pau Monne <roger.pau@citrix.com> wrote: >> --- a/drivers/block/xen-blkback/blkback.c >> +++ b/drivers/block/xen-blkback/blkback.c >> @@ -985,17 +985,31 @@ static void __end_block_io_op(struct pending_req >> *pending_req, int error) >> * the proper response on the ring. >> */ >> if (atomic_dec_and_test(&pending_req->pendcnt)) { >> - xen_blkbk_unmap(pending_req->blkif, >> + struct xen_blkif *blkif = pending_req->blkif; >> + >> + xen_blkbk_unmap(blkif, >> pending_req->segments, >> pending_req->nr_pages); >> - make_response(pending_req->blkif, pending_req->id, >> + make_response(blkif, pending_req->id, >> pending_req->operation, pending_req->status); >> - xen_blkif_put(pending_req->blkif); >> - if (atomic_read(&pending_req->blkif->refcnt) <= 2) { >> - if (atomic_read(&pending_req->blkif->drain)) >> - complete(&pending_req->blkif->drain_complete); >> + free_req(blkif, pending_req); >> + /* >> + * Make sure the request is freed before releasing blkif, >> + * or there could be a race between free_req and the >> + * cleanup done in xen_blkif_free during shutdown. >> + * >> + * NB: The fact that we might try to wake up pending_free_wq >> + * before drain_complete (in case there's a drain going on) >> + * it's not a problem with our current implementation >> + * because we can assure there's no thread waiting on >> + * pending_free_wq if there's a drain going on, but it has >> + * to be taken into account if the current model is changed. >> + */ >> + xen_blkif_put(blkif); >> + if (atomic_read(&blkif->refcnt) <= 2) { >> + if (atomic_read(&blkif->drain)) >> + complete(&blkif->drain_complete); >> } >> - free_req(pending_req->blkif, pending_req); >> } >> } > > The put is still too early imo - you're explicitly accessing field in the > structure immediately afterwards. This may not be an issue at > present, but I think it's at least a latent one. > > Apart from that, the two if()s would - at least to me - be more > clear if combined into one. In order to get rid of the race I had to introduce yet another atomic_t in xen_blkif struct, which is something I don't really like, but I could not see any other way to solve this. If that's fine I will resend the series, here is the reworked patch: --- diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index dcfe49f..d9b8cd3 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -945,7 +945,7 @@ static void xen_blk_drain_io(struct xen_blkif *blkif) do { /* The initial value is one, and one refcnt taken at the * start of the xen_blkif_schedule thread. */ - if (atomic_read(&blkif->refcnt) <= 2) + if (atomic_read(&blkif->inflight) == 0) break; wait_for_completion_interruptible_timeout( &blkif->drain_complete, HZ); @@ -985,17 +985,30 @@ static void __end_block_io_op(struct pending_req *pending_req, int error) * the proper response on the ring. */ if (atomic_dec_and_test(&pending_req->pendcnt)) { - xen_blkbk_unmap(pending_req->blkif, + struct xen_blkif *blkif = pending_req->blkif; + + xen_blkbk_unmap(blkif, pending_req->segments, pending_req->nr_pages); - make_response(pending_req->blkif, pending_req->id, + make_response(blkif, pending_req->id, pending_req->operation, pending_req->status); - xen_blkif_put(pending_req->blkif); - if (atomic_read(&pending_req->blkif->refcnt) <= 2) { - if (atomic_read(&pending_req->blkif->drain)) - complete(&pending_req->blkif->drain_complete); + free_req(blkif, pending_req); + /* + * Make sure the request is freed before releasing blkif, + * or there could be a race between free_req and the + * cleanup done in xen_blkif_free during shutdown. + * + * NB: The fact that we might try to wake up pending_free_wq + * before drain_complete (in case there's a drain going on) + * it's not a problem with our current implementation + * because we can assure there's no thread waiting on + * pending_free_wq if there's a drain going on, but it has + * to be taken into account if the current model is changed. + */ + if (atomic_dec_and_test(&blkif->inflight) && atomic_read(&blkif->drain)) { + complete(&blkif->drain_complete); } - free_req(pending_req->blkif, pending_req); + xen_blkif_put(blkif); } } @@ -1249,6 +1262,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, * below (in "!bio") if we are handling a BLKIF_OP_DISCARD. */ xen_blkif_get(blkif); + atomic_inc(&blkif->inflight); for (i = 0; i < nseg; i++) { while ((bio == NULL) || diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index f733d76..e40326a 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -278,6 +278,7 @@ struct xen_blkif { /* for barrier (drain) requests */ struct completion drain_complete; atomic_t drain; + atomic_t inflight; /* One thread per one blkif. */ struct task_struct *xenblkd; unsigned int waiting_reqs; diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 8afef67..84973c6 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -128,6 +128,7 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid) INIT_LIST_HEAD(&blkif->persistent_purge_list); blkif->free_pages_num = 0; atomic_set(&blkif->persistent_gnt_in_use, 0); + atomic_set(&blkif->inflight, 0); INIT_LIST_HEAD(&blkif->pending_free); ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [Xen-devel] [PATCH 3/3] xen-blkback: fix shutdown race 2014-02-03 16:58 ` Roger Pau Monné @ 2014-02-04 8:02 ` Jan Beulich 2014-02-04 8:16 ` Roger Pau Monné 0 siblings, 1 reply; 15+ messages in thread From: Jan Beulich @ 2014-02-04 8:02 UTC (permalink / raw) To: Roger Pau Monné Cc: Matt Rushton, Matt Wilson, DavidVrabel, Ian Campbell, xen-devel, Boris Ostrovsky, linux-kernel >>> On 03.02.14 at 17:58, Roger Pau Monné<roger.pau@citrix.com> wrote: > On 29/01/14 09:52, Jan Beulich wrote: >>>>> On 28.01.14 at 18:43, Roger Pau Monne <roger.pau@citrix.com> wrote: >>> + free_req(blkif, pending_req); >>> + /* >>> + * Make sure the request is freed before releasing blkif, >>> + * or there could be a race between free_req and the >>> + * cleanup done in xen_blkif_free during shutdown. >>> + * >>> + * NB: The fact that we might try to wake up pending_free_wq >>> + * before drain_complete (in case there's a drain going on) >>> + * it's not a problem with our current implementation >>> + * because we can assure there's no thread waiting on >>> + * pending_free_wq if there's a drain going on, but it has >>> + * to be taken into account if the current model is changed. >>> + */ >>> + xen_blkif_put(blkif); >>> + if (atomic_read(&blkif->refcnt) <= 2) { >>> + if (atomic_read(&blkif->drain)) >>> + complete(&blkif->drain_complete); >>> } >>> - free_req(pending_req->blkif, pending_req); >>> } >>> } >> >> The put is still too early imo - you're explicitly accessing field in the >> structure immediately afterwards. This may not be an issue at >> present, but I think it's at least a latent one. >> >> Apart from that, the two if()s would - at least to me - be more >> clear if combined into one. > > In order to get rid of the race I had to introduce yet another atomic_t > in xen_blkif struct, which is something I don't really like, but I > could not see any other way to solve this. If that's fine I will resend > the series, here is the reworked patch: Mind explaining why you can't simply move the xen_blkif_put() down between the if() and the free_ref(). Jan ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Xen-devel] [PATCH 3/3] xen-blkback: fix shutdown race 2014-02-04 8:02 ` Jan Beulich @ 2014-02-04 8:16 ` Roger Pau Monné 2014-02-04 8:31 ` Jan Beulich 0 siblings, 1 reply; 15+ messages in thread From: Roger Pau Monné @ 2014-02-04 8:16 UTC (permalink / raw) To: Jan Beulich Cc: Matt Rushton, Matt Wilson, DavidVrabel, Ian Campbell, xen-devel, Boris Ostrovsky, linux-kernel On 04/02/14 09:02, Jan Beulich wrote: >>>> On 03.02.14 at 17:58, Roger Pau Monné<roger.pau@citrix.com> wrote: >> On 29/01/14 09:52, Jan Beulich wrote: >>>>>> On 28.01.14 at 18:43, Roger Pau Monne <roger.pau@citrix.com> wrote: >>>> + free_req(blkif, pending_req); >>>> + /* >>>> + * Make sure the request is freed before releasing blkif, >>>> + * or there could be a race between free_req and the >>>> + * cleanup done in xen_blkif_free during shutdown. >>>> + * >>>> + * NB: The fact that we might try to wake up pending_free_wq >>>> + * before drain_complete (in case there's a drain going on) >>>> + * it's not a problem with our current implementation >>>> + * because we can assure there's no thread waiting on >>>> + * pending_free_wq if there's a drain going on, but it has >>>> + * to be taken into account if the current model is changed. >>>> + */ >>>> + xen_blkif_put(blkif); >>>> + if (atomic_read(&blkif->refcnt) <= 2) { >>>> + if (atomic_read(&blkif->drain)) >>>> + complete(&blkif->drain_complete); >>>> } >>>> - free_req(pending_req->blkif, pending_req); >>>> } >>>> } >>> >>> The put is still too early imo - you're explicitly accessing field in the >>> structure immediately afterwards. This may not be an issue at >>> present, but I think it's at least a latent one. >>> >>> Apart from that, the two if()s would - at least to me - be more >>> clear if combined into one. >> >> In order to get rid of the race I had to introduce yet another atomic_t >> in xen_blkif struct, which is something I don't really like, but I >> could not see any other way to solve this. If that's fine I will resend >> the series, here is the reworked patch: > > Mind explaining why you can't simply move the xen_blkif_put() > down between the if() and the free_ref(). You mean doing something like: if (atomic_read(&blkif->refcnt) <= 3) { if (atomic_read(&blkif->drain)) complete(&blkif->drain_complete); } xen_blkif_put(blkif); free_req(blkif, pending_req); This would not be safe, because we are comparing refcnt before decrementing it, and also we are not doing it atomically (the dec and compare). If for example we have two inflight requests, both could perform the atomic_read of refcnt, see there's still another inflight request, and then both decrement, without anyone calling complete. There's also the issue that with this approach as we are freeing the request after we have put blkif, which is a race with the cleanup being done in xen_blkif_free. Roger. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Xen-devel] [PATCH 3/3] xen-blkback: fix shutdown race 2014-02-04 8:16 ` Roger Pau Monné @ 2014-02-04 8:31 ` Jan Beulich 2014-02-04 8:39 ` Roger Pau Monné 0 siblings, 1 reply; 15+ messages in thread From: Jan Beulich @ 2014-02-04 8:31 UTC (permalink / raw) To: Roger Pau Monné Cc: Matt Rushton, Matt Wilson, DavidVrabel, Ian Campbell, xen-devel, Boris Ostrovsky, linux-kernel >>> On 04.02.14 at 09:16, Roger Pau Monné<roger.pau@citrix.com> wrote: > On 04/02/14 09:02, Jan Beulich wrote: >>>>> On 03.02.14 at 17:58, Roger Pau Monné<roger.pau@citrix.com> wrote: >>> On 29/01/14 09:52, Jan Beulich wrote: >>>>>>> On 28.01.14 at 18:43, Roger Pau Monne <roger.pau@citrix.com> wrote: >>>>> + free_req(blkif, pending_req); >>>>> + /* >>>>> + * Make sure the request is freed before releasing blkif, >>>>> + * or there could be a race between free_req and the >>>>> + * cleanup done in xen_blkif_free during shutdown. >>>>> + * >>>>> + * NB: The fact that we might try to wake up pending_free_wq >>>>> + * before drain_complete (in case there's a drain going on) >>>>> + * it's not a problem with our current implementation >>>>> + * because we can assure there's no thread waiting on >>>>> + * pending_free_wq if there's a drain going on, but it has >>>>> + * to be taken into account if the current model is changed. >>>>> + */ >>>>> + xen_blkif_put(blkif); >>>>> + if (atomic_read(&blkif->refcnt) <= 2) { >>>>> + if (atomic_read(&blkif->drain)) >>>>> + complete(&blkif->drain_complete); >>>>> } >>>>> - free_req(pending_req->blkif, pending_req); >>>>> } >>>>> } >>>> >>>> The put is still too early imo - you're explicitly accessing field in the >>>> structure immediately afterwards. This may not be an issue at >>>> present, but I think it's at least a latent one. >>>> >>>> Apart from that, the two if()s would - at least to me - be more >>>> clear if combined into one. >>> >>> In order to get rid of the race I had to introduce yet another atomic_t >>> in xen_blkif struct, which is something I don't really like, but I >>> could not see any other way to solve this. If that's fine I will resend >>> the series, here is the reworked patch: >> >> Mind explaining why you can't simply move the xen_blkif_put() >> down between the if() and the free_ref(). > > You mean doing something like: > > if (atomic_read(&blkif->refcnt) <= 3) { > if (atomic_read(&blkif->drain)) > complete(&blkif->drain_complete); > } > xen_blkif_put(blkif); > free_req(blkif, pending_req); Actually, I got the description wrong. I really meant free_req(); if (atomic_read ...) complete(); xen_blkif_put(); Jan ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Xen-devel] [PATCH 3/3] xen-blkback: fix shutdown race 2014-02-04 8:31 ` Jan Beulich @ 2014-02-04 8:39 ` Roger Pau Monné 0 siblings, 0 replies; 15+ messages in thread From: Roger Pau Monné @ 2014-02-04 8:39 UTC (permalink / raw) To: Jan Beulich Cc: Matt Rushton, Matt Wilson, DavidVrabel, Ian Campbell, xen-devel, Boris Ostrovsky, linux-kernel On 04/02/14 09:31, Jan Beulich wrote: >>>> On 04.02.14 at 09:16, Roger Pau Monné<roger.pau@citrix.com> wrote: >> On 04/02/14 09:02, Jan Beulich wrote: >>>>>> On 03.02.14 at 17:58, Roger Pau Monné<roger.pau@citrix.com> wrote: >>>> On 29/01/14 09:52, Jan Beulich wrote: >>>>>>>> On 28.01.14 at 18:43, Roger Pau Monne <roger.pau@citrix.com> wrote: >>>>>> + free_req(blkif, pending_req); >>>>>> + /* >>>>>> + * Make sure the request is freed before releasing blkif, >>>>>> + * or there could be a race between free_req and the >>>>>> + * cleanup done in xen_blkif_free during shutdown. >>>>>> + * >>>>>> + * NB: The fact that we might try to wake up pending_free_wq >>>>>> + * before drain_complete (in case there's a drain going on) >>>>>> + * it's not a problem with our current implementation >>>>>> + * because we can assure there's no thread waiting on >>>>>> + * pending_free_wq if there's a drain going on, but it has >>>>>> + * to be taken into account if the current model is changed. >>>>>> + */ >>>>>> + xen_blkif_put(blkif); >>>>>> + if (atomic_read(&blkif->refcnt) <= 2) { >>>>>> + if (atomic_read(&blkif->drain)) >>>>>> + complete(&blkif->drain_complete); >>>>>> } >>>>>> - free_req(pending_req->blkif, pending_req); >>>>>> } >>>>>> } >>>>> >>>>> The put is still too early imo - you're explicitly accessing field in the >>>>> structure immediately afterwards. This may not be an issue at >>>>> present, but I think it's at least a latent one. >>>>> >>>>> Apart from that, the two if()s would - at least to me - be more >>>>> clear if combined into one. >>>> >>>> In order to get rid of the race I had to introduce yet another atomic_t >>>> in xen_blkif struct, which is something I don't really like, but I >>>> could not see any other way to solve this. If that's fine I will resend >>>> the series, here is the reworked patch: >>> >>> Mind explaining why you can't simply move the xen_blkif_put() >>> down between the if() and the free_ref(). >> >> You mean doing something like: >> >> if (atomic_read(&blkif->refcnt) <= 3) { >> if (atomic_read(&blkif->drain)) >> complete(&blkif->drain_complete); >> } >> xen_blkif_put(blkif); >> free_req(blkif, pending_req); > > Actually, I got the description wrong. I really meant > > free_req(); > if (atomic_read ...) > complete(); > xen_blkif_put(); IMHO this is still a race, since we evaluate refcnt before decrementing it. If we have for example 2 in flight requests, both could read refcnt, both could see it's greater than 3 (so no one would call complete), and then both will decrement it, without anyone actually calling complete. Roger. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Xen-devel] xen-blkback: bug fixes 2014-01-28 17:43 xen-blkback: bug fixes Roger Pau Monne ` (2 preceding siblings ...) 2014-01-28 17:43 ` [PATCH 3/3] xen-blkback: fix shutdown race Roger Pau Monne @ 2014-01-28 19:38 ` Konrad Rzeszutek Wilk 2014-01-28 20:35 ` Boris Ostrovsky 2014-02-04 6:31 ` Matt Wilson 3 siblings, 2 replies; 15+ messages in thread From: Konrad Rzeszutek Wilk @ 2014-01-28 19:38 UTC (permalink / raw) To: Roger Pau Monne, boris.ostrovsky, david.vrabel; +Cc: xen-devel, linux-kernel On Tue, Jan 28, 2014 at 06:43:32PM +0100, Roger Pau Monne wrote: > blkback bug fixes for memory leaks (patches 1 and 2) and a race > (patch 3). They all look OK to me. I've stuck them in my 'stable/for-jens-3.14' branch and are testing them now (hadn't pushed it yet). Matt and Matt, Could you take a look at the other two patches as well? David, Boris, Are you OK with pushing those patches out to Jens Axboe if nobody gives an NACK by Friday? > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Xen-devel] xen-blkback: bug fixes 2014-01-28 19:38 ` [Xen-devel] xen-blkback: bug fixes Konrad Rzeszutek Wilk @ 2014-01-28 20:35 ` Boris Ostrovsky 2014-02-04 6:31 ` Matt Wilson 1 sibling, 0 replies; 15+ messages in thread From: Boris Ostrovsky @ 2014-01-28 20:35 UTC (permalink / raw) To: Konrad Rzeszutek Wilk Cc: Roger Pau Monne, david.vrabel, xen-devel, linux-kernel On 01/28/2014 02:38 PM, Konrad Rzeszutek Wilk wrote: > On Tue, Jan 28, 2014 at 06:43:32PM +0100, Roger Pau Monne wrote: >> blkback bug fixes for memory leaks (patches 1 and 2) and a race >> (patch 3). > They all look OK to me. I've stuck them in my 'stable/for-jens-3.14' > branch and are testing them now (hadn't pushed it yet). > > Matt and Matt, > > Could you take a look at the other two patches as well? > > David, Boris, > > Are you OK with pushing those patches out to Jens Axboe if nobody > gives an NACK by Friday? The patches look reasonable to me so I don't have any objections (but I am not particularly familiar with this code.) -boris ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Xen-devel] xen-blkback: bug fixes 2014-01-28 19:38 ` [Xen-devel] xen-blkback: bug fixes Konrad Rzeszutek Wilk 2014-01-28 20:35 ` Boris Ostrovsky @ 2014-02-04 6:31 ` Matt Wilson 2014-02-04 14:30 ` Konrad Rzeszutek Wilk 1 sibling, 1 reply; 15+ messages in thread From: Matt Wilson @ 2014-02-04 6:31 UTC (permalink / raw) To: Konrad Rzeszutek Wilk Cc: Roger Pau Monne, boris.ostrovsky, david.vrabel, xen-devel, linux-kernel, Matthew Rushton, Matt Wilson On Tue, Jan 28, 2014 at 03:38:37PM -0400, Konrad Rzeszutek Wilk wrote: > On Tue, Jan 28, 2014 at 06:43:32PM +0100, Roger Pau Monne wrote: > > blkback bug fixes for memory leaks (patches 1 and 2) and a race > > (patch 3). > > They all look OK to me. I've stuck them in my 'stable/for-jens-3.14' > branch and are testing them now (hadn't pushed it yet). > > Matt and Matt, > > Could you take a look at the other two patches as well? Sure, though somehow you didn't address your message to us, so I didn't see it until today. Matt Rushton did some review and testing on an earlier version that came out fine. We'll give the final series a test since there was still a bit of rework. --msw > David, Boris, > > Are you OK with pushing those patches out to Jens Axboe if nobody > gives an NACK by Friday? ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [Xen-devel] xen-blkback: bug fixes 2014-02-04 6:31 ` Matt Wilson @ 2014-02-04 14:30 ` Konrad Rzeszutek Wilk 0 siblings, 0 replies; 15+ messages in thread From: Konrad Rzeszutek Wilk @ 2014-02-04 14:30 UTC (permalink / raw) To: Matt Wilson Cc: Konrad Rzeszutek Wilk, linux-kernel, Matthew Rushton, david.vrabel, Matt Wilson, xen-devel, boris.ostrovsky, Roger Pau Monne On Mon, Feb 03, 2014 at 10:31:40PM -0800, Matt Wilson wrote: > On Tue, Jan 28, 2014 at 03:38:37PM -0400, Konrad Rzeszutek Wilk wrote: > > On Tue, Jan 28, 2014 at 06:43:32PM +0100, Roger Pau Monne wrote: > > > blkback bug fixes for memory leaks (patches 1 and 2) and a race > > > (patch 3). > > > > They all look OK to me. I've stuck them in my 'stable/for-jens-3.14' > > branch and are testing them now (hadn't pushed it yet). > > > > Matt and Matt, > > > > Could you take a look at the other two patches as well? > > Sure, though somehow you didn't address your message to us, so I > didn't see it until today. Duh! > > Matt Rushton did some review and testing on an earlier version that > came out fine. We'll give the final series a test since there was > still a bit of rework. <nods> > > --msw > > > David, Boris, > > > > Are you OK with pushing those patches out to Jens Axboe if nobody > > gives an NACK by Friday? > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xen.org > http://lists.xen.org/xen-devel ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2014-02-04 14:31 UTC | newest] Thread overview: 15+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-01-28 17:43 xen-blkback: bug fixes Roger Pau Monne 2014-01-28 17:43 ` [PATCH 1/3] xen-blkback: fix memory leak when persistent grants are used Roger Pau Monne 2014-01-28 17:43 ` [PATCH 2/3] xen-blkback: fix memory leaks Roger Pau Monne 2014-01-28 17:43 ` [PATCH 3/3] xen-blkback: fix shutdown race Roger Pau Monne 2014-01-29 8:52 ` [Xen-devel] " Jan Beulich 2014-01-29 11:30 ` Roger Pau Monné 2014-02-03 16:58 ` Roger Pau Monné 2014-02-04 8:02 ` Jan Beulich 2014-02-04 8:16 ` Roger Pau Monné 2014-02-04 8:31 ` Jan Beulich 2014-02-04 8:39 ` Roger Pau Monné 2014-01-28 19:38 ` [Xen-devel] xen-blkback: bug fixes Konrad Rzeszutek Wilk 2014-01-28 20:35 ` Boris Ostrovsky 2014-02-04 6:31 ` Matt Wilson 2014-02-04 14:30 ` Konrad Rzeszutek Wilk
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).