mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Andrew Theurer <habanero@linux.vnet.ibm.com>
To: Gleb Natapov <gleb@redhat.com>
Cc: Andrew Jones <drjones@redhat.com>,
	Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>,
	mingo@redhat.com, jeremy@goop.org, x86@kernel.org,
	konrad.wilk@oracle.com, hpa@zytor.com, pbonzini@redhat.com,
	linux-doc@vger.kernel.org, xen-devel@lists.xensource.com,
	peterz@infradead.org, mtosatti@redhat.com,
	stefano.stabellini@eu.citrix.com, andi@firstfloor.org,
	attilio.rao@citrix.com, ouyang@cs.pitt.edu, gregkh@suse.de,
	agraf@suse.de, chegu_vinod@hp.com, torvalds@linux-foundation.org,
	avi.kivity@gmail.com, tglx@linutronix.de, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, stephan.diestelhorst@amd.com,
	riel@redhat.com, virtualization@lists.linux-foundation.org,
	srivatsa.vaddagiri@gmail.com
Subject: Re: [PATCH RFC V9 0/19] Paravirtualized ticket spinlocks
Date: Wed, 26 Jun 2013 10:56:53 -0500	[thread overview]
Message-ID: <1372262213.31391.176.camel@oc6622382223.ibm.com> (raw)
In-Reply-To: <20130626125240.GY18508@redhat.com>

On Wed, 2013-06-26 at 15:52 +0300, Gleb Natapov wrote:
> On Wed, Jun 26, 2013 at 01:37:45PM +0200, Andrew Jones wrote:
> > On Wed, Jun 26, 2013 at 02:15:26PM +0530, Raghavendra K T wrote:
> > > On 06/25/2013 08:20 PM, Andrew Theurer wrote:
> > > >On Sun, 2013-06-02 at 00:51 +0530, Raghavendra K T wrote:
> > > >>This series replaces the existing paravirtualized spinlock mechanism
> > > >>with a paravirtualized ticketlock mechanism. The series provides
> > > >>implementation for both Xen and KVM.
> > > >>
> > > >>Changes in V9:
> > > >>- Changed spin_threshold to 32k to avoid excess halt exits that are
> > > >>    causing undercommit degradation (after PLE handler improvement).
> > > >>- Added  kvm_irq_delivery_to_apic (suggested by Gleb)
> > > >>- Optimized halt exit path to use PLE handler
> > > >>
> > > >>V8 of PVspinlock was posted last year. After Avi's suggestions to look
> > > >>at PLE handler's improvements, various optimizations in PLE handling
> > > >>have been tried.
> > > >
> > > >Sorry for not posting this sooner.  I have tested the v9 pv-ticketlock
> > > >patches in 1x and 2x over-commit with 10-vcpu and 20-vcpu VMs.  I have
> > > >tested these patches with and without PLE, as PLE is still not scalable
> > > >with large VMs.
> > > >
> > > 
> > > Hi Andrew,
> > > 
> > > Thanks for testing.
> > > 
> > > >System: x3850X5, 40 cores, 80 threads
> > > >
> > > >
> > > >1x over-commit with 10-vCPU VMs (8 VMs) all running dbench:
> > > >----------------------------------------------------------
> > > >						Total
> > > >Configuration				Throughput(MB/s)	Notes
> > > >
> > > >3.10-default-ple_on			22945			5% CPU in host kernel, 2% spin_lock in guests
> > > >3.10-default-ple_off			23184			5% CPU in host kernel, 2% spin_lock in guests
> > > >3.10-pvticket-ple_on			22895			5% CPU in host kernel, 2% spin_lock in guests
> > > >3.10-pvticket-ple_off			23051			5% CPU in host kernel, 2% spin_lock in guests
> > > >[all 1x results look good here]
> > > 
> > > Yes. The 1x results look too close
> > > 
> > > >
> > > >
> > > >2x over-commit with 10-vCPU VMs (16 VMs) all running dbench:
> > > >-----------------------------------------------------------
> > > >						Total
> > > >Configuration				Throughput		Notes
> > > >
> > > >3.10-default-ple_on			 6287			55% CPU  host kernel, 17% spin_lock in guests
> > > >3.10-default-ple_off			 1849			2% CPU in host kernel, 95% spin_lock in guests
> > > >3.10-pvticket-ple_on			 6691			50% CPU in host kernel, 15% spin_lock in guests
> > > >3.10-pvticket-ple_off			16464			8% CPU in host kernel, 33% spin_lock in guests
> > > 
> > > I see 6.426% improvement with ple_on
> > > and 161.87% improvement with ple_off. I think this is a very good sign
> > >  for the patches
> > > 
> > > >[PLE hinders pv-ticket improvements, but even with PLE off,
> > > >  we still off from ideal throughput (somewhere >20000)]
> > > >
> > > 
> > > Okay, The ideal throughput you are referring is getting around atleast
> > > 80% of 1x throughput for over-commit. Yes we are still far away from
> > > there.
> > > 
> > > >
> > > >1x over-commit with 20-vCPU VMs (4 VMs) all running dbench:
> > > >----------------------------------------------------------
> > > >						Total
> > > >Configuration				Throughput		Notes
> > > >
> > > >3.10-default-ple_on			22736			6% CPU in host kernel, 3% spin_lock in guests
> > > >3.10-default-ple_off			23377			5% CPU in host kernel, 3% spin_lock in guests
> > > >3.10-pvticket-ple_on			22471			6% CPU in host kernel, 3% spin_lock in guests
> > > >3.10-pvticket-ple_off			23445			5% CPU in host kernel, 3% spin_lock in guests
> > > >[1x looking fine here]
> > > >
> > > 
> > > I see ple_off is little better here.
> > > 
> > > >
> > > >2x over-commit with 20-vCPU VMs (8 VMs) all running dbench:
> > > >----------------------------------------------------------
> > > >						Total
> > > >Configuration				Throughput		Notes
> > > >
> > > >3.10-default-ple_on			 1965			70% CPU in host kernel, 34% spin_lock in guests		
> > > >3.10-default-ple_off			  226			2% CPU in host kernel, 94% spin_lock in guests
> > > >3.10-pvticket-ple_on			 1942			70% CPU in host kernel, 35% spin_lock in guests
> > > >3.10-pvticket-ple_off			 8003			11% CPU in host kernel, 70% spin_lock in guests
> > > >[quite bad all around, but pv-tickets with PLE off the best so far.
> > > >  Still quite a bit off from ideal throughput]
> > > 
> > > This is again a remarkable improvement (307%).
> > > This motivates me to add a patch to disable ple when pvspinlock is on.
> > > probably we can add a hypercall that disables ple in kvm init patch.
> > > but only problem I see is what if the guests are mixed.
> > > 
> > >  (i.e one guest has pvspinlock support but other does not. Host
> > > supports pv)
> > 
> > How about reintroducing the idea to create per-kvm ple_gap,ple_window
> > state. We were headed down that road when considering a dynamic window at
> > one point. Then you can just set a single guest's ple_gap to zero, which
> > would lead to PLE being disabled for that guest. We could also revisit
> > the dynamic window then.
> > 
> Can be done, but lets understand why ple on is such a big problem. Is it
> possible that ple gap and SPIN_THRESHOLD are not tuned properly?

