All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Andreas Färber" <afaerber@suse.de>
To: Bharata B Rao <bharata.rao@gmail.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
	Richard Henderson <rth@twiddle.net>
Subject: Re: [Qemu-devel] [PATCH RFC 3/4] pc: Create sockets and cores for CPUs
Date: Wed, 25 Mar 2015 18:13:48 +0100	[thread overview]
Message-ID: <5512ECCC.3050708@suse.de> (raw)
In-Reply-To: <CAGZKiBq6QT2TriEo-+MFea8QNK+6F_1xDJduAuapN_ZDWUxx-A@mail.gmail.com>

Am 25.03.2015 um 17:55 schrieb Bharata B Rao:
> On Mon, Mar 23, 2015 at 11:02 PM, Andreas Färber <afaerber@suse.de> wrote:
>> Inline realized=true from pc_new_cpu() so that the realization can be
>> deferred, as it would otherwise create a device[n] node.
>>
>> Signed-off-by: Andreas Färber <afaerber@suse.de>
>> ---
>>  hw/i386/pc.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
>>  1 file changed, 58 insertions(+), 8 deletions(-)
>>
>> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
>> index 2c48277..492c262 100644
>> --- a/hw/i386/pc.c
>> +++ b/hw/i386/pc.c
>> @@ -54,11 +54,14 @@
>>  #include "exec/memory.h"
>>  #include "exec/address-spaces.h"
>>  #include "sysemu/arch_init.h"
>> +#include "sysemu/cpus.h"
>>  #include "qemu/bitmap.h"
>>  #include "qemu/config-file.h"
>>  #include "hw/acpi/acpi.h"
>>  #include "hw/acpi/cpu_hotplug.h"
>>  #include "hw/cpu/icc_bus.h"
>> +#include "hw/i386/cpu-socket.h"
>> +#include "hw/i386/cpu-core.h"
>>  #include "hw/boards.h"
>>  #include "hw/pci/pci_host.h"
>>  #include "acpi-build.h"
>> @@ -990,6 +993,17 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level)
>>      }
>>  }
>>
>> +static inline size_t pc_cpu_core_size(void)
>> +{
>> +    return sizeof(X86CPUCore);
>> +}
>> +
>> +static inline X86CPUCore *pc_cpu_socket_get_core(X86CPUSocket *socket,
>> +                                                 unsigned int index)
>> +{
>> +    return &socket->core[index];
>> +}
>> +
>>  static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id,
>>                            DeviceState *icc_bridge, Error **errp)
>>  {
>> @@ -1009,7 +1023,6 @@ static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id,
>>      qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc"));
>>
>>      object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err);
>> -    object_property_set_bool(OBJECT(cpu), true, "realized", &local_err);
>>
>>  out:
>>      if (local_err) {
>> @@ -1060,15 +1073,19 @@ void pc_hot_add_cpu(const int64_t id, Error **errp)
>>          error_propagate(errp, local_err);
>>          return;
>>      }
>> +    object_property_set_bool(OBJECT(cpu), true, "realized", errp);
>>      object_unref(OBJECT(cpu));
>>  }
>>
>>  void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge)
>>  {
>> -    int i;
>> +    int i, j, k;
>> +    X86CPUSocket *socket;
>> +    X86CPUCore *core;
>>      X86CPU *cpu = NULL;
>>      Error *error = NULL;
>>      unsigned long apic_id_limit;
>> +    int sockets, cpu_index = 0;
>>
>>      /* init CPUs */
>>      if (cpu_model == NULL) {
>> @@ -1087,14 +1104,41 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge)
>>          exit(1);
>>      }
>>
>> -    for (i = 0; i < smp_cpus; i++) {
>> -        cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i),
>> -                         icc_bridge, &error);
>> +    sockets = smp_cpus / smp_cores / smp_threads;
>> +    for (i = 0; i < sockets; i++) {
>> +        socket = g_malloc0(sizeof(*socket) + smp_cores * pc_cpu_core_size());
>> +        object_initialize(socket, sizeof(*socket), TYPE_X86_CPU_SOCKET);
>> +        OBJECT(socket)->free = g_free;
>> +
>> +        for (j = 0; j < smp_cores; j++) {
>> +            core = pc_cpu_socket_get_core(socket, j);
>> +            object_initialize(core, sizeof(*core), TYPE_X86_CPU_CORE);
>> +            object_property_add_child(OBJECT(socket), "core[*]",
>> +                                      OBJECT(core), &error);
>> +            if (error) {
>> +                goto error;
>> +            }
>> +
>> +            for (k = 0; k < smp_threads; k++) {
>> +                cpu = pc_new_cpu(cpu_model,
>> +                                 x86_cpu_apic_id_from_index(cpu_index),
>> +                                 icc_bridge, &error);
>> +                if (error) {
>> +                    goto error;
>> +                }
>> +                object_property_add_child(OBJECT(core), "thread[*]",
>> +                                          OBJECT(cpu), &error);
>> +                object_unref(OBJECT(cpu));
>> +                if (error) {
>> +                    goto error;
>> +                }
>> +                cpu_index++;
>> +            }
>> +        }
>> +        object_property_set_bool(OBJECT(socket), true, "realized", &error);
> 
> So you do in-place initialization as part of an "atomic" socket object.

(indivisible might've been a better term on my part)

> 
> I am not sure why cores and threads should be allocated as part of
> socket object and initialized like above ? Do you see any problem with
> just instantiating the socket object and then let the instance_init
> routines of socket and cores to initialize the cores and threads like
> how I am doing for sPAPR ?
> 
> +    sockets = smp_cpus / smp_cores / smp_threads;
> +    for (i = 0; i < sockets; i++) {
> +        socket = object_new(TYPE_POWERPC_CPU_SOCKET);
> +        object_property_set_bool(socket, true, "realized", &error_abort);
>      }
> 
> Ref: http://lists.gnu.org/archive/html/qemu-ppc/2015-03/msg00492.html

Yes, instance_init cannot fail. By making the allocation separate, we
assure that at this stage we have sufficient memory to perform the
initializations. This is easiest when we know how many child objects we
have, then we can use proper fields or arrays to reserve the memory
(e.g., ARM MPCore, PCI host bridges). Here, to cope with dynamic
smp_cores, I am using inline helpers to do the size/offset calculations.

Further, setting realized=true from instance_init is a no-go. It's a
two-step initialization, with realization being the second step and
potentially failing. The alternative I pointed you to was creating
objects in a property setter, like Alexey was asked for for xics.

Regards,
Andreas

-- 
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu,
Graham Norton; HRB 21284 (AG Nürnberg)

  reply	other threads:[~2015-03-25 17:13 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-23 17:31 [Qemu-devel] [PATCH RFC 0/4] target-i386: PC socket/core/thread modeling, part 1 Andreas Färber
2015-03-23 17:32 ` [Qemu-devel] [PATCH RFC 1/4] cpu: Prepare Socket container type Andreas Färber
2015-03-23 17:32 ` [Qemu-devel] [PATCH RFC 2/4] target-i386: Prepare CPU socket/core abstraction Andreas Färber
2015-03-23 17:32 ` [Qemu-devel] [PATCH RFC 3/4] pc: Create sockets and cores for CPUs Andreas Färber
2015-03-25 16:55   ` Bharata B Rao
2015-03-25 17:13     ` Andreas Färber [this message]
2015-03-26  2:24       ` Bharata B Rao
2015-03-23 17:32 ` [Qemu-devel] [PATCH RFC 4/4] pc: Create initial CPUs in-place Andreas Färber
2015-03-24 14:33 ` [Qemu-devel] [PATCH RFC 0/4] target-i386: PC socket/core/thread modeling, part 1 Christian Borntraeger
2015-03-26 17:39 ` Igor Mammedov
2015-04-07 12:43 ` [Qemu-devel] cpu modelling and hotplug (was: [PATCH RFC 0/4] target-i386: PC socket/core/thread modeling, part 1) Christian Borntraeger
2015-04-07 15:07   ` Igor Mammedov
2015-04-08  7:07     ` [Qemu-devel] cpu modelling and hotplug Christian Borntraeger
2015-04-23  7:32   ` [Qemu-devel] cpu modelling and hotplug (was: [PATCH RFC 0/4] target-i386: PC socket/core/thread modeling, part 1) David Gibson
2015-04-23  7:37     ` David Gibson
2015-04-23 13:17     ` Eduardo Habkost
2015-04-27 10:46       ` David Gibson
2015-10-22  1:27   ` [Qemu-devel] cpu modelling and hotplug Zhu Guihua
2015-10-22 16:52     ` Andreas Färber

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5512ECCC.3050708@suse.de \
    --to=afaerber@suse.de \
    --cc=bharata.rao@gmail.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.