KVM: keep track of which task is running a KVM vcpu
authorRik van Riel <riel@redhat.com>
Tue, 1 Feb 2011 14:52:41 +0000 (09:52 -0500)
committerMarcelo Tosatti <mtosatti@redhat.com>
Thu, 17 Mar 2011 16:08:29 +0000 (13:08 -0300)
Keep track of which task is running a KVM vcpu.  This helps us
figure out later what task to wake up if we want to boost a
vcpu that got preempted.

Unfortunately there are no guarantees that the same task
always keeps the same vcpu, so we can only track the task
across a single "run" of the vcpu.

Signed-off-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
include/linux/kvm_host.h
virt/kvm/kvm_main.c

index c8dee22b19459a0fc3ef67c05c951dd9526ee2be..4721b11b922a6e66a57f853173cd70038ef1b770 100644 (file)
@@ -122,6 +122,7 @@ struct kvm_vcpu {
        int fpu_active;
        int guest_fpu_loaded, guest_xcr0_loaded;
        wait_queue_head_t wq;
+       struct pid *pid;
        int sigset_active;
        sigset_t sigset;
        struct kvm_vcpu_stat stat;
index 002fe0b12c9f86778c87b0f96b262e6f85039dbe..bc8bfd15ab716413de25e5d5dac18f673dc98441 100644 (file)
@@ -137,6 +137,14 @@ void vcpu_load(struct kvm_vcpu *vcpu)
        int cpu;
 
        mutex_lock(&vcpu->mutex);
+       if (unlikely(vcpu->pid != current->pids[PIDTYPE_PID].pid)) {
+               /* The thread running this VCPU changed. */
+               struct pid *oldpid = vcpu->pid;
+               struct pid *newpid = get_task_pid(current, PIDTYPE_PID);
+               rcu_assign_pointer(vcpu->pid, newpid);
+               synchronize_rcu();
+               put_pid(oldpid);
+       }
        cpu = get_cpu();
        preempt_notifier_register(&vcpu->preempt_notifier);
        kvm_arch_vcpu_load(vcpu, cpu);
@@ -212,6 +220,7 @@ int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
        vcpu->cpu = -1;
        vcpu->kvm = kvm;
        vcpu->vcpu_id = id;
+       vcpu->pid = NULL;
        init_waitqueue_head(&vcpu->wq);
        kvm_async_pf_vcpu_init(vcpu);
 
@@ -236,6 +245,7 @@ EXPORT_SYMBOL_GPL(kvm_vcpu_init);
 
 void kvm_vcpu_uninit(struct kvm_vcpu *vcpu)
 {
+       put_pid(vcpu->pid);
        kvm_arch_vcpu_uninit(vcpu);
        free_page((unsigned long)vcpu->run);
 }