Skip to content

Commit e4174ff

Browse files
committed
Merge branch 'acpi-numa'
* acpi-numa: docs: mm: numaperf.rst Add brief description for access class 1. node: Add access1 class to represent CPU to memory characteristics ACPI: HMAT: Fix handling of changes from ACPI 6.2 to ACPI 6.3 ACPI: Let ACPI know we support Generic Initiator Affinity Structures x86: Support Generic Initiator only proximity domains ACPI: Support Generic Initiator only domains ACPI / NUMA: Add stub function for pxm_to_node() irq-chip/gic-v3-its: Fix crash if ITS is in a proximity domain without processor or memory ACPI: Remove side effect of partly creating a node in acpi_get_node() ACPI: Rename acpi_map_pxm_to_online_node() to pxm_to_online_node() ACPI: Remove side effect of partly creating a node in acpi_map_pxm_to_online_node() ACPI: Do not create new NUMA domains from ACPI static tables that are not SRAT ACPI: Add out of bounds and numa_off protections to pxm_to_node()
2 parents 20eeeaf + dc9e786 commit e4174ff

15 files changed

Lines changed: 206 additions & 40 deletions

File tree

Documentation/admin-guide/mm/numaperf.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ nodes' access characteristics share the same performance relative to other
5656
linked initiator nodes. Each target within an initiator's access class,
5757
though, do not necessarily perform the same as each other.
5858

59+
The access class "1" is used to allow differentiation between initiators
60+
that are CPUs and hence suitable for generic task scheduling, and
61+
IO initiators such as GPUs and NICs. Unlike access class 0, only
62+
nodes containing CPUs are considered.
63+
5964
================
6065
NUMA Performance
6166
================
@@ -88,6 +93,9 @@ The latency attributes are provided in nanoseconds.
8893
The values reported here correspond to the rated latency and bandwidth
8994
for the platform.
9095

96+
Access class 1 takes the same form but only includes values for CPU to
97+
memory activity.
98+
9199
==========
92100
NUMA Cache
93101
==========

arch/x86/include/asm/numa.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,14 @@ extern void numa_clear_node(int cpu);
6262
extern void __init init_cpu_to_node(void);
6363
extern void numa_add_cpu(int cpu);
6464
extern void numa_remove_cpu(int cpu);
65+
extern void init_gi_nodes(void);
6566
#else /* CONFIG_NUMA */
6667
static inline void numa_set_node(int cpu, int node) { }
6768
static inline void numa_clear_node(int cpu) { }
6869
static inline void init_cpu_to_node(void) { }
6970
static inline void numa_add_cpu(int cpu) { }
7071
static inline void numa_remove_cpu(int cpu) { }
72+
static inline void init_gi_nodes(void) { }
7173
#endif /* CONFIG_NUMA */
7274

7375
#ifdef CONFIG_DEBUG_PER_CPU_MAPS

arch/x86/kernel/setup.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,7 @@ void __init setup_arch(char **cmdline_p)
12181218
prefill_possible_map();
12191219

12201220
init_cpu_to_node();
1221+
init_gi_nodes();
12211222

12221223
io_apic_init_mappings();
12231224

arch/x86/mm/numa.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,27 @@ static void __init init_memory_less_node(int nid)
747747
*/
748748
}
749749

