Skip to content

Commit a3483ee

Browse files
yhuang-inteldavejiang
authored andcommitted
cxl/region: Fix a race condition in memory hotplug notifier
In the memory hotplug notifier function of the CXL region, cxl_region_perf_attrs_callback(), the node ID is obtained by checking the host address range of the region. However, the address range information is not available when the region is registered in devm_cxl_add_region(). Additionally, this information may be removed or added under the protection of cxl_region_rwsem during runtime. If the memory notifier is called for nodes other than that backed by the region, a race condition may occur, potentially leading to a NULL dereference or an invalid address range. The race condition is addressed by checking the availability of the address range information under the protection of cxl_region_rwsem. To enhance code readability and use guard(), the relevant code has been moved into a newly added function: cxl_region_nid(). Fixes: 067353a ("cxl/region: Add memory hotplug notifier for cxl region") Signed-off-by: Huang, Ying <ying.huang@intel.com> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Alison Schofield <alison.schofield@intel.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com> Cc: Dave Jiang <dave.jiang@intel.com> Cc: Bharata B Rao <bharata@amd.com> Cc: Alistair Popple <apopple@nvidia.com> Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> Cc: Davidlohr Bueso <dave@stgolabs.net> Cc: Vishal Verma <vishal.l.verma@intel.com> Cc: Ira Weiny <ira.weiny@intel.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Link: https://patch.msgid.link/20240618084639.1419629-2-ying.huang@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent a0caa19 commit a3483ee

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

drivers/cxl/core/region.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,22 +2304,33 @@ static bool cxl_region_update_coordinates(struct cxl_region *cxlr, int nid)
23042304
return true;
23052305
}
23062306

2307+
static int cxl_region_nid(struct cxl_region *cxlr)
2308+
{
2309+
struct cxl_region_params *p = &cxlr->params;
2310+
struct cxl_endpoint_decoder *cxled;
2311+
struct cxl_decoder *cxld;
2312+
2313+
guard(rwsem_read)(&cxl_region_rwsem);
2314+
cxled = p->targets[0];
2315+
if (!cxled)
2316+
return NUMA_NO_NODE;
2317+
cxld = &cxled->cxld;
2318+
return phys_to_target_node(cxld->hpa_range.start);
2319+
}
2320+
23072321
static int cxl_region_perf_attrs_callback(struct notifier_block *nb,
23082322
unsigned long action, void *arg)
23092323
{
23102324
struct cxl_region *cxlr = container_of(nb, struct cxl_region,
23112325
memory_notifier);
2312-
struct cxl_region_params *p = &cxlr->params;
2313-
struct cxl_endpoint_decoder *cxled = p->targets[0];
2314-
struct cxl_decoder *cxld = &cxled->cxld;
23152326
struct memory_notify *mnb = arg;
23162327
int nid = mnb->status_change_nid;
23172328
int region_nid;
23182329

23192330
if (nid == NUMA_NO_NODE || action != MEM_ONLINE)
23202331
return NOTIFY_DONE;
23212332

2322-
region_nid = phys_to_target_node(cxld->hpa_range.start);
2333+
region_nid = cxl_region_nid(cxlr);
23232334
if (nid != region_nid)
23242335
return NOTIFY_DONE;
23252336

0 commit comments

Comments
 (0)