Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1207474 > unrolled thread

[PATCH v3 2/5] KVM: add KVM_REQ_EXIT request for userspace exit

Started byRadim Krčmář <rkrcmar@redhat.com>
First post2015-08-14 12:20 +0200
Last post2015-08-22 09:10 +0200
Articles 3 — 3 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH v3 2/5] KVM: add KVM_REQ_EXIT request for userspace exit Radim Krčmář <rkrcmar@redhat.com> - 2015-08-14 12:20 +0200
    Re: [PATCH v3 2/5] KVM: add KVM_REQ_EXIT request for userspace exit Wanpeng Li <wanpeng.li@hotmail.com> - 2015-08-20 06:00 +0200
      Re: [PATCH v3 2/5] KVM: add KVM_REQ_EXIT request for userspace exit Paolo Bonzini <pbonzini@redhat.com> - 2015-08-22 09:10 +0200

#1207474 — [PATCH v3 2/5] KVM: add KVM_REQ_EXIT request for userspace exit

FromRadim Krčmář <rkrcmar@redhat.com>
Date2015-08-14 12:20 +0200
Subject[PATCH v3 2/5] KVM: add KVM_REQ_EXIT request for userspace exit
Message-ID<pXkfE-7xK-25@gated-at.bofh.it>
When userspace wants KVM to exit to userspace, it sends a signal.
This has a disadvantage of requiring a change to the signal mask because
the signal needs to be blocked in userspace to stay pending when sending
to self.

Using a request flag allows us to shave 200-300 cycles from every
userspace exit and the speedup grows with NUMA because unblocking
touches shared spinlock.

The disadvantage is that it adds an overhead of one bit check for all
kernel exits.  A quick tracing shows that the ratio of userspace exits
after boot is about 1/5 and in subsequent run of nmap and kernel compile
has about 1/60, so the check should not regress global performance.

All signal_pending() calls are userspace exit requests, so we add a
check for KVM_REQ_EXIT there.  There is one omitted call in kvm_vcpu_run
because KVM_REQ_EXIT is implied in earlier check for requests.

Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
---
 arch/x86/kvm/vmx.c       | 2 +-
 arch/x86/kvm/x86.c       | 6 ++++++
 include/linux/kvm_host.h | 8 +++++++-
 include/uapi/linux/kvm.h | 1 +
 virt/kvm/kvm_main.c      | 2 +-
 5 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 40c6180a0ecb..2b789a869ef5 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -5833,7 +5833,7 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
 			goto out;
 		}
 
-		if (signal_pending(current))
+		if (kvm_need_exit(vcpu))
 			goto out;
 		if (need_resched())
 			schedule();
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e5850076bf7b..c3df7733af09 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6548,6 +6548,11 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
 			++vcpu->stat.signal_exits;
 			break;
 		}
+		if (unlikely(kvm_has_request(KVM_REQ_EXIT, vcpu))) {
+			r = 0;
+			vcpu->run->exit_reason = KVM_EXIT_REQUEST;
+			break;
+		}
 		if (need_resched()) {
 			srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
 			cond_resched();
@@ -6684,6 +6689,7 @@ out:
 	post_kvm_run_save(vcpu);
 	if (vcpu->sigset_active)
 		sigprocmask(SIG_SETMASK, &sigsaved, NULL);
+	clear_bit(KVM_REQ_EXIT, &vcpu->requests);
 
 	return r;
 }
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 52e388367a26..dcc57171e3ec 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -121,7 +121,7 @@ static inline bool is_error_page(struct page *page)
 #define KVM_REQ_UNHALT             6
 #define KVM_REQ_MMU_SYNC           7
 #define KVM_REQ_CLOCK_UPDATE       8
-#define KVM_REQ_KICK               9
+#define KVM_REQ_EXIT               9
 #define KVM_REQ_DEACTIVATE_FPU    10
 #define KVM_REQ_EVENT             11
 #define KVM_REQ_APF_HALT          12
@@ -1104,6 +1104,12 @@ static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
 	}
 }
 
