qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC PATCH 4/5] hw/i386: Generate apicid based on cpu_t


From: Moger, Babu
Subject: Re: [Qemu-devel] [RFC PATCH 4/5] hw/i386: Generate apicid based on cpu_type
Date: Thu, 1 Aug 2019 19:37:26 +0000

Hi Eduardo,
  Thanks for the quick comments. I will look into your comments closely
and will let you know if I have questions.

> -----Original Message-----
> From: Eduardo Habkost <address@hidden>
> Sent: Thursday, August 1, 2019 2:29 PM
> To: Moger, Babu <address@hidden>
> Cc: address@hidden; address@hidden; address@hidden;
> address@hidden; address@hidden; address@hidden
> Subject: Re: [RFC PATCH 4/5] hw/i386: Generate apicid based on cpu_type
> 
> Thanks for the patches.
> 
> I still haven't looked closely at all patches in the series, but
> patches 1-3 seem good on the first look.  A few comments on this
> one:
> 
> On Wed, Jul 31, 2019 at 11:20:50PM +0000, Moger, Babu wrote:
> > Check the cpu_type before calling the apicid functions
> > from topology.h.
> >
> > Signed-off-by: Babu Moger <address@hidden>
> > ---
> [...]
> > @@ -2437,16 +2478,26 @@ static void pc_cpu_pre_plug(HotplugHandler
> *hotplug_dev,
> >          topo.die_id = cpu->die_id;
> >          topo.core_id = cpu->core_id;
> >          topo.smt_id = cpu->thread_id;
> > -        cpu->apic_id = apicid_from_topo_ids(pcms->smp_dies, smp_cores,
> > -                                            smp_threads, &topo);
> > +   if (!strncmp(ms->cpu_type, "EPYC", 4)) {
> 
> Please don't add semantics to the CPU type name.  If you want
> some behavior to be configurable per CPU type, please do it at
> the X86CPUDefinition struct.
> 
> In this specific case, maybe the new APIC ID calculation code
> could
> be conditional on:
>   (vendor == AMD) && (env->features[...] & TOPOEXT).
> 
> Also, we must keep compatibility with the old APIC ID calculation
> code on older machine types.  We need a compatibility flag to
> enable the existing APIC ID calculation.
> 
> 
> > +            x86_topo_ids_from_idx_epyc(nb_numa_nodes, smp_sockets,
> smp_cores,
> > +                                       smp_threads, idx, &topo);
> > +            cpu->apic_id = apicid_from_topo_ids_epyc(smp_cores,
> smp_threads,
> > +                                                     &topo);
> > +   } else
> 
> There's a tab character here.  Please use spaces instead of tabs.
> 
> > +            cpu->apic_id = apicid_from_topo_ids(pcms->smp_dies, smp_cores,
> > +                                                smp_threads, &topo);
> 
> I see you are duplicating very similar logic in 3 different
> places, to call apicid_from_topo_ids() and
> x86_topo_ids_from_apicid().
> 
> Also, apicid_from_topo_ids() and x86_topo_ids_from_apicid() have very
> generic
> names, and people could call them expecting them to work for every CPU
> model
> (which they don't).  This makes the topology API very easy to misuse.
> 
> Why don't we make the existing generic
> apicid_from_topo_ids()/x86_topo_ids_from_apicid() functions work
> on all cases?  If they need additional input to handle EPYC and
> call EPYC-specific functions, we can make them get additional
> arguments.  This way we'll be sure that we'll never call the
> wrong implementation by accident.
> 
> This might make the list of arguments for
> x86_topo_ids_from_apicid() and apicid_from_topo_ids() become
> large.  We can address this by making them get a CpuTopology
> argument.
> 
> 
> In other words, the API could look like this:
> 
> 
> static inline apic_id_t apicid_from_topo_ids(const X86CPUTopology *topo,
>                                              const X86CPUTopologyIds *ids)
> {
>     if (topo->epyc_mode) {
>         return apicid_from_topo_ids_epyc(topo, ids);
>     }
> 
>     /* existing QEMU 4.1 logic: */
>     return (ids->pkg_id  << apicid_pkg_offset(topo)) |
>            (ids->die_id  << apicid_die_offset(topo)) |
>            (ids->core_id << apicid_core_offset(topo)) |
>            ids->smt_id;
> }
> 
> static inline void x86_topo_ids_from_apicid(apic_id_t apicid,
>                                             const X86CPUTopology *topo,
>                                             X86CPUTopologyIds *ids)
> {
>     if (topo->epyc_mode) {
>         x86_topo_ids_from_apicid_epyc(apicid, topo, ids);
>         return;
>     }
> 
>     /* existing QEMU 4.1 logic: */
>     ids->smt_id =
>             apicid &
>             ~(0xFFFFFFFFUL << apicid_smt_width(topo));
>     ids->core_id =
>             (apicid >> apicid_core_offset(topo)) &
>             ~(0xFFFFFFFFUL << apicid_core_width(topo));
>     ids->die_id =
>             (apicid >> apicid_die_offset(topo)) &
>             ~(0xFFFFFFFFUL << apicid_die_width(topo));
>     ids->pkg_id = apicid >> apicid_pkg_offset(topo);
> }
> 
> 
> >      }
> >
> >      cpu_slot = pc_find_cpu_slot(MACHINE(pcms), cpu->apic_id, &idx);
> >      if (!cpu_slot) {
> >          MachineState *ms = MACHINE(pcms);
> >
> > -        x86_topo_ids_from_apicid(cpu->apic_id, pcms->smp_dies,
> > -                                 smp_cores, smp_threads, &topo);
> > +        if(!strncmp(ms->cpu_type, "EPYC", 4))
> > +            x86_topo_ids_from_apicid_epyc(cpu->apic_id, pcms->smp_dies,
> > +                                          smp_cores, smp_threads, &topo);
> > +        else
> > +            x86_topo_ids_from_apicid(cpu->apic_id, pcms->smp_dies,
> > +                                     smp_cores, smp_threads, &topo);
> >          error_setg(errp,
> >              "Invalid CPU [socket: %u, die: %u, core: %u, thread: %u] with"
> >              " APIC ID %" PRIu32 ", valid index range 0:%d",
> > @@ -2874,10 +2925,18 @@ static const CPUArchIdList
> *pc_possible_cpu_arch_ids(MachineState *ms)
> >
> >          ms->possible_cpus->cpus[i].type = ms->cpu_type;
> >          ms->possible_cpus->cpus[i].vcpus_count = 1;
> > -        ms->possible_cpus->cpus[i].arch_id =
> x86_cpu_apic_id_from_index(pcms, i);
> > -        x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id,
> > -                                 pcms->smp_dies, ms->smp.cores,
> > -                                 ms->smp.threads, &topo);
> > +   if(!strncmp(ms->cpu_type, "EPYC", 4)) {
> > +            ms->possible_cpus->cpus[i].arch_id =
> > +                            x86_cpu_apic_id_from_index_epyc(pcms, i);
> > +            x86_topo_ids_from_apicid_epyc(ms->possible_cpus-
> >cpus[i].arch_id,
> > +                                          pcms->smp_dies, ms->smp.cores,
> > +                                     ms->smp.threads, &topo);
> > +   } else {
> > +            ms->possible_cpus->cpus[i].arch_id =
> x86_cpu_apic_id_from_index(pcms, i);
> > +            x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id,
> > +                                     pcms->smp_dies, ms->smp.cores,
> > +                                     ms->smp.threads, &topo);
> > +   }
> >          ms->possible_cpus->cpus[i].props.has_socket_id = true;
> >          ms->possible_cpus->cpus[i].props.socket_id = topo.pkg_id;
> >          ms->possible_cpus->cpus[i].props.has_die_id = true;
> > --
> > 2.20.1
> >
> 
> --
> Eduardo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]