From: liuqiqi <[email protected]>

When a cxl_dax_region is probed, set the numa_node of associated
cxl_memdev devices to match the target node derived from the region's
address range.
The cxl_dax_region_probe function computes the correct target node (nid)
via phys_to_target_node() but does not propagate this information to
the underlying cxl_memdev devices. This can cause memory allocations
to use an incorrect NUMA node.

Environment: node0/node1 = DRAM, node2 = CXL memory.
Before this fix:
  # cat /sys/bus/cxl/devices/mem0/numa_node
  1
After this fix:
  # cat /sys/bus/cxl/devices/mem0/numa_node
  2

Signed-off-by: liuqiqi <[email protected]>
---
 drivers/dax/cxl.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/dax/cxl.c b/drivers/dax/cxl.c
index 3ab39b77843d..a62af46ec31e 100644
--- a/drivers/dax/cxl.c
+++ b/drivers/dax/cxl.c
@@ -4,8 +4,27 @@
 #include <linux/dax.h>
 
 #include "../cxl/cxl.h"
+#include "../cxl/cxlmem.h"
 #include "bus.h"
 
+static void cxl_dax_set_numa_node(struct cxl_region *cxlr, int nid)
+{
+       struct cxl_region_params *p;
+       struct cxl_endpoint_decoder *cxled;
+       struct cxl_memdev *cxlmd;
+       int i;
+
+       p = &cxlr->params;
+       for (i = 0; i < p->nr_targets; i++) {
+               cxled = p->targets[i];
+               if (!cxled)
+                       continue;
+
+               cxlmd = cxled_to_memdev(cxled);
+               set_dev_node(&cxlmd->dev, nid);
+       }
+}
+
 static int cxl_dax_region_probe(struct device *dev)
 {
        struct cxl_dax_region *cxlr_dax = to_cxl_dax_region(dev);
@@ -28,6 +47,7 @@ static int cxl_dax_region_probe(struct device *dev)
                .size = range_len(&cxlr_dax->hpa_range),
                .memmap_on_memory = true,
        };
+       cxl_dax_set_numa_node(cxlr, nid);
 
        return PTR_ERR_OR_ZERO(devm_create_dev_dax(&data));
 }
-- 
2.25.1


Reply via email to