Skip to content

Commit b9fffe4

Browse files
jic23rafaeljw
authored andcommitted
node: Add access1 class to represent CPU to memory characteristics
New access1 class is nearly the same as access0, but always provides characteristics for CPUs to memory. The existing access0 class provides characteristics to nearest or direct connnect initiator which may be a Generic Initiator such as a GPU or network adapter. This new class allows thread placement on CPUs to be performed so as to give optimal access characteristics to memory, even if that memory is for example attached to a GPU or similar and only accessible to the CPU via an appropriate bus. Suggested-by: Dan Willaims <dan.j.williams@intel.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 2c5b9bd commit b9fffe4

1 file changed

Lines changed: 69 additions & 19 deletions

File tree

drivers/acpi/numa/hmat.c

Lines changed: 69 additions & 19 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
}
@@ -567,6 +573,7 @@ static void hmat_register_target_initiators(struct memory_target *target)
567573
unsigned int mem_nid, cpu_nid;
568574
struct memory_locality *loc = NULL;
569575
u32 best = 0;
576+
bool access0done = false;
570577
int i;
571578

572579
mem_nid = pxm_to_node(target->memory_pxm);
@@ -578,7 +585,11 @@ static void hmat_register_target_initiators(struct memory_target *target)
578585
if (target->processor_pxm != PXM_INVAL) {
579586
cpu_nid = pxm_to_node(target->processor_pxm);
580587
register_memory_node_under_compute_node(mem_nid, cpu_nid, 0);
581-
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+
}
582593
}
583594

584595
if (list_empty(&localities))
@@ -592,6 +603,41 @@ static void hmat_register_target_initiators(struct memory_target *target)
592603
*/
593604
bitmap_zero(p_nodes, MAX_NUMNODES);
594605
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;
595641
for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) {
596642
loc = localities_types[i];
597643
if (!loc)
@@ -601,6 +647,10 @@ static void hmat_register_target_initiators(struct memory_target *target)
601647
list_for_each_entry(initiator, &initiators, node) {
602648
u32 value;
603649

650+
if (!initiator->has_cpu) {
651+
clear_bit(initiator->processor_pxm, p_nodes);
652+
continue;
653+
}
604654
if (!test_bit(initiator->processor_pxm, p_nodes))
605655
continue;
606656

@@ -611,12 +661,11 @@ static void hmat_register_target_initiators(struct memory_target *target)
611661
clear_bit(initiator->processor_pxm, p_nodes);
612662
}
613663
if (best)
614-
hmat_update_target_access(target, loc->hmat_loc->data_type, best);
664+
hmat_update_target_access(target, loc->hmat_loc->data_type, best, 1);
615665
}
616-
617666
for_each_set_bit(i, p_nodes, MAX_NUMNODES) {
618667
cpu_nid = pxm_to_node(i);
619-
register_memory_node_under_compute_node(mem_nid, cpu_nid, 0);
668+
register_memory_node_under_compute_node(mem_nid, cpu_nid, 1);
620669
}
621670
}
622671

@@ -629,10 +678,10 @@ static void hmat_register_target_cache(struct memory_target *target)
629678
node_add_cache(mem_nid, &tcache->cache_attrs);
630679
}
631680

632-
static void hmat_register_target_perf(struct memory_target *target)
681+
static void hmat_register_target_perf(struct memory_target *target, int access)
633682
{
634683
unsigned mem_nid = pxm_to_node(target->memory_pxm);
635-
node_set_perf_attrs(mem_nid, &target->hmem_attrs, 0);
684+
node_set_perf_attrs(mem_nid, &target->hmem_attrs[access], access);
636685
}
637686

638687
static void hmat_register_target_device(struct memory_target *target,
@@ -734,7 +783,8 @@ static void hmat_register_target(struct memory_target *target)
734783
if (!target->registered) {
735784
hmat_register_target_initiators(target);
736785
hmat_register_target_cache(target);
737-
hmat_register_target_perf(target);
786+
hmat_register_target_perf(target, 0);
787+
hmat_register_target_perf(target, 1);
738788
target->registered = true;
739789
}
740790
mutex_unlock(&target_lock);

0 commit comments

Comments
 (0)