qemu-devel
[Top][All Lists]
Advanced

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

Re: [PATCH v7 07/13] hw/386: Add EPYC mode topology decoding functions


From: Babu Moger
Subject: Re: [PATCH v7 07/13] hw/386: Add EPYC mode topology decoding functions
Date: Wed, 3 Jun 2020 10:38:46 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.8.0


On 6/3/20 10:31 AM, Eduardo Habkost wrote:
> On Wed, Jun 03, 2020 at 10:22:10AM -0500, Babu Moger wrote:
>>
>>
>>> -----Original Message-----
>>> From: Eduardo Habkost <ehabkost@redhat.com>
>>> Sent: Tuesday, June 2, 2020 6:01 PM
>>> To: Moger, Babu <Babu.Moger@amd.com>
>>> Cc: marcel.apfelbaum@gmail.com; pbonzini@redhat.com; rth@twiddle.net;
>>> mst@redhat.com; imammedo@redhat.com; qemu-devel@nongnu.org
>>> Subject: Re: [PATCH v7 07/13] hw/386: Add EPYC mode topology decoding
>>> functions
>>>
>>> On Tue, Jun 02, 2020 at 04:59:19PM -0500, Babu Moger wrote:
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: Eduardo Habkost <ehabkost@redhat.com>
>>>>> Sent: Tuesday, June 2, 2020 12:19 PM
>>>>> To: Moger, Babu <Babu.Moger@amd.com>
>>>>> Cc: marcel.apfelbaum@gmail.com; pbonzini@redhat.com; rth@twiddle.net;
>>>>> mst@redhat.com; imammedo@redhat.com; qemu-devel@nongnu.org
>>>>> Subject: Re: [PATCH v7 07/13] hw/386: Add EPYC mode topology decoding
>>>>> functions
>>>>>
>>>>> Hi,
>>>>>
>>>>> It looks like this series breaks -device and CPU hotplug:
>>>>>
>>>>> On Wed, Mar 11, 2020 at 05:53:34PM -0500, Babu Moger wrote:
>>>>>> These functions add support for building EPYC mode topology given the
>>> smp
>>>>>> details like numa nodes, cores, threads and sockets.
>>>>>>
>>>>>> The new apic id decoding is mostly similar to current apic id decoding
>>>>>> except that it adds a new field node_id when numa configured. Removes
>>> all
>>>>>> the hardcoded values. Subsequent patches will use these functions to 
>>>>>> build
>>>>>> the topology.
>>>>>>
>>>>>> Following functions are added.
>>>>>> apicid_llc_width_epyc
>>>>>> apicid_llc_offset_epyc
>>>>>> apicid_pkg_offset_epyc
>>>>>> apicid_from_topo_ids_epyc
>>>>>> x86_topo_ids_from_idx_epyc
>>>>>> x86_topo_ids_from_apicid_epyc
>>>>>> x86_apicid_from_cpu_idx_epyc
>>>>>>
>>>>>> The topology details are available in Processor Programming Reference
>>> (PPR)
>>>>>> for AMD Family 17h Model 01h, Revision B1 Processors. The revision
>>> guides
>>>>> are
>>>>>> available from the bugzilla Link below.
>>>>>> Link:
>>>>>
>>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugzilla.
>>>>>
>>> kernel.org%2Fshow_bug.cgi%3Fid%3D206537&amp;data=02%7C01%7Cbabu.m
>>>>>
>>> oger%40amd.com%7C3487f40d37df4d59097d08d807190248%7C3dd8961fe488
>>>>>
>>> 4e608e11a82d994e183d%7C0%7C0%7C637267151289763739&amp;sdata=wE0
>>>>> ukXIVh0l5eNQWsv6VDE9UZEVJmisofaW192gcZAI%3D&amp;reserved=0
>>>>>>
>>>>>> Signed-off-by: Babu Moger <babu.moger@amd.com>
>>>>>> Acked-by: Igor Mammedov <imammedo@redhat.com>
>>>>>> Acked-by: Michael S. Tsirkin <mst@redhat.com>
>>>>>> ---
>>>>> [...]
>>>>>>  typedef struct X86CPUTopoIDs {
>>>>>>      unsigned pkg_id;
>>>>>> +    unsigned node_id;
>>>>>
>>>>> You have added a new field here.
>>>>>
>>>>>>      unsigned die_id;
>>>>>>      unsigned core_id;
>>>>>>      unsigned smt_id;
>>>>> [...]
>>>>>> +static inline apic_id_t
>>>>>> +x86_apicid_from_topo_ids_epyc(X86CPUTopoInfo *topo_info,
>>>>>> +                              const X86CPUTopoIDs *topo_ids)
>>>>>> +{
>>>>>> +    return (topo_ids->pkg_id  << apicid_pkg_offset_epyc(topo_info)) |
>>>>>> +           (topo_ids->node_id << apicid_node_offset_epyc(topo_info)) |
>>>>>
>>>>> You are using the new field here.
>>>>>
>>>>>> +           (topo_ids->die_id  << apicid_die_offset(topo_info)) |
>>>>>> +           (topo_ids->core_id << apicid_core_offset(topo_info)) |
>>>>>> +           topo_ids->smt_id;
>>>>>> +}
>>>>>
>>>>> But you are not initializing node_id in one caller of 
>>>>> apicid_from_topo_ids():
>>>>>
>>>>> static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
>>>>>                             DeviceState *dev, Error **errp)
>>>>> {
>>>>>     [...]
>>>>>     X86CPUTopoIDs topo_ids;
>>>>>     [...]
>>>>>     if (cpu->apic_id == UNASSIGNED_APIC_ID) {
>>>>>         [...]
>>>>>         topo_ids.pkg_id = cpu->socket_id;
>>>>>         topo_ids.die_id = cpu->die_id;
>>>>>         topo_ids.core_id = cpu->core_id;
>>>>>         topo_ids.smt_id = cpu->thread_id;
>>>>>         cpu->apic_id = x86ms->apicid_from_topo_ids(&topo_info, &topo_ids);
>>>>>     }
>>>>>     [...]
>>>>> }
>>>>>
>>>>> Result: -device is broken when using -cpu EPYC:
>>>>>
>>>>>   $ qemu-system-x86_64 -machine q35,accel=kvm -smp
>>>>> 1,maxcpus=2,cores=1,threads=1,sockets=2 -cpu EPYC -device EPYC-x86_64-
>>>>> cpu,core-id=0,socket-id=1,thread-id=0
>>>
>>> [1]
>>>
>>>>>   qemu-system-x86_64: -device EPYC-x86_64-cpu,core-id=0,socket-
>>> id=1,thread-
>>>>> id=0: Invalid CPU [socket: 21855, die: 0, core: 0, thread: 0] with APIC ID
>>> 21855,
>>>>> valid index range 0:1
>>>>>
>>>>> This happens because APIC ID is calculated using uninitialized
>>>>> memory.
>>>> This patch should initialize the node_id. But I am not sure how to
>>>> reproduce the bug. Can you please send me the full command line to
>>>> reproduce the problem. Also test different options.
>>>
>>> The full command line is above[1].
>>
>> I just picked up the latest tree from
>> git clone 
>> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.qemu.org%2Fgit%2Fqemu.git&amp;data=02%7C01%7Cbabu.moger%40amd.com%7C7752c36b7ad24df4039d08d807d334fa%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637267951007572953&amp;sdata=69rG4w79FnLs9bhNmroxsRckzmy%2BGuH1dMjyP8PPRUo%3D&amp;reserved=0
>>  qemu
>> Not seeing the problem.
>>
>> ./x86_64-softmmu/qemu-system-x86_64 -machine q35,accel=kvm -smp
>> 1,maxcpus=2,cores=1,threads=1,sockets=2 -cpu EPYC -device
>> EPYC-x86_64-cpu,core-id=0,socket-id=1,thread-id=0
>> VNC server running on ::1:5900
>>
>> It appears to run ok.