+static inline bool kvm_need_exit(struct kvm_vcpu *vcpu)
+{
+	return signal_pending(current) ||
+	       kvm_has_request(KVM_REQ_EXIT, vcpu);
+}
+
 extern bool kvm_rebooting;
 
 struct kvm_device {
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 26daafbba9ec..d996a7cdb4d2 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -184,6 +184,7 @@ struct kvm_s390_skeys {
 #define KVM_EXIT_SYSTEM_EVENT     24
 #define KVM_EXIT_S390_STSI        25
 #define KVM_EXIT_IOAPIC_EOI       26
+#define KVM_EXIT_REQUEST          27
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index d8db2f8fce9c..347899966178 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1914,7 +1914,7 @@ static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
 	}
 	if (kvm_cpu_has_pending_timer(vcpu))
 		return -EINTR;
-	if (signal_pending(current))
+	if (kvm_need_exit(vcpu))
 		return -EINTR;
 
 	return 0;
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1210129

FromWanpeng Li <wanpeng.li@hotmail.com>
Date2015-08-20 06:00 +0200
Message-ID<pZpbb-1nR-1@gated-at.bofh.it>
In reply to#1207474
On 8/14/15 6:08 PM, Radim Krčmář wrote:
> When userspace wants KVM to exit to userspace, it sends a signal.
> This has a disadvantage of requiring a change to the signal mask because
> the signal needs to be blocked in userspace to stay pending when sending
> to self.
>
> Using a request flag allows us to shave 200-300 cycles from every
> userspace exit and the speedup grows with NUMA because unblocking
> touches shared spinlock.
>
> The disadvantage is that it adds an overhead of one bit check for all
> kernel exits.  A quick tracing shows that the ratio of userspace exits
> after boot is about 1/5 and in subsequent run of nmap and kernel compile
> has about 1/60, so the check should not regress global performance.
>
> All signal_pending() calls are userspace exit requests, so we add a
> check for KVM_REQ_EXIT there.  There is one omitted call in kvm_vcpu_run
> because KVM_REQ_EXIT is implied in earlier check for requests.

Actually I see more SIGUSR1 signals are intercepted by signal_pending() 
in vcpu_enter_guest() and vcpu_run() w/ win7 guest and kernel_irqchip=off.

Regards,
Wanpeng Li

>
> Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
> ---
>   arch/x86/kvm/vmx.c       | 2 +-
>   arch/x86/kvm/x86.c       | 6 ++++++
>   include/linux/kvm_host.h | 8 +++++++-
>   include/uapi/linux/kvm.h | 1 +
>   virt/kvm/kvm_main.c      | 2 +-
>   5 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> index 40c6180a0ecb..2b789a869ef5 100644
> --- a/arch/x86/kvm/vmx.c
> +++ b/arch/x86/kvm/vmx.c
> @@ -5833,7 +5833,7 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu)
>   			goto out;
>   		}
>   
> -		if (signal_pending(current))
> +		if (kvm_need_exit(vcpu))
>   			goto out;
>   		if (need_resched())
>   			schedule();
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index e5850076bf7b..c3df7733af09 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -6548,6 +6548,11 @@ static int vcpu_run(struct kvm_vcpu *vcpu)
>   			++vcpu->stat.signal_exits;
>   			break;
>   		}
> +		if (unlikely(kvm_has_request(KVM_REQ_EXIT, vcpu))) {
> +			r = 0;
> +			vcpu->run->exit_reason = KVM_EXIT_REQUEST;
> +			break;
> +		}
>   		if (need_resched()) {
>   			srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx);
>   			cond_resched();
> @@ -6684,6 +6689,7 @@ out:
>   	post_kvm_run_save(vcpu);
>   	if (vcpu->sigset_active)
>   		sigprocmask(SIG_SETMASK, &sigsaved, NULL);
> +	clear_bit(KVM_REQ_EXIT, &vcpu->requests);
>   
>   	return r;
>   }
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 52e388367a26..dcc57171e3ec 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -121,7 +121,7 @@ static inline bool is_error_page(struct page *page)
>   #define KVM_REQ_UNHALT             6
>   #define KVM_REQ_MMU_SYNC           7
>   #define KVM_REQ_CLOCK_UPDATE       8
> -#define KVM_REQ_KICK               9
> +#define KVM_REQ_EXIT               9
>   #define KVM_REQ_DEACTIVATE_FPU    10
>   #define KVM_REQ_EVENT             11
>   #define KVM_REQ_APF_HALT          12
> @@ -1104,6 +1104,12 @@ static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
>   	}
>   }
>   
> +static inline bool kvm_need_exit(struct kvm_vcpu *vcpu)
> +{
> +	return signal_pending(current) ||
> +	       kvm_has_request(KVM_REQ_EXIT, vcpu);
> +}
> +
>   extern bool kvm_rebooting;
>   
>   struct kvm_device {
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index 26daafbba9ec..d996a7cdb4d2 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -184,6 +184,7 @@ struct kvm_s390_skeys {
>   #define KVM_EXIT_SYSTEM_EVENT     24
>   #define KVM_EXIT_S390_STSI        25
>   #define KVM_EXIT_IOAPIC_EOI       26
> +#define KVM_EXIT_REQUEST          27
>   
>   /* For KVM_EXIT_INTERNAL_ERROR */
>   /* Emulate instruction failed. */
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index d8db2f8fce9c..347899966178 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -1914,7 +1914,7 @@ static int kvm_vcpu_check_block(struct kvm_vcpu *vcpu)
>   	}
>   	if (kvm_cpu_has_pending_timer(vcpu))
>   		return -EINTR;
> -	if (signal_pending(current))
> +	if (kvm_need_exit(vcpu))
>   		return -EINTR;
>   
>   	return 0;

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1211413

FromPaolo Bonzini <pbonzini@redhat.com>
Date2015-08-22 09:10 +0200
Message-ID<q0b6a-3oF-3@gated-at.bofh.it>
In reply to#1210129

On 19/08/2015 20:55, Wanpeng Li wrote:
>> The disadvantage is that it adds an overhead of one bit check for all
>> kernel exits.  A quick tracing shows that the ratio of userspace exits
>> after boot is about 1/5 and in subsequent run of nmap and kernel compile
>> has about 1/60, so the check should not regress global performance.
>>
>> All signal_pending() calls are userspace exit requests, so we add a
>> check for KVM_REQ_EXIT there.  There is one omitted call in kvm_vcpu_run
>> because KVM_REQ_EXIT is implied in earlier check for requests.
> 
> Actually I see more SIGUSR1 signals are intercepted by signal_pending()
> in vcpu_enter_guest() and vcpu_run() w/ win7 guest and kernel_irqchip=off.

You need more patches on the QEMU side.  I tested a version that is
mostly okay but not ready for upstream inclusion.

Paolo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web