cxl/region: Deal with numa nodes not enumerated by SRAT
authorDave Jiang <dave.jiang@intel.com>
Fri, 8 Mar 2024 21:59:31 +0000 (14:59 -0700)
committerDan Williams <dan.j.williams@intel.com>
Tue, 12 Mar 2024 21:54:03 +0000 (14:54 -0700)
For the numa nodes that are not created by SRAT, no memory_target is
allocated and is not managed by the HMAT_REPORTING code. Therefore
hmat_callback() memory hotplug notifier will exit early on those NUMA
nodes. The CXL memory hotplug notifier will need to call
node_set_perf_attrs() directly in order to setup the access sysfs
attributes.

In acpi_numa_init(), the last proximity domain (pxm) id created by SRAT is
stored. Add a helper function acpi_node_backed_by_real_pxm() in order to
check if a NUMA node id is defined by SRAT or created by CFMWS.

node_set_perf_attrs() symbol is exported to allow update of perf attribs
for a node. The sysfs path of
/sys/devices/system/node/nodeX/access0/initiators/* is created by
node_set_perf_attrs() for the various attributes where nodeX is matched
to the NUMA node of the CXL region.

Cc: Rafael J. Wysocki <rafael@kernel.org>
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Tested-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/20240308220055.2172956-13-dave.jiang@intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/acpi/numa/srat.c
drivers/base/node.c
drivers/cxl/core/cdat.c
drivers/cxl/core/core.h
drivers/cxl/core/region.c
include/linux/acpi.h

index 0214518fc582f47b6ed43faa7154ea60a9d8ae48..e45e64993c504c5db1624aae118d6144e4d912ee 100644 (file)
@@ -29,6 +29,8 @@ static int node_to_pxm_map[MAX_NUMNODES]
 unsigned char acpi_srat_revision __initdata;
 static int acpi_numa __initdata;
 
+static int last_real_pxm;
+
 void __init disable_srat(void)
 {
        acpi_numa = -1;
@@ -536,6 +538,7 @@ int __init acpi_numa_init(void)
                if (node_to_pxm_map[i] > fake_pxm)
                        fake_pxm = node_to_pxm_map[i];
        }
+       last_real_pxm = fake_pxm;
        fake_pxm++;
        acpi_table_parse_cedt(ACPI_CEDT_TYPE_CFMWS, acpi_parse_cfmws,
                              &fake_pxm);
@@ -547,6 +550,14 @@ int __init acpi_numa_init(void)
        return 0;
 }
 
+bool acpi_node_backed_by_real_pxm(int nid)
+{
+       int pxm = node_to_pxm(nid);
+
+       return pxm <= last_real_pxm;
+}
+EXPORT_SYMBOL_GPL(acpi_node_backed_by_real_pxm);
+
 static int acpi_get_pxm(acpi_handle h)
 {
        unsigned long long pxm;
index a73b0c9a401ada6a31ddc5d7391a2c9797e5a095..eb72580288e62727e5b2198a6451cf9c2533225a 100644 (file)
@@ -215,6 +215,7 @@ void node_set_perf_attrs(unsigned int nid, struct access_coordinate *coord,
                }
        }
 }
+EXPORT_SYMBOL_GPL(node_set_perf_attrs);
 
 /**
  * struct node_cache_info - Internal tracking for memory node caches
index ee1bc8fa396b72debbe2789c551563b3167a37aa..10d4f1d7dad1dbec6b4629f6e9896bc2acdcff11 100644 (file)
@@ -586,3 +586,8 @@ int cxl_update_hmat_access_coordinates(int nid, struct cxl_region *cxlr,
 {
        return hmat_update_target_coordinates(nid, &cxlr->coord[access], access);
 }
+
+bool cxl_need_node_perf_attrs_update(int nid)
+{
+       return !acpi_node_backed_by_real_pxm(nid);
+}
index e19800a7ce0680db15fb3a34c2c611d0820a319b..bc5a95665aa0af5490118e77e912dd2f6872fcde 100644 (file)
@@ -92,5 +92,6 @@ long cxl_pci_get_latency(struct pci_dev *pdev);
 
 int cxl_update_hmat_access_coordinates(int nid, struct cxl_region *cxlr,
                                       enum access_coordinate_class access);
+bool cxl_need_node_perf_attrs_update(int nid);
 
 #endif /* __CXL_CORE_H__ */
index 535492ec852906baa02357a1432ae66e56d2439a..5c186e0a39b965835bdd775aa3c841873b172633 100644 (file)
@@ -2279,7 +2279,12 @@ static bool cxl_region_update_coordinates(struct cxl_region *cxlr, int nid)
 
        for (int i = 0; i < ACCESS_COORDINATE_MAX; i++) {
                if (cxlr->coord[i].read_bandwidth) {
-                       rc = cxl_update_hmat_access_coordinates(nid, cxlr, i);
+                       rc = 0;
+                       if (cxl_need_node_perf_attrs_update(nid))
+                               node_set_perf_attrs(nid, &cxlr->coord[i], i);
+                       else
+                               rc = cxl_update_hmat_access_coordinates(nid, cxlr, i);
+
                        if (rc == 0)
                                cset++;
                }
index c84c2f34b8ee2ae4d4f36619dd0053b057664035..2a7c4b90d5897c01cf570ef2e685dc306c7a9875 100644 (file)
@@ -1559,4 +1559,13 @@ static inline int hmat_update_target_coordinates(int nid,
 }
 #endif
 
+#ifdef CONFIG_ACPI_NUMA
+bool acpi_node_backed_by_real_pxm(int nid);
+#else
+static inline bool acpi_node_backed_by_real_pxm(int nid)
+{
+       return false;
+}
+#endif
+
 #endif /*_LINUX_ACPI_H*/