aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cxl/core/region.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2022-11-03 17:30:30 -0700
committerDan Williams <dan.j.williams@intel.com>2022-11-04 15:58:35 -0700
commit0d9e734018d70cecf79e2e4c6082167160a0f13f (patch)
tree0b1b634170cd8b47e5c2034a87c811843ff25ce9 /drivers/cxl/core/region.c
parentcxl/region: Fix region HPA ordering validation (diff)
downloadlinux-dev-0d9e734018d70cecf79e2e4c6082167160a0f13f.tar.xz
linux-dev-0d9e734018d70cecf79e2e4c6082167160a0f13f.zip
cxl/region: Fix cxl_region leak, cleanup targets at region delete
When a region is deleted any targets that have been previously assigned to that region hold references to it. Trigger those references to drop by detaching all targets at unregister_region() time. Otherwise that region object will leak as userspace has lost the ability to detach targets once region sysfs is torn down. Cc: <stable@vger.kernel.org> Fixes: b9686e8c8e39 ("cxl/region: Enable the assignment of endpoint decoders to regions") Reviewed-by: Dave Jiang <dave.jiang@intel.com> Reviewed-by: Vishal Verma <vishal.l.verma@intel.com> Link: https://lore.kernel.org/r/166752183055.947915.17681995648556534844.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to '')
-rw-r--r--drivers/cxl/core/region.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index d26ca7a6beae..c52465e09f26 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -1557,8 +1557,19 @@ static struct cxl_region *to_cxl_region(struct device *dev)
static void unregister_region(void *dev)
{
struct cxl_region *cxlr = to_cxl_region(dev);
+ struct cxl_region_params *p = &cxlr->params;
+ int i;
device_del(dev);
+
+ /*
+ * Now that region sysfs is shutdown, the parameter block is now
+ * read-only, so no need to hold the region rwsem to access the
+ * region parameters.
+ */
+ for (i = 0; i < p->interleave_ways; i++)
+ detach_target(cxlr, i);
+
cxl_region_iomem_release(cxlr);
put_device(dev);
}