qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH RFC qom-cpu-next 1/6] cpu: Register VMStateDescr


From: Andreas Färber
Subject: Re: [Qemu-devel] [PATCH RFC qom-cpu-next 1/6] cpu: Register VMStateDescription through CPUState
Date: Thu, 07 Feb 2013 19:02:32 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130105 Thunderbird/17.0.2

Am 07.02.2013 18:46, schrieb Eduardo Habkost:
> On Thu, Feb 07, 2013 at 06:20:52PM +0100, Andreas Färber wrote:
>> Am 07.02.2013 17:40, schrieb Eduardo Habkost:
>>> On Sat, Feb 02, 2013 at 04:04:11PM +0100, Andreas Färber wrote:
>>>> In comparison to DeviceClass::vmsd, CPU VMState is split in two,
>>>> "cpu_common" and "cpu", and uses cpu_index as instance_id instead of -1.
>>>> Therefore add a CPU-specific CPUClass::vmsd field.
>>>>
>>>> Unlike the legacy CPUArchState registration, rather register CPUState.
>>>>
>>>> Signed-off-by: Juan Quintela <address@hidden>
>>>> Signed-off-by: Andreas Färber <address@hidden>
>>>> ---
>>>>  exec.c            |   13 +++++++++++--
>>>>  include/qom/cpu.h |    3 +++
>>>>  2 Dateien geändert, 14 Zeilen hinzugefügt(+), 2 Zeilen entfernt(-)
>>>>
>>>> diff --git a/exec.c b/exec.c
>>>> index b85508b..5eee174 100644
>>>> --- a/exec.c
>>>> +++ b/exec.c
>>>> @@ -219,7 +219,7 @@ void cpu_exec_init_all(void)
>>>>  #endif
>>>>  }
>>>>  
>>>> -#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
>>>> +#if !defined(CONFIG_USER_ONLY)
>>>>  
>>>>  static int cpu_common_post_load(void *opaque, int version_id)
>>>>  {
>>>> @@ -266,6 +266,9 @@ CPUState *qemu_get_cpu(int index)
>>>>  void cpu_exec_init(CPUArchState *env)
>>>>  {
>>>>      CPUState *cpu = ENV_GET_CPU(env);
>>>> +#if !defined(CONFIG_USER_ONLY) && !defined(CPU_SAVE_VERSION)
>>>> +    CPUClass *cc = CPU_GET_CLASS(cpu);
>>>> +#endif
>>>>      CPUArchState **penv;
>>>>      int cpu_index;
>>>>  
>>>> @@ -290,10 +293,16 @@ void cpu_exec_init(CPUArchState *env)
>>>>  #if defined(CONFIG_USER_ONLY)
>>>>      cpu_list_unlock();
>>>>  #endif
>>>> -#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
>>>> +#if !defined(CONFIG_USER_ONLY)
>>>>      vmstate_register(NULL, cpu_index, &vmstate_cpu_common, env);
>>>> +#if defined(CPU_SAVE_VERSION)
>>>>      register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
>>>>                      cpu_save, cpu_load, env);
>>>
>>> What about introducing stub register_savevm() function in libqemustub.a,
>>> so we can eliminate the CONFIG_USER_ONLY ifdefs?
>>>
>>> (we already have vmstate_register()/vmstate_unregister() stubs).
>>
>> register_savevm() itself is not the issue, it's the VMStateDescription
>> itself with all its external references that would be quite some (IMO
>> useless) work to make available to *-user...
> 
> Are you talking about the VMStateDescription struct declaration, or
> about actually setting the vmsd field?

I'm talking about, e.g., #include "machine.c", i.e. VMStateDescription
vmstate_something = { ... }; something_else = &vmstate_something;.

This broke horribly.

> The struct declaration is available even if CONFIG_USER_ONLY is set. See
> qdev.c. It doesn't have any #ifdefs around
> vmstate_register()/vmstate_unregister() calls.
> 
> I don't suggest we set the field to non-NULL if CONFIG_USER_ONLY is set
> (that would be difficult and unnecessary).

That's what I was saying, yes.

>>>> +#else
>>>
>>> Do we have any architecture that sets CPU_SAVE_VERSION _and_ sets
>>> cc->vmsd at the same time? If not, we could put the "if (cc->vmsd)
>>> vmstate_register()" part outside any #ifdef/#else block.
>>
>> They shouldn't. When this series and any follow-up by Juan himself were
>> applied, there would be no more CPU_SAVE_VERSION and all CPUs would
>> register a vmsd one way or another. Targets to be converted include ppc,
>> arm and sparc.
>>
>> Together with the final RFC patch in this series, doing it inside an
>> #else block avoids repeating the lax checks that have led alpha,
>> openrisc and a few others to not register things correctly.
> 
> What exactly were the lax checks that have led them to not register
> things correctly?

In short: Lack of patch 6.

!defined(CPU_SAVE_VERSION) but implementing cpu_save/load when they
should've #define'd CPU_SAVE_VERSION.

In turn I want to assure that when !defined(CPU_SAVE_VERSION)
implementing cpu_save/load leads to build error.

> Would my suggestion below cause the same problems?
> 
>> This is the
>> part of the patch that I adopted from Juan. I don't insist though.
> 
> I am OK with "#ifdef CPU_SAVE_VERSION" #ifdef because it is for legacy
> code (and should be temporary, right?), but I think we can easily drop
> the #ifdefs around all the other lines. I mean, we can easily make the
> code look like this:
> 
> void cpu_exec_init(CPUArchState *env)
> {
>     CPUState *cpu = ENV_GET_CPU(env);
>     CPUClass *cc = CPU_GET_CLASS(cpu);
>     [...]
> 
>     vmstate_register(NULL, cpu_index, &vmstate_cpu_common, env);

&vmstate_cpu_common will break for linux-user.

> #if defined(CPU_SAVE_VERSION)
>     register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
>                      cpu_save, cpu_load, env);
> #endif
>     if (cc->vmsd) {
>         vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
>     }
> }
> 
> If we want to catch architectures that don't set CPU_SAVE_VERSION but
> also don't register any vmsd (is this the bug you are trying to catch?),
> we could do this:
> 
> #if defined(CPU_SAVE_VERSION)
>     register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
>                      cpu_save, cpu_load, env);
> #elif !defined(CONFIG_USER_ONLY)
>     assert(cc->vmsd);

