diff options
| author | Guixin Liu <kanie@linux.alibaba.com> | 2026-08-31 14:11:20 +0800 |
|---|---|---|
| committer | Dave Jiang <dave.jiang@intel.com> | 2026-09-17 20:05:17 -0700 |
| commit | bb26797c08d408ea7e8d3625045f0fe28714a425 (patch) | |
| tree | 448064924812364b646f5624c64f0f041c8520d7 | |
| parent | 0de71a1ab211694be7e88d56fc35c9bf72078ad1 (diff) | |
| download | linux-next-bb26797c08d408ea7e8d3625045f0fe28714a425.tar.gz linux-next-bb26797c08d408ea7e8d3625045f0fe28714a425.zip | |
cxl/region: Unregister the pmem region when the bridge is unbound
Removing cxl_acpi unbinds the nvdimm bridge before the regions it
serves. A region probe can therefore register its cxl_pmem_region and
only then find the bridge unbound, which leaves the new device with
nothing to remove it.
The orphan outlives the teardown and pins its region and its memdevs, so
a later cxl_acpi bind renumbers the root port, ports, endpoints,
decoders and the memdev.
Unregister the cxl_pmem_region when the bridge is unbound.
Found by code inspection. Racing a cxl_region bind against a cxl_acpi
unbind leaked a pmem_region device on 12 of 12 attempts, and none with
this patch.
Fixes: f17b558d6663 ("cxl/pmem: Refactor nvdimm device registration, delete the workqueue")
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
Reviewed-by: Richard Cheng <icheng@nvidia.com>
Reviewed-by: Li Ming <ming.li@zohomail.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Link: https://patch.msgid.link/20260831061120.200790-1-kanie@linux.alibaba.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
| -rw-r--r-- | drivers/cxl/core/region_pmem.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/cxl/core/region_pmem.c b/drivers/cxl/core/region_pmem.c index 23d97e3d78b6..7ab1373a95e0 100644 --- a/drivers/cxl/core/region_pmem.c +++ b/drivers/cxl/core/region_pmem.c @@ -168,12 +168,14 @@ int devm_cxl_add_pmem_region(struct cxl_region *cxlr) dev_name(dev)); scoped_guard(device, &cxl_nvb->dev) { - if (cxl_nvb->dev.driver) + if (cxl_nvb->dev.driver) { rc = devm_add_action_or_reset(&cxl_nvb->dev, cxlr_pmem_unregister, cxlr_pmem); - else + } else { rc = -ENXIO; + cxlr_pmem_unregister(cxlr_pmem); + } } if (rc) |
