]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm tools: Exit properly on SMP guests
authorSasha Levin <levinsasha928@gmail.com>
Thu, 19 May 2011 12:28:30 +0000 (15:28 +0300)
committerPekka Enberg <penberg@kernel.org>
Thu, 19 May 2011 19:11:20 +0000 (22:11 +0300)
When shutting down SMP guests only VCPU #0 will receive
a KVM_EXIT_SHUTDOWN. Waiting for all VCPU threads to exit
causes them to hang.

Instead, notify all VCPU threads once VCPU #0 thread is terminated
so they could also stop properly.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
tools/kvm/include/kvm/kvm.h
tools/kvm/kvm-cpu.c
tools/kvm/kvm-run.c

index d9943bf7db684bd960f84648dca51b187a3ab6f1..3cf6e6c584bf97d85de778fd0b968e602090ef57 100644 (file)
@@ -11,6 +11,8 @@
 #define KVM_32BIT_GAP_SIZE     (512 << 20)
 #define KVM_32BIT_GAP_START    ((1ULL << 32) - KVM_32BIT_GAP_SIZE)
 
+#define SIGKVMEXIT             (SIGUSR1 + 2)
+
 struct kvm {
        int                     sys_fd;         /* For system ioctls(), i.e. /dev/kvm */
        int                     vm_fd;          /* For VM ioctls() */
index cdfeb8551fc0189fa01de2e7f0852083dd6e46cd..331e02517cc5d2be8500357168705133cbdd4439 100644 (file)
@@ -379,6 +379,11 @@ void kvm_cpu__run(struct kvm_cpu *vcpu)
                die_perror("KVM_RUN failed");
 }
 
+static void kvm_cpu_exit_handler(int signum)
+{
+       /* Don't do anything here */
+}
+
 int kvm_cpu__start(struct kvm_cpu *cpu)
 {
        sigset_t sigset;
@@ -388,6 +393,8 @@ int kvm_cpu__start(struct kvm_cpu *cpu)
 
        pthread_sigmask(SIG_BLOCK, &sigset, NULL);
 
+       signal(SIGKVMEXIT, kvm_cpu_exit_handler);
+
        kvm_cpu__setup_cpuid(cpu);
        kvm_cpu__reset_vcpu(cpu);
 
@@ -430,7 +437,11 @@ int kvm_cpu__start(struct kvm_cpu *cpu)
                        break;
                }
                case KVM_EXIT_INTR:
-                       break;
+                       /*
+                        * Currently we only handle exit signal, which means
+                        * we just exit if KVM_RUN exited due to a signal.
+                        */
+                       goto exit_kvm;
                case KVM_EXIT_SHUTDOWN:
                        goto exit_kvm;
                default:
index 63181bf78955694a48a5ca8a57471060f080dce4..8379a52b7688c1a30969e7d321027087e15fc65e 100644 (file)
@@ -404,6 +404,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
        int max_cpus;
        char *hi;
        int i;
+       void *ret;
 
        signal(SIGALRM, handle_sigalrm);
        signal(SIGQUIT, handle_sigquit);
@@ -583,14 +584,17 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix)
                        die("unable to create KVM VCPU thread");
        }
 
-       for (i = 0; i < nrcpus; i++) {
-               void *ret;
+       /* Only VCPU #0 is going to exit by itself when shutting down */
+       if (pthread_join(kvm_cpus[0]->thread, &ret) != 0)
+               exit_code = 1;
 
+       for (i = 1; i < nrcpus; i++) {
+               pthread_kill(kvm_cpus[i]->thread, SIGKVMEXIT);
                if (pthread_join(kvm_cpus[i]->thread, &ret) != 0)
                        die("pthread_join");
 
                if (ret != NULL)
-                       exit_code       = 1;
+                       exit_code = 1;
        }
 
        kvm__delete(kvm);