qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [RFC PATCH v2.1 08/12] spapr: Add CPU type specific cor


From: Michael Roth
Subject: Re: [Qemu-devel] [RFC PATCH v2.1 08/12] spapr: Add CPU type specific core devices
Date: Fri, 08 Apr 2016 18:35:10 -0500
User-agent: alot/0.3.6

Quoting Bharata B Rao (2016-03-31 03:39:17)
> Introduce core devices for each CPU type supported by sPAPR. These
> core devices are derived from the base spapr-cpu-core device type.
> 
> TODO:
> - Add core types for other remaining CPU types
> - Handle CPU model alias correctly
> 
> Signed-off-by: Bharata B Rao <address@hidden>
> ---
>  hw/ppc/spapr.c                  |   3 +-
>  hw/ppc/spapr_cpu_core.c         | 118 
> ++++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/spapr.h          |   1 +
>  include/hw/ppc/spapr_cpu_core.h |  36 ++++++++++++
>  4 files changed, 156 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 64c4acc..45ac5dc 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -1614,8 +1614,7 @@ static void spapr_boot_set(void *opaque, const char 
> *boot_device,
>      machine->boot_order = g_strdup(boot_device);
>  }
> 
> -static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu,
> -                           Error **errp)
> +void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu, Error **errp)
>  {
>      CPUPPCState *env = &cpu->env;
> 
> diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
> index 8cbe2a5..3751a54 100644
> --- a/hw/ppc/spapr_cpu_core.c
> +++ b/hw/ppc/spapr_cpu_core.c
> @@ -22,9 +22,127 @@ static const TypeInfo spapr_cpu_core_type_info = {
>      .instance_size = sizeof(sPAPRCPUCore),
>  };
> 
> +#define DEFINE_SPAPR_CPU_CORE(_name)                                         
>   \
> +static void                                                                  
>   \
> +glue(_name, _spapr_cpu_core_create_threads)(DeviceState *dev, int threads,   
>   \
> +    Error **errp)                                                            
>   \
> +{                                                                            
>   \
> +    int i;                                                                   
>   \
> +    Error *local_err = NULL;                                                 
>   \
> +    sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));                          
>   \
> +    glue(_name, sPAPRCPUCore) * core =                                       
>   \
> +         glue(_name, _SPAPR_CPU_CORE)(OBJECT(dev));                          
>   \
> +                                                                             
>   \
> +    for (i = 0; i < threads; i++) {                                          
>   \
> +        char id[32];                                                         
>   \
> +                                                                             
>   \
> +        object_initialize(&sc->threads[i], sizeof(sc->threads[i]),           
>   \
> +                          object_class_get_name(core->cpu));                 
>   \
> +        snprintf(id, sizeof(id), "thread[%d]", i);                           
>   \
> +        object_property_add_child(OBJECT(core), id, OBJECT(&sc->threads[i]), 
>   \
> +                                  &local_err);                               
>   \
> +        if (local_err) {                                                     
>   \
> +            goto err;                                                        
>   \
> +        }                                                                    
>   \
> +    }                                                                        
>   \
> +    return;                                                                  
>   \
> +                                                                             
>   \
> +err:                                                                         
>   \
> +    while (--i) {                                                            
>   \
> +        object_unparent(OBJECT(&sc->threads[i]));                            
>   \
> +    }                                                                        
>   \
> +    error_propagate(errp, local_err);                                        
>   \
> +}                                                                            
>   \
> +                                                                             
>   \
> +static int                                                                   
>   \
> +glue(_name, _spapr_cpu_core_realize_child)(Object *child, void *opaque)      
>   \
> +{                                                                            
>   \
> +    Error **errp = opaque;                                                   
>   \
> +    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());            
>   \
> +    CPUState *cs = CPU(child);                                               
>   \
> +    PowerPCCPU *cpu = POWERPC_CPU(cs);                                       
>   \
> +                                                                             
>   \
> +    object_property_set_bool(child, true, "realized", errp);                 
>   \
> +    if (*errp) {                                                             
>   \
> +        return 1;                                                            
>   \
> +    }                                                                        
>   \
> +                                                                             
>   \
> +    spapr_cpu_init(spapr, cpu, errp);                                        
>   \
> +    if (*errp) {                                                             
>   \
> +        return 1;                                                            
>   \
> +    }                                                                        
>   \
> +    return 0;                                                                
>   \
> +}                                                                            
>   \
> +                                                                             
>   \
> +static void                                                                  
>   \
> +glue(_name, _spapr_cpu_core_realize)(DeviceState *dev, Error **errp)         
>   \
> +{                                                                            
>   \
> +    sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));                          
>   \
> +    CPUCore *cc = CPU_CORE(OBJECT(dev));                                     
>   \
> +    Error *local_err = NULL;                                                 
>   \
> +                                                                             
>   \
> +    /*                                                                       
>   \
> +     * TODO: This is CPU model specific CPU core's realize routine.          
>   \
> +     * However I am initializing "threads" field of the parent type          
>   \
> +     * sPAPRCPUCore here. Is this ok ? If not I will have make "threads"     
>   \
> +     * part of CPU model specific CPU core type and have different plug()    
>   \
> +     * handlers for each type instead of having a common plug() handler      
>   \
> +     * for all core types.                                                   
>   \
> +     */                                                                      
>   \