[2]

>>
>>>
>>>
>>>>
>>>> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
>>>> index 2128f3d6fe..047b4b9391 100644
>>>> --- a/hw/i386/pc.c
>>>> +++ b/hw/i386/pc.c
>>>> @@ -1539,6 +1539,9 @@ static void pc_cpu_pre_plug(HotplugHandler
>>> *hotplug_dev,
>>>>      if (cpu->apic_id == UNASSIGNED_APIC_ID) {
>>>>          int max_socket = (ms->smp.max_cpus - 1) /
>>>>                                  smp_threads / smp_cores / x86ms->smp_dies;
>>>
>>> So, here's the input you are using to calculate topo_ids.node_id:
>>>
>>>> +        unsigned nr_nodes = MAX(topo_info.nodes_per_pkg, 1);
>>>
>>> When is topo_info.nodes_per_pkg allowed to be 0?
>>
>> It will be zero if numa is not configured. Node_id will be zero for all
>> the cores.
>>
>>>
>>>> +        unsigned cores_per_node = DIV_ROUND_UP((x86ms->smp_dies *
>>> smp_cores *
>>>> +                                                smp_threads), nr_nodes);
>>>
>>> x86ms->smp_dies should be available at topo_info.dies_per_pkg,
>>> smp_cores should available at topo_info.cores_per_die,
>>> smp_threads should be available at topo_info.threads_per_core,
>>> nr_nodes should be available at topo_info.nodes_per_pkg.
>>>
>>>>
>>>>          /*
>>>>           * die-id was optional in QEMU 4.0 and older, so keep it optional
>>>> @@ -1585,6 +1588,7 @@ static void pc_cpu_pre_plug(HotplugHandler
>>> *hotplug_dev,
>>>>          topo_ids.die_id = cpu->die_id;
>>>>          topo_ids.core_id = cpu->core_id;
>>>>          topo_ids.smt_id = cpu->thread_id;
>>>> +        topo_ids.node_id = (cpu->core_id / cores_per_node) % nr_nodes;
>>>
>>> apicid_from_topo_ids() have access to topo_info and topo_ids, If
>>> all the information you need to calculate node_id is already
>>> available inside topo_info + topo_ids, we could be calculating it
>>> inside apicid_from_topo_ids().  Why don't we do it?
>>>
>>> Also, is topo_ids.core_id really allowed to be larger than
>>> cores_per_node when calling apicid_from_topo_ids()?
>>
>> Yes. It is. If we have two numa nodes and 8 cores. Then cores_per_node is
>> 4. Nr_nodes =2. Yes. Core_id can be larger than cores_per_node.
> 
> I assumed core_id identified the core inside a die, and the range
> would be [0, cores_per_die).  This seems to be what
> apicid_from_topo_ids_epyc() expects.
> 
> We need clearer documentation on the semantics of each *_id
> field, to avoid confusion.

Ok. Sure. I will add that. Can you please clarify on how to repro the
issue. Marked the question at [2].

> 
>>
>>>
>>>>          cpu->apic_id =
>>>>          x86ms->apicid_from_topo_ids(&topo_info,
>>>>          &topo_ids); }
>>>>
>>>
>>> -- Eduardo
>>
> 



reply via email to

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