On the actual hardware, CXL memory is exposed to the OS as a "Memory Only Node." This allows the OS to recognize that accessing CXL memory takes time. As a preliminary step, a function was created to automatically add a NUMA node for each instance of CXL memory. This function generates one NUMA node per instance of CXL memory. This function is executed when program_hdm_decoder is set.
Signed-off-by: Yukiya Takaki <[email protected]> --- hw/cxl/cxl-host.c | 38 +++++++++++++++++++++++++++++++++++++ hw/i386/pc.c | 1 + include/hw/cxl/cxl_device.h | 1 + include/hw/cxl/cxl_host.h | 1 + 4 files changed, 41 insertions(+) diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c index 1967c9a9c3..ba321841dc 100644 --- a/hw/cxl/cxl-host.c +++ b/hw/cxl/cxl-host.c @@ -720,6 +720,44 @@ void cxl_c3_update_mmio(void) object_child_foreach_recursive(object_get_root(), cxl_c3_mmio_map, NULL); } +static int setup_cxl_numa_node_inner(Object *obj, void *opaque) +{ + MachineState *machine = opaque; + DeviceState *dev; + CXLType3Dev *c3d; + int node_id; + + if (!object_dynamic_cast(obj, TYPE_CXL_TYPE3)) { + return 0; + } + + dev = DEVICE(obj); + c3d = CXL_TYPE3(dev); + node_id = machine->numa_state->num_nodes; + + if (!c3d->program_hdm_decoder) { + return 0; + } + + NumaOptions option = { + .type = NUMA_OPTIONS_TYPE_NODE, + .u.node = { + .has_nodeid = true, + .nodeid = node_id, + }, + }; + + set_numa_options(machine, &option, &error_fatal); + c3d->node = node_id; + return 0; +} + +void setup_cxl_numa_node(MachineState *machine) +{ + object_child_foreach_recursive(object_get_root(), + setup_cxl_numa_node_inner, machine); +} + hwaddr cxl_fmws_set_memmap(hwaddr base, hwaddr max_addr) { GSList *cfmws_list, *iter; diff --git a/hw/i386/pc.c b/hw/i386/pc.c index f843629543..b1d1f03468 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -534,6 +534,7 @@ void pc_machine_done(Notifier *notifier, void *data) if (pcms->cxl_devices_state.is_enabled) { cxl_fmws_link_targets(&error_fatal); + setup_cxl_numa_node(MACHINE(pcms)); cxl_c3_update_mmio(); } diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index 07654f4b62..9001aacf0e 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -780,6 +780,7 @@ struct CXLType3Dev { bool program_hdm_decoder; hwaddr hpa_offset; int idx; + int node; struct dynamic_capacity { HostMemoryBackend *host_dc; diff --git a/include/hw/cxl/cxl_host.h b/include/hw/cxl/cxl_host.h index 6c142a5b89..70285328c4 100644 --- a/include/hw/cxl/cxl_host.h +++ b/include/hw/cxl/cxl_host.h @@ -19,6 +19,7 @@ void cxl_hook_up_pxb_registers(PCIBus *bus, CXLState *state, Error **errp); hwaddr cxl_fmws_set_memmap(hwaddr base, hwaddr max_addr); void cxl_fmws_update_mmio(void); void cxl_c3_update_mmio(void); +void setup_cxl_numa_node(MachineState *machine); void cxl_c3_add_memory_map(hwaddr base, hwaddr size); GSList *cxl_fmws_get_all_sorted(void); -- 2.52.0
