[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20191220142954.9500-50-sashal@kernel.org>
Date: Fri, 20 Dec 2019 09:29:52 -0500
From: Sasha Levin <sashal@...nel.org>
To: linux-kernel@...r.kernel.org, stable@...r.kernel.org
Cc: Paul Durrant <pdurrant@...zon.com>,
Roger Pau Monné <roger.pau@...rix.com>,
Juergen Gross <jgross@...e.com>,
Sasha Levin <sashal@...nel.org>,
xen-devel@...ts.xenproject.org, linux-block@...r.kernel.org
Subject: [PATCH AUTOSEL 5.4 50/52] xen-blkback: prevent premature module unload
From: Paul Durrant <pdurrant@...zon.com>
[ Upstream commit fa2ac657f9783f0891b2935490afe9a7fd29d3fa ]
Objects allocated by xen_blkif_alloc come from the 'blkif_cache' kmem
cache. This cache is destoyed when xen-blkif is unloaded so it is
necessary to wait for the deferred free routine used for such objects to
complete. This necessity was missed in commit 14855954f636 "xen-blkback:
allow module to be cleanly unloaded". This patch fixes the problem by
taking/releasing extra module references in xen_blkif_alloc/free()
respectively.
Signed-off-by: Paul Durrant <pdurrant@...zon.com>
Reviewed-by: Roger Pau Monné <roger.pau@...rix.com>
Signed-off-by: Juergen Gross <jgross@...e.com>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---
drivers/block/xen-blkback/xenbus.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index b90dbcd99c03e..c4cd68116e7fc 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -171,6 +171,15 @@ static struct xen_blkif *xen_blkif_alloc(domid_t domid)
blkif->domid = domid;
atomic_set(&blkif->refcnt, 1);
init_completion(&blkif->drain_complete);
+
+ /*
+ * Because freeing back to the cache may be deferred, it is not
+ * safe to unload the module (and hence destroy the cache) until
+ * this has completed. To prevent premature unloading, take an
+ * extra module reference here and release only when the object
+ * has been freed back to the cache.
+ */
+ __module_get(THIS_MODULE);
INIT_WORK(&blkif->free_work, xen_blkif_deferred_free);
return blkif;
@@ -320,6 +329,7 @@ static void xen_blkif_free(struct xen_blkif *blkif)
/* Make sure everything is drained before shutting down */
kmem_cache_free(xen_blkif_cachep, blkif);
+ module_put(THIS_MODULE);
}
int __init xen_blkif_interface_init(void)
--
2.20.1
Powered by blists - more mailing lists