The biggest problem currently is the double_runqueue_lock from
yield_to():
[2x overcommit with 20-vCPU VMs (8 VMs) all running dbench]

perf from host:
> 28.27%        396402  qemu-system-x86  [kernel.kallsyms]        [k] _raw_spin_lock                            
>  4.65%         65667  qemu-system-x86  [kernel.kallsyms]        [k] __schedule                                
>  3.87%         54802  qemu-system-x86  [kernel.kallsyms]        [k] finish_task_switch                        
>  3.32%         47022  qemu-system-x86  [kernel.kallsyms]        [k] perf_event_task_sched_out                 
>  2.84%         40093  qemu-system-x86  [kvm_intel]              [k] vmx_vcpu_run                              
>  2.70%         37672  qemu-system-x86  [kernel.kallsyms]        [k] yield_to                                  
>  2.63%         36859  qemu-system-x86  [kvm]                    [k] kvm_vcpu_on_spin                          
>  2.18%         30810  qemu-system-x86  [kvm_intel]              [k] __vmx_load_host_state     

A tiny patch [included below] checks if the target task is running
before double_runqueue_lock (then bails if it is running).  This does
reduce the lock contention somewhat:

[2x overcommit with 20-vCPU VMs (8 VMs) all running dbench]  
   
perf from host:
> 20.51%        284829  qemu-system-x86  [kernel.kallsyms]        [k] _raw_spin_lock                           
>  5.21%         72949  qemu-system-x86  [kernel.kallsyms]        [k] __schedule                               
>  3.70%         51962  qemu-system-x86  [kernel.kallsyms]        [k] finish_task_switch                       
>  3.50%         48607  qemu-system-x86  [kvm]                    [k] kvm_vcpu_on_spin                         
>  3.22%         45214  qemu-system-x86  [kernel.kallsyms]        [k] perf_event_task_sched_out                
>  3.18%         44546  qemu-system-x86  [kvm_intel]              [k] vmx_vcpu_run                             
>  3.13%         43176  qemu-system-x86  [kernel.kallsyms]        [k] yield_to                                 
>  2.37%         33349  qemu-system-x86  [kvm_intel]              [k] __vmx_load_host_state                    
>  2.06%         28503  qemu-system-x86  [kernel.kallsyms]        [k] get_pid_task    

