Skip to content

Commit 894c26a

Browse files
jic23rafaeljw
authored andcommitted
ACPI: Support Generic Initiator only domains
Generic Initiators are a new ACPI concept that allows for the description of proximity domains that contain a device which performs memory access (such as a network card) but neither host CPU nor Memory. This patch has the parsing code and provides the infrastructure for an architecture to associate these new domains with their nearest memory processing node. Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 4849bc7 commit 894c26a

File tree

3 files changed

+72
-1
lines changed

3 files changed

+72
-1
lines changed

drivers/acpi/numa/srat.c

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,36 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
130130
}
131131
break;
132132

133+
case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
134+
{
135+
struct acpi_srat_generic_affinity *p =
136+
(struct acpi_srat_generic_affinity *)header;
137+
138+
if (p->device_handle_type == 0) {
139+
/*
140+
* For pci devices this may be the only place they
141+
* are assigned a proximity domain
142+
*/
143+
pr_debug("SRAT Generic Initiator(Seg:%u BDF:%u) in proximity domain %d %s\n",
144+
*(u16 *)(&p->device_handle[0]),
145+
*(u16 *)(&p->device_handle[2]),
146+
p->proximity_domain,
147+
(p->flags & ACPI_SRAT_GENERIC_AFFINITY_ENABLED) ?
148+
"enabled" : "disabled");
149+
} else {
150+
/*
151+
* In this case we can rely on the device having a
152+
* proximity domain reference
153+
*/
154+
pr_debug("SRAT Generic Initiator(HID=%.8s UID=%.4s) in proximity domain %d %s\n",
155+
(char *)(&p->device_handle[0]),
156+
(char *)(&p->device_handle[8]),
157+
p->proximity_domain,
158+
(p->flags & ACPI_SRAT_GENERIC_AFFINITY_ENABLED) ?
159+
"enabled" : "disabled");
160+
}
161+
}
162+
break;
133163
default:
134164
pr_warn("Found unsupported SRAT entry (type = 0x%x)\n",
135165
header->type);
@@ -332,6 +362,41 @@ acpi_parse_gicc_affinity(union acpi_subtable_headers *header,
332362
return 0;
333363
}
334364

365+
#if defined(CONFIG_X86) || defined(CONFIG_ARM64)
366+
static int __init
367+
acpi_parse_gi_affinity(union acpi_subtable_headers *header,
368+
const unsigned long end)
369+
{
370+
struct acpi_srat_generic_affinity *gi_affinity;
371+
int node;
372+
373+
gi_affinity = (struct acpi_srat_generic_affinity *)header;
374+
if (!gi_affinity)
375+
return -EINVAL;
376+
acpi_table_print_srat_entry(&header->common);
377+
378+
if (!(gi_affinity->flags & ACPI_SRAT_GENERIC_AFFINITY_ENABLED))
379+
return -EINVAL;
380+
381+
node = acpi_map_pxm_to_node(gi_affinity->proximity_domain);
382+
if (node == NUMA_NO_NODE || node >= MAX_NUMNODES) {
383+
pr_err("SRAT: Too many proximity domains.\n");
384+
return -EINVAL;
385+
}
386+
node_set(node, numa_nodes_parsed);
387+
node_set_state(node, N_GENERIC_INITIATOR);
388+
389+
return 0;
390+
}
391+
#else
392+
static int __init
393+
acpi_parse_gi_affinity(union acpi_subtable_headers *header,
394+
const unsigned long end)
395+
{
396+
return 0;
397+
}
398+
#endif /* defined(CONFIG_X86) || defined (CONFIG_ARM64) */
399+
335400
static int __initdata parsed_numa_memblks;
336401

337402
static int __init
@@ -385,7 +450,7 @@ int __init acpi_numa_init(void)
385450

386451
/* SRAT: System Resource Affinity Table */
387452
if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
388-
struct acpi_subtable_proc srat_proc[3];
453+
struct acpi_subtable_proc srat_proc[4];
389454

390455
memset(srat_proc, 0, sizeof(srat_proc));
391456
srat_proc[0].id = ACPI_SRAT_TYPE_CPU_AFFINITY;
@@ -394,6 +459,8 @@ int __init acpi_numa_init(void)
394459
srat_proc[1].handler = acpi_parse_x2apic_affinity;
395460
srat_proc[2].id = ACPI_SRAT_TYPE_GICC_AFFINITY;
396461
srat_proc[2].handler = acpi_parse_gicc_affinity;
462+
srat_proc[3].id = ACPI_SRAT_TYPE_GENERIC_AFFINITY;
463+
srat_proc[3].handler = acpi_parse_gi_affinity;
397464

398465
acpi_table_parse_entries_array(ACPI_SIG_SRAT,
399466
sizeof(struct acpi_table_srat),

drivers/base/node.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,8 @@ static struct node_attr node_state_attr[] = {
980980
#endif
981981
[N_MEMORY] = _NODE_ATTR(has_memory, N_MEMORY),
982982
[N_CPU] = _NODE_ATTR(has_cpu, N_CPU),
983+
[N_GENERIC_INITIATOR] = _NODE_ATTR(has_generic_initiator,
984+
N_GENERIC_INITIATOR),
983985
};
984986

985987
static struct attribute *node_state_attrs[] = {
@@ -991,6 +993,7 @@ static struct attribute *node_state_attrs[] = {
991993
#endif
992994
&node_state_attr[N_MEMORY].attr.attr,
993995
&node_state_attr[N_CPU].attr.attr,
996+
&node_state_attr[N_GENERIC_INITIATOR].attr.attr,
994997
NULL
995998
};
996999

include/linux/nodemask.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ enum node_states {
399399
#endif
400400
N_MEMORY, /* The node has memory(regular, high, movable) */
401401
N_CPU, /* The node has one or more cpus */
402+
N_GENERIC_INITIATOR, /* The node has one or more Generic Initiators */
402403
NR_NODE_STATES
403404
};
404405

0 commit comments

Comments
 (0)