Skip to content

Commit 362f533

Browse files
committed
Merge tag 'cxl-for-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl
Pull CXL (Compute Express Link) updates from Dan Williams: "The highlight is initial support for CXL memory hotplug. The static NUMA node (ACPI SRAT Physical Address to Proximity Domain) information known to platform firmware is extended to support the potential performance-class / memory-target nodes dynamically created from available CXL memory device capacity. New unit test infrastructure is added for validating health information payloads. Fixes to module reload stress and stack usage from exposure in -next are included. A symbol rename and some other miscellaneous fixups are included as well. Summary: - Rework ACPI sub-table infrastructure to optionally be used outside of __init scenarios and use it for CEDT.CFMWS sub-table parsing. - Add support for extending num_possible_nodes by the potential hotplug CXL memory ranges - Extend tools/testing/cxl with mock memory device health information - Fix a module-reload workqueue race - Fix excessive stack-frame usage - Rename the driver context data structure from "cxl_mem" since that name collides with a proposed driver name - Use EXPORT_SYMBOL_NS_GPL instead of -DDEFAULT_SYMBOL_NAMESPACE at build time" * tag 'cxl-for-5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl: cxl/core: Remove cxld_const_init in cxl_decoder_alloc() cxl/pmem: Fix module reload vs workqueue state ACPI: NUMA: Add a node and memblk for each CFMWS not in SRAT cxl/test: Mock acpi_table_parse_cedt() cxl/acpi: Convert CFMWS parsing to ACPI sub-table helpers ACPI: Add a context argument for table parsing handlers ACPI: Teach ACPI table parsing about the CEDT header format ACPI: Keep sub-table parsing infrastructure available for modules tools/testing/cxl: add mock output for the GET_HEALTH_INFO command cxl/memdev: Remove unused cxlmd field cxl/core: Convert to EXPORT_SYMBOL_NS_GPL cxl/memdev: Change cxl_mem to a more descriptive name cxl/mbox: Remove bad comment cxl/pmem: Fix reference counting for delayed work
2 parents 3acbdbf + be185c2 commit 362f533

File tree

21 files changed

+675
-501
lines changed

21 files changed

+675
-501
lines changed

drivers/acpi/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ config ACPI_SYSTEM_POWER_STATES_SUPPORT
5959
config ACPI_CCA_REQUIRED
6060
bool
6161

62+
config ACPI_TABLE_LIB
63+
bool
64+
6265
config ACPI_DEBUGGER
6366
bool "AML debugger interface"
6467
select ACPI_DEBUG

drivers/acpi/numa/srat.c

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,47 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
297297
out_err:
298298
return -EINVAL;
299299
}
300+
301+
static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
302+
void *arg, const unsigned long table_end)
303+
{
304+
struct acpi_cedt_cfmws *cfmws;
305+
int *fake_pxm = arg;
306+
u64 start, end;
307+
int node;
308+
309+
cfmws = (struct acpi_cedt_cfmws *)header;
310+
start = cfmws->base_hpa;
311+
end = cfmws->base_hpa + cfmws->window_size;
312+
313+
/* Skip if the SRAT already described the NUMA details for this HPA */
314+
node = phys_to_target_node(start);
315+
if (node != NUMA_NO_NODE)
316+
return 0;
317+
318+
node = acpi_map_pxm_to_node(*fake_pxm);
319+
320+
if (node == NUMA_NO_NODE) {
321+
pr_err("ACPI NUMA: Too many proximity domains while processing CFMWS.\n");
322+
return -EINVAL;
323+
}
324+
325+
if (numa_add_memblk(node, start, end) < 0) {
326+
/* CXL driver must handle the NUMA_NO_NODE case */
327+
pr_warn("ACPI NUMA: Failed to add memblk for CFMWS node %d [mem %#llx-%#llx]\n",
328+
node, start, end);
329+
}
330+
331+
/* Set the next available fake_pxm value */
332+
(*fake_pxm)++;
333+
return 0;
334+
}
335+
#else
336+
static int __init acpi_parse_cfmws(union acpi_subtable_headers *header,
337+
void *arg, const unsigned long table_end)
338+
{
339+
return 0;
340+
}
300341
#endif /* defined(CONFIG_X86) || defined (CONFIG_ARM64) */
301342