750+
/*
751+
* A node may exist which has one or more Generic Initiators but no CPUs and no
752+
* memory.
753+
*
754+
* This function must be called after init_cpu_to_node(), to ensure that any
755+
* memoryless CPU nodes have already been brought online, and before the
756+
* node_data[nid] is needed for zone list setup in build_all_zonelists().
757+
*
758+
* When this function is called, any nodes containing either memory and/or CPUs
759+
* will already be online and there is no need to do anything extra, even if
760+
* they also contain one or more Generic Initiators.
761+
*/
762+
void __init init_gi_nodes(void)
763+
{
764+
int nid;
765+
766+
for_each_node_state(nid, N_GENERIC_INITIATOR)
767+
if (!node_online(nid))
768+
init_memory_less_node(nid);
769+
}
770+
750771
/*
751772
* Setup early cpu_to_node.
752773
*

drivers/acpi/arm64/iort.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1335,7 +1335,7 @@ static int __init arm_smmu_v3_set_proximity(struct device *dev,
13351335

13361336
smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
13371337
if (smmu->flags & ACPI_IORT_SMMU_V3_PXM_VALID) {
1338-
int dev_node = acpi_map_pxm_to_node(smmu->pxm);
1338+
int dev_node = pxm_to_node(smmu->pxm);
13391339

13401340
if (dev_node != NUMA_NO_NODE && !node_online(dev_node))
13411341
return -EINVAL;

drivers/acpi/bus.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,11 @@ static void acpi_bus_osc_support(void)
303303
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_OST_SUPPORT;
304304
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT;
305305

306+
#ifdef CONFIG_ARM64
307+
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT;
308+
#endif
306309
#ifdef CONFIG_X86
310+
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GENERIC_INITIATOR_SUPPORT;
307311
if (boot_cpu_has(X86_FEATURE_HWP)) {
308312
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT;
309313
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT;

drivers/acpi/nfit/core.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3006,10 +3006,8 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
30063006
ndr_desc->provider_data = nfit_spa;
30073007
ndr_desc->attr_groups = acpi_nfit_region_attribute_groups;
30083008
if (spa->flags & ACPI_NFIT_PROXIMITY_VALID) {
3009-
ndr_desc->numa_node = acpi_map_pxm_to_online_node(
3010-
spa->proximity_domain);
3011-
ndr_desc->target_node = acpi_map_pxm_to_node(
3012-
spa->proximity_domain);
3009+
ndr_desc->numa_node = pxm_to_online_node(spa->proximity_domain);
3010+
ndr_desc->target_node = pxm_to_node(spa->proximity_domain);
30133011
} else {
30143012
ndr_desc->numa_node = NUMA_NO_NODE;
30153013
ndr_desc->target_node = NUMA_NO_NODE;

drivers/acpi/numa/hmat.c

Lines changed: 73 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ struct memory_target {
5656
unsigned int memory_pxm;
5757
unsigned int processor_pxm;
5858
struct resource memregions;
59-
struct node_hmem_attrs hmem_attrs;
59+
struct node_hmem_attrs hmem_attrs[2];
6060
struct list_head caches;
6161
struct node_cache_attrs cache_attrs;
6262
bool registered;
@@ -65,6 +65,7 @@ struct memory_target {
6565
struct memory_initiator {
6666
struct list_head node;
6767
unsigned int processor_pxm;
68+
bool has_cpu;
6869
};
6970

7071
struct memory_locality {
@@ -108,6 +109,7 @@ static __init void alloc_memory_initiator(unsigned int cpu_pxm)
108109
return;
109110

110111
initiator->processor_pxm = cpu_pxm;
112+
initiator->has_cpu = node_state(pxm_to_node(cpu_pxm), N_CPU);
111113
list_add_tail(&initiator->node, &initiators);
112114
}
113115

@@ -215,28 +217,28 @@ static u32 hmat_normalize(u16 entry, u64 base, u8 type)
215217
}
216218

217219
static void hmat_update_target_access(struct memory_target *target,
218-
u8 type, u32 value)
220+
u8 type, u32 value, int access)
219221
{
220222
switch (type) {
221223
case ACPI_HMAT_ACCESS_LATENCY:
222-
target->hmem_attrs.read_latency = value;
223-
target->hmem_attrs.write_latency = value;
224+
target->hmem_attrs[access].read_latency = value;
225+
target->hmem_attrs[access].write_latency = value;
224226
break;
225227
case ACPI_HMAT_READ_LATENCY:
226-
target->hmem_attrs.read_latency = value;
228+
target->hmem_attrs[access].read_latency = value;
227229
break;
228230
case ACPI_HMAT_WRITE_LATENCY:
229-
target->hmem_attrs.write_latency = value;
231+
target->hmem_attrs[access].write_latency = value;
230232
break;
231233
case ACPI_HMAT_ACCESS_BANDWIDTH:
232-
target->hmem_attrs.read_bandwidth = value;
233-
target->hmem_attrs.write_bandwidth = value;
234+
target->hmem_attrs[access].read_bandwidth = value;
235+
target->hmem_attrs[access].write_bandwidth = value;
234236
break;
235237
case ACPI_HMAT_READ_BANDWIDTH:
236-
target->hmem_attrs.read_bandwidth = value;
238+
target->hmem_attrs[access].read_bandwidth = value;
237239
break;
238240
case ACPI_HMAT_WRITE_BANDWIDTH:
239-
target->hmem_attrs.write_bandwidth = value;
241+
target->hmem_attrs[access].write_bandwidth = value;
240242
break;
241243
default:
242244
break;
@@ -329,8 +331,12 @@ static __init int hmat_parse_locality(union acpi_subtable_headers *header,
329331

330332
if (mem_hier == ACPI_HMAT_MEMORY) {
331333
target = find_mem_target(targs[targ]);
332-
if (target && target->processor_pxm == inits[init])
333-
hmat_update_target_access(target, type, value);
334+
if (target && target->processor_pxm == inits[init]) {
335+
hmat_update_target_access(target, type, value, 0);
336+
/* If the node has a CPU, update access 1 */
337+
if (node_state(pxm_to_node(inits[init]), N_CPU))
338+
hmat_update_target_access(target, type, value, 1);
339+
}
334340
}
335341
}
336342
}
@@ -424,7 +430,8 @@ static int __init hmat_parse_proximity_domain(union acpi_subtable_headers *heade
424430
pr_info("HMAT: Memory Flags:%04x Processor Domain:%u Memory Domain:%u\n",
425431
p->flags, p->processor_PD, p->memory_PD);
426432

427-
if (p->flags & ACPI_HMAT_MEMORY_PD_VALID && hmat_revision == 1) {
433+
if ((hmat_revision == 1 && p->flags & ACPI_HMAT_MEMORY_PD_VALID) ||
434+
hmat_revision > 1) {
428435
target = find_mem_target(p->memory_PD);
429436
if (!target) {
430437
pr_debug("HMAT: Memory Domain missing from SRAT\n");
@@ -566,6 +573,7 @@ static void hmat_register_target_initiators(struct memory_target *target)
566573
unsigned int mem_nid, cpu_nid;
567574
struct memory_locality *loc = NULL;
568575
u32 best = 0;
576+
bool access0done = false;
569577
int i;
570578

571579
mem_nid = pxm_to_node(target->memory_pxm);
@@ -577,7 +585,11 @@ static void hmat_register_target_initiators(struct memory_target *target)
577585
if (target->processor_pxm != PXM_INVAL) {
578586
cpu_nid = pxm_to_node(target->processor_pxm);
579587
register_memory_node_under_compute_node(mem_nid, cpu_nid, 0);
580-
return;
588+
access0done = true;
589+
if (node_state(cpu_nid, N_CPU)) {
590+
register_memory_node_under_compute_node(mem_nid, cpu_nid, 1);
591+
return;
592+
}
581593
}
582594

583595
if (list_empty(&localities))
@@ -591,6 +603,41 @@ static void hmat_register_target_initiators(struct memory_target *target)
591603
*/
592604
bitmap_zero(p_nodes, MAX_NUMNODES);
593605
list_sort(p_nodes, &initiators, initiator_cmp);
606+
if (!access0done) {
607+
for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) {
608+
loc = localities_types[i];
609+
if (!loc)
610+
continue;
611+
612+
best = 0;
613+
list_for_each_entry(initiator, &initiators, node) {
614+
u32 value;
615+
616+
if (!test_bit(initiator->processor_pxm, p_nodes))
617+
continue;
618+
619+
value = hmat_initiator_perf(target, initiator,
620+
loc->hmat_loc);
621+
if (hmat_update_best(loc->hmat_loc->data_type, value, &best))
622+
bitmap_clear(p_nodes, 0, initiator->processor_pxm);
623+
if (value != best)
624+
clear_bit(initiator->processor_pxm, p_nodes);
625+
}
626+
if (best)
627+
hmat_update_target_access(target, loc->hmat_loc->data_type,
628+
best, 0);
629+
}
630+
631+
for_each_set_bit(i, p_nodes, MAX_NUMNODES) {
632+
cpu_nid = pxm_to_node(i);
633+
register_memory_node_under_compute_node(mem_nid, cpu_nid, 0);
634+
}
635+
}
636+
637+
/* Access 1 ignores Generic Initiators */
638+
bitmap_zero(p_nodes, MAX_NUMNODES);
639+
list_sort(p_nodes, &initiators, initiator_cmp);
640+
best = 0;
594641
for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) {
595642
loc = localities_types[i];
596643
if (!loc)
@@ -600,6 +647,10 @@ static void hmat_register_target_initiators(struct memory_target *target)
600647
list_for_each_entry(initiator, &initiators, node) {
601648
u32 value;
602649

650+
if (!initiator->has_cpu) {
651+
clear_bit(initiator->processor_pxm, p_nodes);
652+
continue;
653+
}
603654
if (!test_bit(initiator->processor_pxm, p_nodes))
604655
continue;
605656

@@ -610,12 +661,11 @@ static void hmat_register_target_initiators(struct memory_target *target)
610661
clear_bit(initiator->processor_pxm, p_nodes);
611662
}
612663
if (best)
613-
hmat_update_target_access(target, loc->hmat_loc->data_type, best);
664+
hmat_update_target_access(target, loc->hmat_loc->data_type, best, 1);
614665
}
615-
616666
for_each_set_bit(i, p_nodes, MAX_NUMNODES) {
617667
cpu_nid = pxm_to_node(i);
618-
register_memory_node_under_compute_node(mem_nid, cpu_nid, 0);
668+
register_memory_node_under_compute_node(mem_nid, cpu_nid, 1);
619669
}
620670
}
621671

@@ -628,10 +678,10 @@ static void hmat_register_target_cache(struct memory_target *target)
628678
node_add_cache(mem_nid, &tcache->cache_attrs);
629679
}
630680

