diff mbox

[RFC,v4,04/11] cpus: Add a sync version of cpu_remove()

Message ID 1438838837-28504-5-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
This sync API will be used by the CPU hotplug code to wait for the CPU to
completely get removed before flagging the failure to the device_add
command.

Sync version of this call is needed to correctly recover from CPU
realization failures when ->plug() handler fails.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
 cpus.c            | 14 ++++++++++++++
 include/qom/cpu.h |  8 ++++++++
 2 files changed, 22 insertions(+)

Comments

David Gibson Sept. 4, 2015, 6:11 a.m. UTC | #1
On Thu, Aug 06, 2015 at 10:57:10AM +0530, Bharata B Rao wrote:
> This sync API will be used by the CPU hotplug code to wait for the CPU to
> completely get removed before flagging the failure to the device_add
> command.
> 
> Sync version of this call is needed to correctly recover from CPU
> realization failures when ->plug() handler fails.
> 
> Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
> ---
>  cpus.c            | 14 ++++++++++++++
>  include/qom/cpu.h |  8 ++++++++
>  2 files changed, 22 insertions(+)
> 
> diff --git a/cpus.c b/cpus.c
> index 73ae2e7..9d9644e 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -999,6 +999,8 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
>          qemu_kvm_wait_io_event(cpu);
>          if (cpu->exit && !cpu_can_run(cpu)) {
>              qemu_kvm_destroy_vcpu(cpu);
> +            cpu->created = false;
> +            qemu_cond_signal(&qemu_cpu_cond);
>              qemu_mutex_unlock(&qemu_global_mutex);
>              return NULL;
>          }
> @@ -1104,6 +1106,8 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
>          }
>          if (remove_cpu) {
>              qemu_tcg_destroy_vcpu(remove_cpu);
> +            cpu->created = false;
> +            qemu_cond_signal(&qemu_cpu_cond);
>              remove_cpu = NULL;
>          }
>      }
> @@ -1283,6 +1287,16 @@ void cpu_remove(CPUState *cpu)
>      qemu_cpu_kick(cpu);
>  }
>  
> +void cpu_remove_sync(CPUState *cpu)
> +{
> +    cpu->stop = true;
> +    cpu->exit = true;
> +    qemu_cpu_kick(cpu);

It would be nicer for this to call the async cpu_remove() above, to
ensure they stay in sync.

> +    while (cpu->created) {
> +        qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
> +    }
> +}
> +
>  /* For temporary buffers for forming a name */
>  #define VCPU_THREAD_NAME_SIZE 16
>  
> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
> index 136d9fe..65c6852 100644
> --- a/include/qom/cpu.h
> +++ b/include/qom/cpu.h
> @@ -655,6 +655,14 @@ void cpu_resume(CPUState *cpu);
>   */
>  void cpu_remove(CPUState *cpu);
>  
> + /**
> + * cpu_remove_sync:
> + * @cpu: The CPU to remove.
> + *
> + * Requests the CPU to be removed and waits till it is removed.
> + */
> +void cpu_remove_sync(CPUState *cpu);
> +
>  /**
>   * qemu_init_vcpu:
>   * @cpu: The vCPU to initialize.
Bharata B Rao Sept. 9, 2015, 5:57 a.m. UTC | #2
On Fri, Sep 04, 2015 at 04:11:38PM +1000, David Gibson wrote:
> On Thu, Aug 06, 2015 at 10:57:10AM +0530, Bharata B Rao wrote:
> > This sync API will be used by the CPU hotplug code to wait for the CPU to
> > completely get removed before flagging the failure to the device_add
> > command.
> > 
> > Sync version of this call is needed to correctly recover from CPU
> > realization failures when ->plug() handler fails.
> > 
> > Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
> > ---
> >  cpus.c            | 14 ++++++++++++++
> >  include/qom/cpu.h |  8 ++++++++
> >  2 files changed, 22 insertions(+)
> > 
> > diff --git a/cpus.c b/cpus.c
> > index 73ae2e7..9d9644e 100644
> > --- a/cpus.c
> > +++ b/cpus.c
> > @@ -999,6 +999,8 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
> >          qemu_kvm_wait_io_event(cpu);
> >          if (cpu->exit && !cpu_can_run(cpu)) {
> >              qemu_kvm_destroy_vcpu(cpu);
> > +            cpu->created = false;
> > +            qemu_cond_signal(&qemu_cpu_cond);
> >              qemu_mutex_unlock(&qemu_global_mutex);
> >              return NULL;
> >          }
> > @@ -1104,6 +1106,8 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
> >          }
> >          if (remove_cpu) {
> >              qemu_tcg_destroy_vcpu(remove_cpu);
> > +            cpu->created = false;
> > +            qemu_cond_signal(&qemu_cpu_cond);
> >              remove_cpu = NULL;
> >          }
> >      }
> > @@ -1283,6 +1287,16 @@ void cpu_remove(CPUState *cpu)
> >      qemu_cpu_kick(cpu);
> >  }
> >  
> > +void cpu_remove_sync(CPUState *cpu)
> > +{
> > +    cpu->stop = true;
> > +    cpu->exit = true;
> > +    qemu_cpu_kick(cpu);
> 
> It would be nicer for this to call the async cpu_remove() above, to
> ensure they stay in sync.

Makes sense, will incorporate this in the next iteration.

Regards,
Bharata.
diff mbox

Patch

diff --git a/cpus.c b/cpus.c
index 73ae2e7..9d9644e 100644
--- a/cpus.c
+++ b/cpus.c
@@ -999,6 +999,8 @@  static void *qemu_kvm_cpu_thread_fn(void *arg)
         qemu_kvm_wait_io_event(cpu);
         if (cpu->exit && !cpu_can_run(cpu)) {
             qemu_kvm_destroy_vcpu(cpu);
+            cpu->created = false;
+            qemu_cond_signal(&qemu_cpu_cond);
             qemu_mutex_unlock(&qemu_global_mutex);
             return NULL;
         }
@@ -1104,6 +1106,8 @@  static void *qemu_tcg_cpu_thread_fn(void *arg)
         }
         if (remove_cpu) {
             qemu_tcg_destroy_vcpu(remove_cpu);
+            cpu->created = false;
+            qemu_cond_signal(&qemu_cpu_cond);
             remove_cpu = NULL;
         }
     }
@@ -1283,6 +1287,16 @@  void cpu_remove(CPUState *cpu)
     qemu_cpu_kick(cpu);
 }
 
+void cpu_remove_sync(CPUState *cpu)
+{
+    cpu->stop = true;
+    cpu->exit = true;
+    qemu_cpu_kick(cpu);
+    while (cpu->created) {
+        qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
+    }
+}
+
 /* For temporary buffers for forming a name */
 #define VCPU_THREAD_NAME_SIZE 16
 
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 136d9fe..65c6852 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -655,6 +655,14 @@  void cpu_resume(CPUState *cpu);
  */
 void cpu_remove(CPUState *cpu);
 
+ /**
+ * cpu_remove_sync:
+ * @cpu: The CPU to remove.
+ *
+ * Requests the CPU to be removed and waits till it is removed.
+ */
+void cpu_remove_sync(CPUState *cpu);
+
 /**
  * qemu_init_vcpu:
  * @cpu: The vCPU to initialize.