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 <[email protected]> Cc: Dan Williams <[email protected]> Cc: Alison Schofield <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Jonathan Cameron <[email protected]> Cc: Dave Jiang <[email protected]> Cc: Bharata B Rao <[email protected]> Cc: Alistair Popple <[email protected]> Cc: Aneesh Kumar K.V <[email protected]> Cc: Davidlohr Bueso <[email protected]> Cc: Vishal Verma <[email protected]> Cc: Ira Weiny <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Dave Jiang <[email protected]>
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)