On Tue, 20 Feb 2024 17:25:00 +0800 Zhao Liu <zhao1.liu@xxxxxxxxxxxxxxx> wrote: > From: Zhao Liu <zhao1.liu@xxxxxxxxx> > > Add "l1d-cache", "l1i-cache". "l2-cache", and "l3-cache" options in > -smp to define the cache topology for SMP system. > > Signed-off-by: Zhao Liu <zhao1.liu@xxxxxxxxx> Hi Zhao Liu I like the scheme. Strikes a good balance between complexity of description and systems that actually exist. Sure there are systems with more cache levels etc but they are rare and support can be easily added later if people want to model them. A few minor comments inline. Jonathan > --- > hw/core/machine-smp.c | 128 ++++++++++++++++++++++++++++++++++++++++++ > hw/core/machine.c | 4 ++ > qapi/machine.json | 14 ++++- > system/vl.c | 15 +++++ > 4 files changed, 160 insertions(+), 1 deletion(-) > > diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c > index 8a8296b0d05b..2cbd19f4aa57 100644 > --- a/hw/core/machine-smp.c > +++ b/hw/core/machine-smp.c > @@ -61,6 +61,132 @@ static char *cpu_hierarchy_to_string(MachineState *ms) > return g_string_free(s, false); > } > > +static bool machine_check_topo_support(MachineState *ms, > + CPUTopoLevel topo) > +{ > + MachineClass *mc = MACHINE_GET_CLASS(ms); > + > + if (topo == CPU_TOPO_LEVEL_MODULE && !mc->smp_props.modules_supported) { > + return false; > + } > + > + if (topo == CPU_TOPO_LEVEL_CLUSTER && !mc->smp_props.clusters_supported) { > + return false; > + } > + > + if (topo == CPU_TOPO_LEVEL_DIE && !mc->smp_props.dies_supported) { > + return false; > + } > + > + if (topo == CPU_TOPO_LEVEL_BOOK && !mc->smp_props.books_supported) { > + return false; > + } > + > + if (topo == CPU_TOPO_LEVEL_DRAWER && !mc->smp_props.drawers_supported) { > + return false; > + } > + > + return true; > +} > + > +static int smp_cache_string_to_topology(MachineState *ms, Not a good name for a function that does rather more than that. > + char *topo_str, > + CPUTopoLevel *topo, > + Error **errp) > +{ > + *topo = string_to_cpu_topo(topo_str); > + > + if (*topo == CPU_TOPO_LEVEL_MAX || *topo == CPU_TOPO_LEVEL_INVALID) { > + error_setg(errp, "Invalid cache topology level: %s. The cache " > + "topology should match the CPU topology level", topo_str); > + return -1; > + } > + > + if (!machine_check_topo_support(ms, *topo)) { > + error_setg(errp, "Invalid cache topology level: %s. The topology " > + "level is not supported by this machine", topo_str); > + return -1; > + } > + > + return 0; > +} > + > +static void machine_parse_smp_cache_config(MachineState *ms, > + const SMPConfiguration *config, > + Error **errp) > +{ > + MachineClass *mc = MACHINE_GET_CLASS(ms); > + > + if (config->l1d_cache) { > + if (!mc->smp_props.l1_separated_cache_supported) { > + error_setg(errp, "L1 D-cache topology not " > + "supported by this machine"); > + return; > + } > + > + if (smp_cache_string_to_topology(ms, config->l1d_cache, > + &ms->smp_cache.l1d, errp)) { Indent is to wrong opening bracket. Same for other cases. > + return; > + } > + } > +} > + > /* > * machine_parse_smp_config: Generic function used to parse the given > * SMP configuration > @@ -249,6 +375,8 @@ void machine_parse_smp_config(MachineState *ms, > mc->name, mc->max_cpus); > return; > } > + > + machine_parse_smp_cache_config(ms, config, errp); > } > > unsigned int machine_topo_get_cores_per_socket(const MachineState *ms)