Not sure, but there seems to be precedence for descendants of CPUClass
at least. e.g. arm_cpu_realizefn() modifies it's parent CPUState.

But do we even need a model-specific realize? It seems like once
core->cpu is set via the model's instance_init, the same realize /
create_threads functions can be shared by everyone thanks to
object_class_get_name(). So maybe we could move ObjectClass *cpu up into
sPAPRCPUCore, and use a common realize set via spapr_cpu_core_class_init?

If that's doable, we could drop all the macros, or at least limit them
to basically just a model-specific instance_init that sets
sPAPRCPUCore->cpu. You might not even need typedefs for the different
models at that point, since instance_size == sizeof(sPAPRCPUCore) for
everyone at that point. Currently, at least.

In fact, arm_cpu_register_types() seems to do something very similar
for registering TypeInfos for tuples of (model name, init fn).

> +    sc->threads = g_new0(PowerPCCPU, cc->threads);                           
>   \
> +    glue(_name, _spapr_cpu_core_create_threads)(dev, cc->threads, 
> &local_err); \
> +    if (local_err) {                                                         
>   \
> +        goto out;                                                            
>   \
> +    }                                                                        
>   \
> +                                                                             
>   \
> +    object_child_foreach(OBJECT(dev),                                        
>   \
> +                         glue(_name, _spapr_cpu_core_realize_child),         
>   \
> +                         &local_err);                                        
>   \
> +                                                                             
>   \
> +out:                                                                         
>   \
> +    if (local_err) {                                                         
>   \
> +        g_free(sc->threads);                                                 
>   \
> +        error_propagate(errp, local_err);                                    
>   \
> +    }                                                                        
>   \
> +}                                                                            
>   \
> +                                                                             
>   \
> +static void                                                                  
>   \
> +glue(_name, _spapr_cpu_core_instance_init)(Object *obj)                      
>   \
> +{                                                                            
>   \
> +    glue(_name, sPAPRCPUCore) * core = glue(_name, _SPAPR_CPU_CORE)(obj);    
>   \
> +    const char *type = stringify(_name) "-" TYPE_POWERPC_CPU;                
>   \
> +    ObjectClass *oc = object_class_by_name(type);                            
>   \
> +                                                                             
>   \
> +    core->cpu = oc;                                                          
>   \
> +}                                                                            
>   \
> +                                                                             
>   \
> +static void                                                                  
>   \
> +glue(_name, _spapr_cpu_core_class_init)(ObjectClass *oc, void *data)         
>   \
> +{                                                                            
>   \
> +                                                                             
>   \
> +    DeviceClass *dc = DEVICE_CLASS(oc);                                      
>   \
> +    dc->realize = glue(_name, _spapr_cpu_core_realize);                      
>   \
> +}                                                                            
>   \
> +                                                                             
>   \
> +static const TypeInfo glue(_name, _spapr_cpu_core_type_info) =               
>   \
> +{                                                                            
>   \
> +    .name = stringify(_name) "-" TYPE_SPAPR_CPU_CORE,                        
>   \
> +    .parent = TYPE_SPAPR_CPU_CORE,                                           
>   \
> +    .instance_size = sizeof(glue(_name, sPAPRCPUCore)),                      
>   \
> +    .instance_init = glue(_name, _spapr_cpu_core_instance_init),             
>   \
> +    .class_init = glue(_name, _spapr_cpu_core_class_init),                   
>   \
> +};
> +
> +DEFINE_SPAPR_CPU_CORE(host);
> +DEFINE_SPAPR_CPU_CORE(POWER7);
> +DEFINE_SPAPR_CPU_CORE(POWER8);
> +
>  static void spapr_cpu_core_register_types(void)
>  {
>      type_register_static(&spapr_cpu_core_type_info);
> +    type_register_static(&host_spapr_cpu_core_type_info);
> +    type_register_static(&POWER7_spapr_cpu_core_type_info);
> +    type_register_static(&POWER8_spapr_cpu_core_type_info);
>  }
> 
>  type_init(spapr_cpu_core_register_types)
> diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
> index 098d85d..0fdf448 100644
> --- a/include/hw/ppc/spapr.h
> +++ b/include/hw/ppc/spapr.h
> @@ -585,6 +585,7 @@ void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType 
> drc_type,
>                                         uint32_t count);
>  void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type,
>                                            uint32_t count);
> +void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu, Error **errp);
> 
>  /* rtas-configure-connector state */
>  struct sPAPRConfigureConnectorState {
> diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h
> index e3340ea..71e69c0 100644
> --- a/include/hw/ppc/spapr_cpu_core.h
> +++ b/include/hw/ppc/spapr_cpu_core.h
> @@ -24,4 +24,40 @@ typedef struct sPAPRCPUCore {
>      PowerPCCPU *threads;
>  } sPAPRCPUCore;
> 
> +#define TYPE_host_SPAPR_CPU_CORE "host-spapr-cpu-core"
> +#define host_SPAPR_CPU_CORE(obj) \
> +    OBJECT_CHECK(hostsPAPRCPUCore, (obj), TYPE_host_SPAPR_CPU_CORE)
> +
> +typedef struct hostsPAPRCPUCore {
> +    /*< private >*/
> +    sPAPRCPUCore parent_obj;
> +
> +    /*< public >*/
> +    ObjectClass *cpu;
> +} hostsPAPRCPUCore;
> +
> +#define TYPE_POWER7_SPAPR_CPU_CORE "POWER7-spapr-cpu-core"
> +#define POWER7_SPAPR_CPU_CORE(obj) \
> +    OBJECT_CHECK(POWER7sPAPRCPUCore, (obj), TYPE_POWER7_SPAPR_CPU_CORE)
> +
> +typedef struct POWER7sPAPRCPUCore {
> +    /*< private >*/
> +    sPAPRCPUCore parent_obj;
> +
> +    /*< public >*/
> +    ObjectClass *cpu;
> +} POWER7sPAPRCPUCore;
> +
> +#define TYPE_POWER8_SPAPR_CPU_CORE "POWER8-spapr-cpu-core"
> +#define POWER8_SPAPR_CPU_CORE(obj) \
> +    OBJECT_CHECK(POWER8sPAPRCPUCore, (obj), TYPE_POWER8_SPAPR_CPU_CORE)
> +
> +typedef struct POWER8sPAPRCPUCore {
> +    /*< private >*/
> +    sPAPRCPUCore parent_obj;
> +
> +    /*< public >*/
> +    ObjectClass *cpu;
> +} POWER8sPAPRCPUCore;
> +
>  #endif
> -- 
> 2.1.0
> 




reply via email to

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