diff mbox

[RFC,v4,02/11] exec: Do vmstate unregistration from cpu_exec_exit()

Message ID 1438838837-28504-3-git-send-email-bharata@linux.vnet.ibm.com
State New
Headers show

Commit Message

Bharata B Rao Aug. 6, 2015, 5:27 a.m. UTC
cpu_exec_init() does vmstate_register and register_savevm for the CPU device.
These need to be undone from cpu_exec_exit(). These changes are needed to
support CPU hot removal and also to correctly fail hotplug attempts
beyond max_cpus.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 exec.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

Comments

David Gibson Sept. 4, 2015, 6:03 a.m. UTC | #1
On Thu, Aug 06, 2015 at 10:57:08AM +0530, Bharata B Rao wrote:
> cpu_exec_init() does vmstate_register and register_savevm for the CPU device.
> These need to be undone from cpu_exec_exit(). These changes are needed to
> support CPU hot removal and also to correctly fail hotplug attempts
> beyond max_cpus.
> 
> Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>

As with 1/2, looks reasonable, but I'm wondering how x86 hotplug is
getting away without this.

> ---
>  exec.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/exec.c b/exec.c
> index b196d68..3415cd7 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -545,6 +545,8 @@ static int cpu_get_free_index(Error **errp)
>  
>  void cpu_exec_exit(CPUState *cpu)
>  {
> +    CPUClass *cc = CPU_GET_CLASS(cpu);
> +
>      if (cpu->cpu_index == -1) {
>          /* cpu_index was never allocated by this @cpu or was already freed. */
>          return;
> @@ -556,6 +558,15 @@ void cpu_exec_exit(CPUState *cpu)
>      }
>      bitmap_clear(cpu_index_map, cpu->cpu_index, 1);
>      cpu->cpu_index = -1;
> +    if (cc->vmsd != NULL) {
> +        vmstate_unregister(NULL, cc->vmsd, cpu);
> +    }
> +#if defined(CPU_SAVE_VERSION)
> +    unregister_savevm(NULL, "cpu", cpu->env_ptr);
> +#endif
> +    if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
> +        vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
> +    }
>  }
>  #else
>  
> @@ -572,12 +583,20 @@ static int cpu_get_free_index(Error **errp)
>  
>  void cpu_exec_exit(CPUState *cpu)
>  {
> +    CPUClass *cc = CPU_GET_CLASS(cpu);
> +
>      cpu_list_lock();
>      if (cpu->queued) {
>          QTAILQ_REMOVE(&cpus, cpu, node);
>          cpu->queued = false;
>      }
>      cpu_list_unlock();
> +    if (cc->vmsd != NULL) {
> +        vmstate_unregister(NULL, cc->vmsd, cpu);
> +    }
> +    if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
> +        vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
> +    }
>  }
>  #endif
>
Bharata B Rao Sept. 9, 2015, 5:56 a.m. UTC | #2
On Fri, Sep 04, 2015 at 04:03:43PM +1000, David Gibson wrote:
> On Thu, Aug 06, 2015 at 10:57:08AM +0530, Bharata B Rao wrote:
> > cpu_exec_init() does vmstate_register and register_savevm for the CPU device.
> > These need to be undone from cpu_exec_exit(). These changes are needed to
> > support CPU hot removal and also to correctly fail hotplug attempts
> > beyond max_cpus.
> > 
> > Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
> 
> As with 1/2, looks reasonable, but I'm wondering how x86 hotplug is
> getting away without this.

x86 does this explicitly in CPU's unrealizefn. Since registration is
done from cpu_exec_init(), I though un-registration could be done
in cpu_exec_init() instead of each arch doing it separately.

As said earlier, I will probably pursue these changes separately from
this series.

Regards,
Bharata.
diff mbox

Patch

diff --git a/exec.c b/exec.c
index b196d68..3415cd7 100644
--- a/exec.c
+++ b/exec.c
@@ -545,6 +545,8 @@  static int cpu_get_free_index(Error **errp)
 
 void cpu_exec_exit(CPUState *cpu)
 {
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
     if (cpu->cpu_index == -1) {
         /* cpu_index was never allocated by this @cpu or was already freed. */
         return;
@@ -556,6 +558,15 @@  void cpu_exec_exit(CPUState *cpu)
     }
     bitmap_clear(cpu_index_map, cpu->cpu_index, 1);
     cpu->cpu_index = -1;
+    if (cc->vmsd != NULL) {
+        vmstate_unregister(NULL, cc->vmsd, cpu);
+    }
+#if defined(CPU_SAVE_VERSION)
+    unregister_savevm(NULL, "cpu", cpu->env_ptr);
+#endif
+    if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
+        vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
+    }
 }
 #else
 
@@ -572,12 +583,20 @@  static int cpu_get_free_index(Error **errp)
 
 void cpu_exec_exit(CPUState *cpu)
 {
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
     cpu_list_lock();
     if (cpu->queued) {
         QTAILQ_REMOVE(&cpus, cpu, node);
         cpu->queued = false;
     }
     cpu_list_unlock();
+    if (cc->vmsd != NULL) {
+        vmstate_unregister(NULL, cc->vmsd, cpu);
+    }
+    if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
+        vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
+    }
 }
 #endif