Skip to content

Commit d5c0078

Browse files
committed
Merge branch 'for-6.9/cxl-qos' into for-6.9/cxl
Pick up support for CXL "HMEM reporting" for v6.9, i.e. build an HMAT from CXL CDAT and PCIe switch information.
2 parents c6c3187 + debdce2 commit d5c0078

File tree

13 files changed

+492
-58
lines changed

13 files changed

+492
-58
lines changed

Documentation/ABI/testing/sysfs-bus-cxl

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,3 +552,37 @@ Description:
552552
attribute is only visible for devices supporting the
553553
capability. The retrieved errors are logged as kernel
554554
events when cxl_poison event tracing is enabled.
555+
556+
557+
What: /sys/bus/cxl/devices/regionZ/accessY/read_bandwidth
558+
/sys/bus/cxl/devices/regionZ/accessY/write_banwidth
559+
Date: Jan, 2024
560+
KernelVersion: v6.9
561+
Contact: linux-cxl@vger.kernel.org
562+
Description:
563+
(RO) The aggregated read or write bandwidth of the region. The
564+
number is the accumulated read or write bandwidth of all CXL memory
565+
devices that contributes to the region in MB/s. It is
566+
identical data that should appear in
567+
/sys/devices/system/node/nodeX/accessY/initiators/read_bandwidth or
568+
/sys/devices/system/node/nodeX/accessY/initiators/write_bandwidth.
569+
See Documentation/ABI/stable/sysfs-devices-node. access0 provides
570+
the number to the closest initiator and access1 provides the
571+
number to the closest CPU.
572+
573+
574+
What: /sys/bus/cxl/devices/regionZ/accessY/read_latency
575+
/sys/bus/cxl/devices/regionZ/accessY/write_latency
576+
Date: Jan, 2024
577+
KernelVersion: v6.9
578+
Contact: linux-cxl@vger.kernel.org
579+
Description:
580+
(RO) The read or write latency of the region. The number is
581+
the worst read or write latency of all CXL memory devices that
582+
contributes to the region in nanoseconds. It is identical data
583+
that should appear in
584+
/sys/devices/system/node/nodeX/accessY/initiators/read_latency or
585+
/sys/devices/system/node/nodeX/accessY/initiators/write_latency.
586+
See Documentation/ABI/stable/sysfs-devices-node. access0 provides
587+
the number to the closest initiator and access1 provides the
588+
number to the closest CPU.

drivers/acpi/numa/hmat.c

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,8 @@ struct target_cache {
5959
};
6060

6161
enum {
62-
NODE_ACCESS_CLASS_0 = 0,
63-
NODE_ACCESS_CLASS_1,
64-
NODE_ACCESS_CLASS_GENPORT_SINK,
62+
NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL = ACCESS_COORDINATE_MAX,
63+
NODE_ACCESS_CLASS_GENPORT_SINK_CPU,
6564
NODE_ACCESS_CLASS_MAX,
6665
};
6766

@@ -75,6 +74,7 @@ struct memory_target {
7574
struct node_cache_attrs cache_attrs;
7675
u8 gen_port_device_handle[ACPI_SRAT_DEVICE_HANDLE_SIZE];
7776
bool registered;
77+
bool ext_updated; /* externally updated */
7878
};
7979

8080
struct memory_initiator {
@@ -127,7 +127,8 @@ static struct memory_target *acpi_find_genport_target(u32 uid)
127127
/**
128128
* acpi_get_genport_coordinates - Retrieve the access coordinates for a generic port
129129
* @uid: ACPI unique id
130-
* @coord: The access coordinates written back out for the generic port
130+
* @coord: The access coordinates written back out for the generic port.
131+
* Expect 2 levels array.
131132
*
132133
* Return: 0 on success. Errno on failure.
133134
*
@@ -143,7 +144,10 @@ int acpi_get_genport_coordinates(u32 uid,
143144
if (!target)
144145
return -ENOENT;
145146

146-
*coord = target->coord[NODE_ACCESS_CLASS_GENPORT_SINK];
147+
coord[ACCESS_COORDINATE_LOCAL] =
148+
target->coord[NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL];
149+
coord[ACCESS_COORDINATE_CPU] =
150+
target->coord[NODE_ACCESS_CLASS_GENPORT_SINK_CPU];
147151

148152
return 0;
149153
}
@@ -325,6 +329,35 @@ static void hmat_update_target_access(struct memory_target *target,
325329
}
326330
}
327331

332+
int hmat_update_target_coordinates(int nid, struct access_coordinate *coord,
333+
enum access_coordinate_class access)
334+
{
335+
struct memory_target *target;
336+
int pxm;
337+
338+
if (nid == NUMA_NO_NODE)
339+
return -EINVAL;
340+
341+
pxm = node_to_pxm(nid);
342+
guard(mutex)(&target_lock);
343+
target = find_mem_target(pxm);
344+
if (!target)
345+
return -ENODEV;
346+
347+
hmat_update_target_access(target, ACPI_HMAT_READ_LATENCY,
348+
coord->read_latency, access);
349+
hmat_update_target_access(target, ACPI_HMAT_WRITE_LATENCY,
350+
coord->write_latency, access);
351+
hmat_update_target_access(target, ACPI_HMAT_READ_BANDWIDTH,
352+
coord->read_bandwidth, access);
353+
hmat_update_target_access(target, ACPI_HMAT_WRITE_BANDWIDTH,
354+
coord->write_bandwidth, access);
355+
target->ext_updated = true;
356+
357+
return 0;
358+
}
359+
EXPORT_SYMBOL_GPL(hmat_update_target_coordinates);
360+
328361
static __init void hmat_add_locality(struct acpi_hmat_locality *hmat_loc)
329362
{
330363
struct memory_locality *loc;
@@ -374,11 +407,11 @@ static __init void hmat_update_target(unsigned int tgt_pxm, unsigned int init_px
374407

375408
if (target && target->processor_pxm == init_pxm) {
376409
hmat_update_target_access(target, type, value,
377-
NODE_ACCESS_CLASS_0);
410+
ACCESS_COORDINATE_LOCAL);
378411
/* If the node has a CPU, update access 1 */
379412
if (node_state(pxm_to_node(init_pxm), N_CPU))
380413
hmat_update_target_access(target, type, value,
381-
NODE_ACCESS_CLASS_1);
414+
ACCESS_COORDINATE_CPU);
382415
}
383416
}
384417