We would need to leave out the #elif and assert cc->vmsd == NULL, but
then it would address my concern, yes.

!defined(CPU_SAVE_VERSION) => cc->vmsd != NULL is not guaranteed:
For 1.4 some unmigratable CPUs register via dc->vmsd instead.

Regards,
Andreas

> #endif
>     if (cc->vmsd) {
>         vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
>     }
> 
> 
>>
>> Regards,
>> Andreas
>>
>>>> +    if (cc->vmsd != NULL) {
>>>> +        vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
>>>> +    }
>>>> +#endif
>>>>  #endif
>>>>  }
>>>>  
>>>> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
>>>> index 46f2247..b870752 100644
>>>> --- a/include/qom/cpu.h
>>>> +++ b/include/qom/cpu.h
>>>> @@ -43,6 +43,7 @@ typedef struct CPUState CPUState;
>>>>   * @class_by_name: Callback to map -cpu command line model name to an
>>>>   * instantiatable CPU type.
>>>>   * @reset: Callback to reset the #CPUState to its initial state.
>>>> + * @vmsd: State description for migration.
>>>>   *
>>>>   * Represents a CPU family or model.
>>>>   */
>>>> @@ -54,6 +55,8 @@ typedef struct CPUClass {
>>>>      ObjectClass *(*class_by_name)(const char *cpu_model);
>>>>  
>>>>      void (*reset)(CPUState *cpu);
>>>> +
>>>> +    const struct VMStateDescription *vmsd;
>>>>  } CPUClass;
>>>>  
>>>>  struct KVMState;
>>>> -- 
>>>> 1.7.10.4
>>
>> -- 
>> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
>> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg



reply via email to

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