631-
static void hmat_register_target_perf(struct memory_target *target)
681+
static void hmat_register_target_perf(struct memory_target *target, int access)
632682
{
633683
unsigned mem_nid = pxm_to_node(target->memory_pxm);
634-
node_set_perf_attrs(mem_nid, &target->hmem_attrs, 0);
684+
node_set_perf_attrs(mem_nid, &target->hmem_attrs[access], access);
635685
}
636686

637687
static void hmat_register_target_device(struct memory_target *target,
@@ -664,9 +714,9 @@ static void hmat_register_target_device(struct memory_target *target,
664714
goto out_pdev;
665715
}
666716

667-
pdev->dev.numa_node = acpi_map_pxm_to_online_node(target->memory_pxm);
717+
pdev->dev.numa_node = pxm_to_online_node(target->memory_pxm);
668718
info = (struct memregion_info) {
669-
.target_node = acpi_map_pxm_to_node(target->memory_pxm),
719+
.target_node = pxm_to_node(target->memory_pxm),
670720
};
671721
rc = platform_device_add_data(pdev, &info, sizeof(info));
672722
if (rc < 0) {
@@ -733,7 +783,8 @@ static void hmat_register_target(struct memory_target *target)
733783
if (!target->registered) {
734784
hmat_register_target_initiators(target);
735785
hmat_register_target_cache(target);
736-
hmat_register_target_perf(target);
786+
hmat_register_target_perf(target, 0);
787+
hmat_register_target_perf(target, 1);
737788
target->registered = true;
738789
}
739790
mutex_unlock(&target_lock);

0 commit comments

Comments
 (0)