So, the lock contention is reduced, and the results improve slightly
over default PLE/yield_to (in this case 1942 -> 2161, 11%), but this is
still far off from no PLE at all (8003) and way off from a ideal
throughput (>20000).

One of the problems, IMO, is that we are chasing our tail and burning
too much CPU trying to fix the problem, but much of what is done is not
actually fixing the problem (getting the one vcpu holding the lock to
run again).  We end up spending a lot of cycles getting a lot of vcpus
running again, and most of them are not holding that lock.  One
indication of this is the context switches in the host:

[2x overcommit with 20-vCPU VMs (8 VMs) all running dbench]

pvticket with PLE on:  2579227.76/sec
pvticket with PLE pff:  233711.30/sec

That's over 10x context switches with PLE on.  All of this is for
yield_to, but IMO most of vcpus are probably yielding to vcpus which are
not actually holding the lock.

I would like to see how this changes by tracking the lock holder in the
pvticket lock structure, and when a vcpu spins beyond a threshold, the
vcpu makes a hypercall to yield_to a -vCPU-it-specifies-, the one it
knows to be holding the lock.  Note that PLE is no longer needed for
this and the PLE detection should probably be disabled when the guest
has this ability.

Additionally, when other vcpus reach their spin threshold and also
identify the same target vcpu (the same lock), they may opt to not make
the yield_to hypercall, if another vcpu made the yield_to hypercall to
the same target vcpu -very-recently-, thus avoiding a redundant exit and
yield_to.

Another optimization may be to allow vcpu preemption to be visible
-inside- the guest.  If a vcpu reaches the spin threshold, then
identifies the lock holding vcpu, it then checks to see if a preemption
bit is set for that vcpu.  If it is not set, then it does nothing, and
if it is, it makes the yield_to hypercall.  This should help for locks
which really do have a big critical section, and the vcpus really do
need to spin for a while.

OK, one last thing.  This is a completely different approach at the
problem:  automatically adjust active vcpus from within a guest, with
some sort of daemon (vcpud?) to approximate the actual host cpu resource
available.  The daemon would monitor steal time and hot unplug vcpus to
reduce steal time to a small percentage. ending up with a slight cpu
overcommit.  It would also have to online vcpus if more cpu resource is
made available, again looking at steal time and adding vcpus until steal
time increases to a small percentage.  I am not sure if the overhead of
plugging/unplugging is worth it, but I would bet the guest would be far
more efficient, because (a) PLE and pvticket would be handling much
lower effective cpu overcommit (let's say ~1.1x) and (b) the guest and
its applications would have much better scalability because the active
vcpu count is much lower.

So, let's see what one of those situations would look like, without
actually writing something to do the unplugging/plugging for us.  Let's
take the one of the examples above, where we have 8 VMs, each defined
with 20 vcpus, for 2x overcommit, but let's unplug 9 vcpus in each of
the VMs, so we end up with a 1.1x effective overcommit (the last test
below).

[2x overcommit with 20-vCPU VMs (8 VMs) all running dbench] 

							Total
Configuration						Throughput	Notes

3.10-default-ple_on					1965		70% CPU in host kernel, 34% spin_lock in guests		
3.10-default-ple_off			 		 226		2% CPU in host kernel, 94% spin_lock in guests
3.10-pvticket-ple_on			 		1942		70% CPU in host kernel, 35% spin_lock in guests
3.10-pvticket-ple_off			 		8003		11% CPU in host kernel, 70% spin_lock in guests
3.10-pvticket-ple-on_doublerq-opt	 		2161		68% CPU in host kernel, 33% spin_lock in guests		
3.10-pvticket-ple_on_doublerq-opt_9vcpus-unplugged	22534		6% CPU in host kernel,  9% steal in guests, 2% spin_lock in guests

Finally, we get a nice result!  Note this is the lowest spin % in the guest.  The spin_lock in the host is also quite a bit better:


> 6.77%         55421  qemu-system-x86  [kernel.kallsyms]        [k] _raw_spin_lock                             
> 4.29%         57345  qemu-system-x86  [kvm_intel]              [k] vmx_vcpu_run                               
> 3.87%         62049  qemu-system-x86  [kernel.kallsyms]        [k] native_apic_msr_write                      
> 2.88%         45272  qemu-system-x86  [kernel.kallsyms]        [k] atomic_dec_and_mutex_lock                  
> 2.71%         39276  qemu-system-x86  [kvm]                    [k] vcpu_enter_guest                           
> 2.48%         38886  qemu-system-x86  [kernel.kallsyms]        [k] memset                                     
> 2.22%         18331  qemu-system-x86  [kvm]                    [k] kvm_vcpu_on_spin                           
> 2.09%         32628  qemu-system-x86  [kernel.kallsyms]        [k] perf_event_alloc 

Also the host context switches dropped significantly (66%), to 38768/sec.

-Andrew





Patch to reduce double runqueue lock in yield_to():

Signed-off-by: Andrew Theurer <habanero@linux.vnet.ibm.com>

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 58453b8..795d324 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4454,6 +4454,9 @@ again:
 		goto out_irq;
 	}
 