302343
static int __init acpi_parse_slit(struct acpi_table_header *table)
@@ -441,7 +482,7 @@ acpi_table_parse_srat(enum acpi_srat_type id,
441482

442483
int __init acpi_numa_init(void)
443484
{
444-
int cnt = 0;
485+
int i, fake_pxm, cnt = 0;
445486

446487
if (acpi_disabled)
447488
return -EINVAL;
@@ -477,6 +518,22 @@ int __init acpi_numa_init(void)
477518
/* SLIT: System Locality Information Table */
478519
acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
479520

521+
/*
522+
* CXL Fixed Memory Window Structures (CFMWS) must be parsed
523+
* after the SRAT. Create NUMA Nodes for CXL memory ranges that
524+
* are defined in the CFMWS and not already defined in the SRAT.
525+
* Initialize a fake_pxm as the first available PXM to emulate.
526+
*/
527+
528+
/* fake_pxm is the next unused PXM value after SRAT parsing */
529+
for (i = 0, fake_pxm = -1; i < MAX_NUMNODES - 1; i++) {
530+
if (node_to_pxm_map[i] > fake_pxm)
531+
fake_pxm = node_to_pxm_map[i];
532+
}
533+
fake_pxm++;
534+
acpi_table_parse_cedt(ACPI_CEDT_TYPE_CFMWS, acpi_parse_cfmws,
535+
&fake_pxm);
536+
480537
if (cnt < 0)
481538
return cnt;
482539
else if (!parsed_numa_memblks)

drivers/acpi/tables.c

Lines changed: 66 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,13 @@ static char *mps_inti_flags_trigger[] = { "dfl", "edge", "res", "level" };
3535

3636
static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata;
3737

38-
static int acpi_apic_instance __initdata;
38+
static int acpi_apic_instance __initdata_or_acpilib;
3939

4040
enum acpi_subtable_type {
4141
ACPI_SUBTABLE_COMMON,
4242
ACPI_SUBTABLE_HMAT,
4343
ACPI_SUBTABLE_PRMT,
44+
ACPI_SUBTABLE_CEDT,
4445
};
4546

4647
struct acpi_subtable_entry {
@@ -52,7 +53,7 @@ struct acpi_subtable_entry {
5253
* Disable table checksum verification for the early stage due to the size
5354
* limitation of the current x86 early mapping implementation.
5455
*/
55-
static bool acpi_verify_table_checksum __initdata = false;
56+
static bool acpi_verify_table_checksum __initdata_or_acpilib = false;
5657

5758
void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
5859
{
@@ -216,7 +217,7 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
216217
}
217218
}
218219

219-
static unsigned long __init
220+
static unsigned long __init_or_acpilib
220221
acpi_get_entry_type(struct acpi_subtable_entry *entry)
221222
{
222223
switch (entry->type) {
@@ -226,11 +227,13 @@ acpi_get_entry_type(struct acpi_subtable_entry *entry)
226227
return entry->hdr->hmat.type;
227228
case ACPI_SUBTABLE_PRMT:
228229
return 0;
230+
case ACPI_SUBTABLE_CEDT:
231+
return entry->hdr->cedt.type;
229232
}
230233
return 0;
231234
}
232235

233-
static unsigned long __init
236+
static unsigned long __init_or_acpilib
234237
acpi_get_entry_length(struct acpi_subtable_entry *entry)
235238
{
236239
switch (entry->type) {
@@ -240,11 +243,13 @@ acpi_get_entry_length(struct acpi_subtable_entry *entry)
240243
return entry->hdr->hmat.length;
241244
case ACPI_SUBTABLE_PRMT:
242245
return entry->hdr->prmt.length;
246+
case ACPI_SUBTABLE_CEDT:
247+
return entry->hdr->cedt.length;
243248
}
244249
return 0;
245250
}
246251

247-
static unsigned long __init
252+
static unsigned long __init_or_acpilib
248253
acpi_get_subtable_header_length(struct acpi_subtable_entry *entry)
249254
{
250255
switch (entry->type) {
@@ -254,20 +259,40 @@ acpi_get_subtable_header_length(struct acpi_subtable_entry *entry)
254259
return sizeof(entry->hdr->hmat);
255260
case ACPI_SUBTABLE_PRMT:
256261
return sizeof(entry->hdr->prmt);
262+
case ACPI_SUBTABLE_CEDT:
263+
return sizeof(entry->hdr->cedt);
257264
}
258265
return 0;
259266
}
260267

261-
static enum acpi_subtable_type __init
268+
static enum acpi_subtable_type __init_or_acpilib
262269
acpi_get_subtable_type(char *id)
263270
{
264271
if (strncmp(id, ACPI_SIG_HMAT, 4) == 0)
265272
return ACPI_SUBTABLE_HMAT;
266273
if (strncmp(id, ACPI_SIG_PRMT, 4) == 0)
267274
return ACPI_SUBTABLE_PRMT;
275+
if (strncmp(id, ACPI_SIG_CEDT, 4) == 0)
276+
return ACPI_SUBTABLE_CEDT;
268277
return ACPI_SUBTABLE_COMMON;
269278
}
270279

280+
static __init_or_acpilib bool has_handler(struct acpi_subtable_proc *proc)
281+
{
282+
return proc->handler || proc->handler_arg;
283+
}
284+
285+
static __init_or_acpilib int call_handler(struct acpi_subtable_proc *proc,
286+
union acpi_subtable_headers *hdr,
287+
unsigned long end)
288+
{
289+
if (proc->handler)
290+
return proc->handler(hdr, end);
291+
if (proc->handler_arg)
292+
return proc->handler_arg(hdr, proc->arg, end);
293+
return -EINVAL;
294+
}
295+
271296
/**
272297
* acpi_parse_entries_array - for each proc_num find a suitable subtable
273298
*
@@ -291,10 +316,10 @@ acpi_get_subtable_type(char *id)
291316
* On success returns sum of all matching entries for all proc handlers.
292317
* Otherwise, -ENODEV or -EINVAL is returned.
293318
*/
294-
static int __init acpi_parse_entries_array(char *id, unsigned long table_size,
295-
struct acpi_table_header *table_header,
296-
struct acpi_subtable_proc *proc, int proc_num,
297-
unsigned int max_entries)
319+
static int __init_or_acpilib acpi_parse_entries_array(
320+
char *id, unsigned long table_size,
321+
struct acpi_table_header *table_header, struct acpi_subtable_proc *proc,
322+
int proc_num, unsigned int max_entries)
298323
{
299324
struct acpi_subtable_entry entry;
300325
unsigned long table_end, subtable_len, entry_len;
@@ -318,8 +343,9 @@ static int __init acpi_parse_entries_array(char *id, unsigned long table_size,
318343
for (i = 0; i < proc_num; i++) {
319344
if (acpi_get_entry_type(&entry) != proc[i].id)
320345
continue;
321-
if (!proc[i].handler ||
322-
(!errs && proc[i].handler(entry.hdr, table_end))) {
346+
if (!has_handler(&proc[i]) ||
347+
(!errs &&
348+
call_handler(&proc[i], entry.hdr, table_end))) {
323349
errs++;
324350
continue;
325351
}
@@ -352,10 +378,9 @@ static int __init acpi_parse_entries_array(char *id, unsigned long table_size,
352378
return errs ? -EINVAL : count;
353379
}
354380

355-
int __init acpi_table_parse_entries_array(char *id,
356-
unsigned long table_size,
357-
struct acpi_subtable_proc *proc, int proc_num,
358-
unsigned int max_entries)
381+
int __init_or_acpilib acpi_table_parse_entries_array(
382+
char *id, unsigned long table_size, struct acpi_subtable_proc *proc,
383+
int proc_num, unsigned int max_entries)
359384
{
360385
struct acpi_table_header *table_header = NULL;
361386
int count;
@@ -386,21 +411,41 @@ int __init acpi_table_parse_entries_array(char *id,
386411
return count;
387412
}
388413

389-
int __init acpi_table_parse_entries(char *id,
390-
unsigned long table_size,
391-
int entry_id,
392-
acpi_tbl_entry_handler handler,
393-
unsigned int max_entries)
414+
static int __init_or_acpilib __acpi_table_parse_entries(
415+
char *id, unsigned long table_size, int entry_id,
416+
acpi_tbl_entry_handler handler, acpi_tbl_entry_handler_arg handler_arg,
417+
void *arg, unsigned int max_entries)
394418
{
395419
struct acpi_subtable_proc proc = {
396420
.id = entry_id,
397421
.handler = handler,
422+
.handler_arg = handler_arg,
423+
.arg = arg,
398424
};
399425

400426
return acpi_table_parse_entries_array(id, table_size, &proc, 1,
401427
max_entries);
402428
}
403429

430+
int __init_or_acpilib
431+
acpi_table_parse_cedt(enum acpi_cedt_type id,
432+
acpi_tbl_entry_handler_arg handler_arg, void *arg)
433+
{
434+
return __acpi_table_parse_entries(ACPI_SIG_CEDT,
435+
sizeof(struct acpi_table_cedt), id,
436+
NULL, handler_arg, arg, 0);
437+
}
438+
EXPORT_SYMBOL_ACPI_LIB(acpi_table_parse_cedt);
439+
440+
int __init acpi_table_parse_entries(char *id, unsigned long table_size,
441+
int entry_id,
442+
acpi_tbl_entry_handler handler,
443+
unsigned int max_entries)
444+
{
445+
return __acpi_table_parse_entries(id, table_size, entry_id, handler,
446+
NULL, NULL, max_entries);
447+
}
448+
404449
int __init acpi_table_parse_madt(enum acpi_madt_type id,
405450
acpi_tbl_entry_handler handler, unsigned int max_entries)
406451
{

drivers/cxl/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ config CXL_ACPI
5151
tristate "CXL ACPI: Platform Support"
5252
depends on ACPI
5353
default CXL_BUS
54+
select ACPI_TABLE_LIB
5455
help
5556
Enable support for host managed device memory (HDM) resources
5657
published by a platform's ACPI CXL memory layout description. See

0 commit comments

Comments
 (0)