@@ -696,8 +729,13 @@ static void hmat_update_target_attrs(struct memory_target *target,
696729
u32 best = 0;
697730
int i;
698731

732+
/* Don't update if an external agent has changed the data. */
733+
if (target->ext_updated)
734+
return;
735+
699736
/* Don't update for generic port if there's no device handle */
700-
if (access == NODE_ACCESS_CLASS_GENPORT_SINK &&
737+
if ((access == NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL ||
738+
access == NODE_ACCESS_CLASS_GENPORT_SINK_CPU) &&
701739
!(*(u16 *)target->gen_port_device_handle))
702740
return;
703741

@@ -709,7 +747,8 @@ static void hmat_update_target_attrs(struct memory_target *target,
709747
*/
710748
if (target->processor_pxm != PXM_INVAL) {
711749
cpu_nid = pxm_to_node(target->processor_pxm);
712-
if (access == 0 || node_state(cpu_nid, N_CPU)) {
750+
if (access == ACCESS_COORDINATE_LOCAL ||
751+
node_state(cpu_nid, N_CPU)) {
713752
set_bit(target->processor_pxm, p_nodes);
714753
return;
715754
}
@@ -737,7 +776,9 @@ static void hmat_update_target_attrs(struct memory_target *target,
737776
list_for_each_entry(initiator, &initiators, node) {
738777
u32 value;
739778

740-
if (access == 1 && !initiator->has_cpu) {
779+
if ((access == ACCESS_COORDINATE_CPU ||
780+
access == NODE_ACCESS_CLASS_GENPORT_SINK_CPU) &&
781+
!initiator->has_cpu) {
741782
clear_bit(initiator->processor_pxm, p_nodes);
742783
continue;
743784
}
@@ -770,20 +811,24 @@ static void __hmat_register_target_initiators(struct memory_target *target,
770811
}
771812
}
772813

773-
static void hmat_register_generic_target_initiators(struct memory_target *target)
814+
static void hmat_update_generic_target(struct memory_target *target)
774815
{
775816
static DECLARE_BITMAP(p_nodes, MAX_NUMNODES);
776817

777-
__hmat_register_target_initiators(target, p_nodes,
778-
NODE_ACCESS_CLASS_GENPORT_SINK);
818+
hmat_update_target_attrs(target, p_nodes,
819+
NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL);
820+
hmat_update_target_attrs(target, p_nodes,
821+
NODE_ACCESS_CLASS_GENPORT_SINK_CPU);
779822
}
780823

781824
static void hmat_register_target_initiators(struct memory_target *target)
782825
{
783826
static DECLARE_BITMAP(p_nodes, MAX_NUMNODES);
784827

785-
__hmat_register_target_initiators(target, p_nodes, 0);
786-
__hmat_register_target_initiators(target, p_nodes, 1);
828+
__hmat_register_target_initiators(target, p_nodes,
829+
ACCESS_COORDINATE_LOCAL);
830+
__hmat_register_target_initiators(target, p_nodes,
831+
ACCESS_COORDINATE_CPU);
787832
}
788833

789834
static void hmat_register_target_cache(struct memory_target *target)
@@ -835,7 +880,7 @@ static void hmat_register_target(struct memory_target *target)
835880
*/
836881
mutex_lock(&target_lock);
837882
if (*(u16 *)target->gen_port_device_handle) {
838-
hmat_register_generic_target_initiators(target);
883+
hmat_update_generic_target(target);
839884
target->registered = true;
840885
}
841886
mutex_unlock(&target_lock);
@@ -854,8 +899,8 @@ static void hmat_register_target(struct memory_target *target)
854899
if (!target->registered) {
855900
hmat_register_target_initiators(target);
856901
hmat_register_target_cache(target);
857-
hmat_register_target_perf(target, NODE_ACCESS_CLASS_0);
858-
hmat_register_target_perf(target, NODE_ACCESS_CLASS_1);
902+
hmat_register_target_perf(target, ACCESS_COORDINATE_LOCAL);
903+
hmat_register_target_perf(target, ACCESS_COORDINATE_CPU);
859904
target->registered = true;
860905
}
861906
mutex_unlock(&target_lock);
@@ -927,7 +972,7 @@ static int hmat_calculate_adistance(struct notifier_block *self,
927972
return NOTIFY_OK;
928973

929974
mutex_lock(&target_lock);
930-
hmat_update_target_attrs(target, p_nodes, 1);
975+
hmat_update_target_attrs(target, p_nodes, ACCESS_COORDINATE_CPU);
931976
mutex_unlock(&target_lock);
932977

933978
perf = &target->coord[1];

drivers/acpi/numa/srat.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ static int node_to_pxm_map[MAX_NUMNODES]
2929
unsigned char acpi_srat_revision __initdata;
3030
static int acpi_numa __initdata;
3131

32+
static int last_real_pxm;
33+
3234
void __init disable_srat(void)
3335
{
3436
acpi_numa = -1;
@@ -536,6 +538,7 @@ int __init acpi_numa_init(void)
536538
if (node_to_pxm_map[i] > fake_pxm)
537539
fake_pxm = node_to_pxm_map[i];
538540
}
541+
last_real_pxm = fake_pxm;
539542
fake_pxm++;
540543
acpi_table_parse_cedt(ACPI_CEDT_TYPE_CFMWS, acpi_parse_cfmws,
541544
&fake_pxm);
@@ -547,6 +550,14 @@ int __init acpi_numa_init(void)
547550
return 0;
548551
}
549552

553+
bool acpi_node_backed_by_real_pxm(int nid)
554+
{
555+
int pxm = node_to_pxm(nid);
556+
557+
return pxm <= last_real_pxm;
558+
}
559+
EXPORT_SYMBOL_GPL(acpi_node_backed_by_real_pxm);
560+
550561
static int acpi_get_pxm(acpi_handle h)
551562
{
552563
unsigned long long pxm;

drivers/base/node.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ static void node_access_release(struct device *dev)
126126
}
127127

128128
static struct node_access_nodes *node_init_node_access(struct node *node,
129-
unsigned int access)
129+
enum access_coordinate_class access)
130130
{
131131
struct node_access_nodes *access_node;
132132
struct device *dev;
@@ -191,7 +191,7 @@ static struct attribute *access_attrs[] = {
191191
* @access: The access class the for the given attributes
192192
*/
193193
void node_set_perf_attrs(unsigned int nid, struct access_coordinate *coord,
194-
unsigned int access)
194+
enum access_coordinate_class access)
195195
{
196196
struct node_access_nodes *c;
197197
struct node *node;
@@ -215,6 +215,7 @@ void node_set_perf_attrs(unsigned int nid, struct access_coordinate *coord,
215215
}
216216
}
217217
}
218+
EXPORT_SYMBOL_GPL(node_set_perf_attrs);
218219

219220
/**
220221
* struct node_cache_info - Internal tracking for memory node caches
@@ -689,7 +690,7 @@ int register_cpu_under_node(unsigned int cpu, unsigned int nid)
689690
*/
690691
int register_memory_node_under_compute_node(unsigned int mem_nid,
691692
unsigned int cpu_nid,
692-
unsigned int access)
693+
enum access_coordinate_class access)
693694
{
694695
struct node *init_node, *targ_node;
695696
struct node_access_nodes *initiator, *target;

drivers/cxl/acpi.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -530,13 +530,15 @@ static int get_genport_coordinates(struct device *dev, struct cxl_dport *dport)
530530
if (kstrtou32(acpi_device_uid(hb), 0, &uid))
531531
return -EINVAL;
532532

533-
rc = acpi_get_genport_coordinates(uid, &dport->hb_coord);
533+
rc = acpi_get_genport_coordinates(uid, dport->hb_coord);
534534
if (rc < 0)
535535
return rc;
536536

537537
/* Adjust back to picoseconds from nanoseconds */
538-
dport->hb_coord.read_latency *= 1000;
539-
dport->hb_coord.write_latency *= 1000;
538+
for (int i = 0; i < ACCESS_COORDINATE_MAX; i++) {
539+
dport->hb_coord[i].read_latency *= 1000;
540+
dport->hb_coord[i].write_latency *= 1000;
541+
}
540542

541543
return 0;
542544
}

0 commit comments

Comments
 (0)