+	if (task_running(p_rq, p) || p->state)
+		goto out_irq;
+
 	double_rq_lock(rq, p_rq);
 	while (task_rq(p) != p_rq) {
 		double_rq_unlock(rq, p_rq);



  parent reply	other threads:[~2013-06-26 15:57 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-01 19:21 Raghavendra K T
2013-06-01 19:21 ` [PATCH RFC V9 1/19] x86/spinlock: Replace pv spinlocks with pv ticketlocks Raghavendra K T
2013-06-01 20:32   ` Jeremy Fitzhardinge
2013-06-02  6:54     ` Raghavendra K T
2013-06-01 19:22 ` [PATCH RFC V9 2/19] x86/ticketlock: Don't inline _spin_unlock when using paravirt spinlocks Raghavendra K T
2013-06-03 15:28   ` Konrad Rzeszutek Wilk
2013-06-01 19:22 ` [PATCH RFC V9 3/19] x86/ticketlock: Collapse a layer of functions Raghavendra K T
2013-06-03 15:28   ` Konrad Rzeszutek Wilk
2013-06-01 19:22 ` [PATCH RFC V9 4/19] xen: Defer spinlock setup until boot CPU setup Raghavendra K T
2013-06-01 19:23 ` [PATCH RFC V9 5/19] xen/pvticketlock: Xen implementation for PV ticket locks Raghavendra K T
2013-06-03 16:03   ` Konrad Rzeszutek Wilk
2013-06-04  7:21     ` Raghavendra K T
2013-06-01 19:23 ` [PATCH RFC V9 6/19] xen/pvticketlocks: Add xen_nopvspin parameter to disable xen pv ticketlocks Raghavendra K T
2013-06-01 19:23 ` [PATCH RFC V9 7/19] x86/pvticketlock: Use callee-save for lock_spinning Raghavendra K T
2013-06-01 19:24 ` [PATCH RFC V9 8/19] x86/pvticketlock: When paravirtualizing ticket locks, increment by 2 Raghavendra K T
2013-06-03 15:53   ` Konrad Rzeszutek Wilk
2013-06-01 19:24 ` [PATCH RFC V9 9/19] Split out rate limiting from jump_label.h Raghavendra K T
2013-06-03 15:56   ` Konrad Rzeszutek Wilk
2013-06-04  7:15     ` Raghavendra K T
2013-06-01 19:24 ` [PATCH RFC V9 10/19] x86/ticketlock: Add slowpath logic Raghavendra K T
2013-06-01 19:24 ` [PATCH RFC V9 11/19] xen/pvticketlock: Allow interrupts to be enabled while blocking Raghavendra K T
2013-06-01 19:25 ` [PATCH RFC V9 12/19] xen: Enable PV ticketlocks on HVM Xen Raghavendra K T
2013-06-03 15:57   ` Konrad Rzeszutek Wilk
2013-06-04  7:16     ` Raghavendra K T
2013-06-04 14:44       ` Konrad Rzeszutek Wilk
2013-06-04 15:00         ` Raghavendra K T
2013-06-01 19:25 ` [PATCH RFC V9 13/19] kvm hypervisor : Add a hypercall to KVM hypervisor to support pv-ticketlocks Raghavendra K T
2013-06-01 19:25 ` [PATCH RFC V9 14/19] kvm : Fold pv_unhalt flag into GET_MP_STATE ioctl to aid migration Raghavendra K T
2013-06-01 19:25 ` [PATCH RFC V9 15/19] kvm guest : Add configuration support to enable debug information for KVM Guests Raghavendra K T
2013-06-01 19:25 ` [PATCH RFC V9 16/19] kvm : Paravirtual ticketlocks support for linux guests running on KVM hypervisor Raghavendra K T
2013-06-03 16:00   ` Konrad Rzeszutek Wilk
2013-06-04  7:19     ` Raghavendra K T
2013-06-01 19:26 ` [PATCH RFC V9 17/19] kvm hypervisor : Simplify kvm_for_each_vcpu with kvm_irq_delivery_to_apic Raghavendra K T
2013-06-01 19:26 ` [PATCH RFC V9 18/19] Documentation/kvm : Add documentation on Hypercalls and features used for PV spinlock Raghavendra K T
2013-06-03 16:04   ` Konrad Rzeszutek Wilk
2013-06-04  7:22     ` Raghavendra K T
2013-06-01 19:26 ` [PATCH RFC V9 19/19] kvm hypervisor: Add directed yield in vcpu block path Raghavendra K T
2013-06-03 16:05   ` Konrad Rzeszutek Wilk
2013-06-04  7:28     ` Raghavendra K T
2013-06-02  8:07 ` [PATCH RFC V9 0/19] Paravirtualized ticket spinlocks Gleb Natapov
2013-06-02 16:20   ` Jiannan Ouyang
2013-06-03  1:40     ` Raghavendra K T
2013-06-03  6:21       ` Raghavendra K T
2013-06-07  6:15         ` Raghavendra K T
2013-06-07 13:29           ` Andrew Theurer
2013-06-07 23:41           ` Jiannan Ouyang
2013-06-25 14:50 ` Andrew Theurer
2013-06-26  8:45   ` Raghavendra K T
2013-06-26 11:37     ` Andrew Jones
2013-06-26 12:52       ` Gleb Natapov
2013-06-26 13:40         ` Raghavendra K T
     [not found]           ` <51CAFD28.7080002@hp.com>
2013-06-26 15:37             ` Raghavendra K T
2013-06-26 16:11           ` Gleb Natapov
2013-06-26 17:54             ` Raghavendra K T
2013-07-09  9:11               ` Raghavendra K T
2013-07-10 10:33                 ` Gleb Natapov
2013-07-10 10:40                   ` Peter Zijlstra
2013-07-10 10:47                     ` Gleb Natapov
2013-07-10 11:28                       ` Raghavendra K T
2013-07-10 11:29                         ` Gleb Natapov
2013-07-10 11:40                         ` Raghavendra K T
2013-07-10 15:03                       ` Konrad Rzeszutek Wilk
2013-07-10 15:16                         ` Gleb Natapov
2013-07-11  0:12                           ` Konrad Rzeszutek Wilk
2013-07-10 11:24                   ` Raghavendra K T
2013-07-10 11:41                     ` Gleb Natapov
2013-07-10 11:50                       ` Raghavendra K T
2013-07-11  9:13                   ` Raghavendra K T
2013-07-11  9:48                     ` Gleb Natapov
2013-07-11 10:10                       ` Raghavendra K T
2013-07-11 10:11                         ` Gleb Natapov
2013-07-11 10:53                           ` Raghavendra K T
2013-07-11 10:56                             ` Gleb Natapov
2013-07-11 11:14                               ` Raghavendra K T
2013-06-26 14:13         ` Konrad Rzeszutek Wilk
2013-06-26 15:56         ` Andrew Theurer [this message]
2013-07-01  9:30           ` Raghavendra K T
  -- strict thread matches above, loose matches on Subject: below --
2013-06-01  8:21 Raghavendra K T
2013-06-01 20:14 ` Andi Kleen
2013-06-01 20:28   ` Jeremy Fitzhardinge
2013-06-01 20:46     ` Andi Kleen
2013-06-04 10:58   ` Raghavendra K T

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1372262213.31391.176.camel@oc6622382223.ibm.com \
    --to=habanero@linux.vnet.ibm.com \
    --cc=agraf@suse.de \
    --cc=andi@firstfloor.org \
    --cc=attilio.rao@citrix.com \
    --cc=avi.kivity@gmail.com \
    --cc=chegu_vinod@hp.com \
    --cc=drjones@redhat.com \
    --cc=gleb@redhat.com \
    --cc=gregkh@suse.de \
    --cc=hpa@zytor.com \
    --cc=jeremy@goop.org \
    --cc=konrad.wilk@oracle.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=mtosatti@redhat.com \
    --cc=ouyang@cs.pitt.edu \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=raghavendra.kt@linux.vnet.ibm.com \
    --cc=riel@redhat.com \
    --cc=srivatsa.vaddagiri@gmail.com \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=stephan.diestelhorst@amd.com \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=virtualization@lists.linux-foundation.org \
    --cc=x86@kernel.org \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®