Skip to content

Commit d4d3d8e

Browse files
roygersashalevin
authored andcommitted
xen/blkback: free requests on disconnection
commit f929d42 upstream. This is due to commit 86839c5 "xen/block: add multi-page ring support" When using an guest under UEFI - after the domain is destroyed the following warning comes from blkback. ------------[ cut here ]------------ WARNING: CPU: 2 PID: 95 at /home/julien/works/linux/drivers/block/xen-blkback/xenbus.c:274 xen_blkif_deferred_free+0x1f4/0x1f8() Modules linked in: CPU: 2 PID: 95 Comm: kworker/2:1 Tainted: G W 4.2.0 torvalds#85 Hardware name: APM X-Gene Mustang board (DT) Workqueue: events xen_blkif_deferred_free Call trace: [<ffff8000000890a8>] dump_backtrace+0x0/0x124 [<ffff8000000891dc>] show_stack+0x10/0x1c [<ffff8000007653bc>] dump_stack+0x78/0x98 [<ffff800000097e88>] warn_slowpath_common+0x9c/0xd4 [<ffff800000097f80>] warn_slowpath_null+0x14/0x20 [<ffff800000557a0c>] xen_blkif_deferred_free+0x1f0/0x1f8 [<ffff8000000ad020>] process_one_work+0x160/0x3b4 [<ffff8000000ad3b4>] worker_thread+0x140/0x494 [<ffff8000000b2e34>] kthread+0xd8/0xf0 ---[ end trace 6f859b7883c88cdd ]--- Request allocation has been moved to connect_ring, which is called every time blkback connects to the frontend (this can happen multiple times during a blkback instance life cycle). On the other hand, request freeing has not been moved, so it's only called when destroying the backend instance. Due to this mismatch, blkback can allocate the request pool multiple times, without freeing it. In order to fix it, move the freeing of requests to xen_blkif_disconnect to restore the symmetry between request allocation and freeing. Reported-by: Julien Grall <julien.grall@citrix.com> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Tested-by: Julien Grall <julien.grall@citrix.com> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> Cc: David Vrabel <david.vrabel@citrix.com> Cc: xen-devel@lists.xenproject.org Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
1 parent e279615 commit d4d3d8e

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

drivers/block/xen-blkback/xenbus.c

+20-18
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,9 @@ static int xen_blkif_map(struct xen_blkif *blkif, grant_ref_t *gref,
212212

213213
static int xen_blkif_disconnect(struct xen_blkif *blkif)
214214
{
215+
struct pending_req *req, *n;
216+
int i = 0, j;
217+
215218
if (blkif->xenblkd) {
216219
kthread_stop(blkif->xenblkd);
217220
wake_up(&blkif->shutdown_wq);
@@ -238,13 +241,28 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif)
238241
/* Remove all persistent grants and the cache of ballooned pages. */
239242
xen_blkbk_free_caches(blkif);
240243

244+
/* Check that there is no request in use */
245+
list_for_each_entry_safe(req, n, &blkif->pending_free, free_list) {
246+
list_del(&req->free_list);
247+
248+
for (j = 0; j < MAX_INDIRECT_SEGMENTS; j++)
249+
kfree(req->segments[j]);
250+
251+
for (j = 0; j < MAX_INDIRECT_PAGES; j++)
252+
kfree(req->indirect_pages[j]);
253+
254+
kfree(req);
255+
i++;
256+
}
257+
258+
WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages));
259+
blkif->nr_ring_pages = 0;
260+
241261
return 0;
242262
}
243263

244264
static void xen_blkif_free(struct xen_blkif *blkif)
245265
{
246-
struct pending_req *req, *n;
247-
int i = 0, j;
248266

249267
xen_blkif_disconnect(blkif);
250268
xen_vbd_free(&blkif->vbd);
@@ -257,22 +275,6 @@ static void xen_blkif_free(struct xen_blkif *blkif)
257275
BUG_ON(!list_empty(&blkif->free_pages));
258276
BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts));
259277

260-
/* Check that there is no request in use */
261-
list_for_each_entry_safe(req, n, &blkif->pending_free, free_list) {
262-
list_del(&req->free_list);
263-
264-
for (j = 0; j < MAX_INDIRECT_SEGMENTS; j++)
265-
kfree(req->segments[j]);
266-
267-
for (j = 0; j < MAX_INDIRECT_PAGES; j++)
268-
kfree(req->indirect_pages[j]);
269-
270-
kfree(req);
271-
i++;
272-
}
273-
274-
WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages));
275-
276278
kmem_cache_free(xen_blkif_cachep, blkif);
277279
}
278280

0 commit comments

Comments
 (0)