From: Waiman Long <waiman.long@hp.com>
To: Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>
Cc: jeremy@goop.org, kvm@vger.kernel.org, peterz@infradead.org,
virtualization@lists.linux-foundation.org,
paul.gortmaker@windriver.com, hpa@zytor.com, ak@linux.intel.com,
gleb@redhat.com, x86@kernel.org, mingo@redhat.com,
xen-devel@lists.xenproject.org, paulmck@linux.vnet.ibm.com,
riel@redhat.com, konrad.wilk@oracle.com, oleg@redhat.com,
davej@redhat.com, tglx@linutronix.de, fernando_b1@lab.ntt.co.jp,
chegu_vinod@hp.com, linux-kernel@vger.kernel.org,
pbonzini@redhat.com, torvalds@linux-foundation.org
Subject: Re: [RFC] Implement Batched (group) ticket lock
Date: Thu, 29 May 2014 18:45:18 -0400 [thread overview]
Message-ID: <5387B87E.2010609@hp.com> (raw)
In-Reply-To: <1401279399-23854-1-git-send-email-raghavendra.kt@linux.vnet.ibm.com>
On 05/28/2014 08:16 AM, Raghavendra K T wrote:
>
> TODO:
> - we need an intelligent way to nullify the effect of batching for baremetal
> (because extra cmpxchg is not required).
To do this, you will need to have 2 slightly different algorithms
depending on the paravirt_ticketlocks_enabled jump label.
>
> - My kernbench/ebizzy test on baremetal (32 cpu +ht sandybridge) did not seem to
> show the impact of extra cmpxchg. but there should be effect of extra cmpxchg.
It will depend on the micro-benchmark and the test system used. I had
seen the a test case that extra cmpxchg did not really impact
performance on a Westmere system but had noticeable adverse impact on an
IvyBridge system with the same micro-benchmark.
> Please provide your suggestion and comments.
>
> diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h
> index 0f62f54..87685f1 100644
> --- a/arch/x86/include/asm/spinlock.h
> +++ b/arch/x86/include/asm/spinlock.h
> @@ -81,23 +81,36 @@ static __always_inline int arch_spin_value_unlocked(arch_spinlock_t lock)
> */
> static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
> {
> - register struct __raw_tickets inc = { .tail = TICKET_LOCK_INC };
> + register struct __raw_tickets inc = { .tail = TICKET_LOCK_TAIL_INC };
> + struct __raw_tickets new;
>
> inc = xadd(&lock->tickets, inc);
> - if (likely(inc.head == inc.tail))
> - goto out;
>
> inc.tail&= ~TICKET_SLOWPATH_FLAG;
> for (;;) {
> unsigned count = SPIN_THRESHOLD;
>
> do {
> - if (ACCESS_ONCE(lock->tickets.head) == inc.tail)
> - goto out;
> + if ((inc.head& TICKET_LOCK_BATCH_MASK) == (inc.tail&
> + TICKET_LOCK_BATCH_MASK))
> + goto spin;
> cpu_relax();
> + inc.head = ACCESS_ONCE(lock->tickets.head);
> } while (--count);
> __ticket_lock_spinning(lock, inc.tail);
> }
> +spin:
> + for (;;) {
> + inc.head = ACCESS_ONCE(lock->tickets.head);
> + if (!(inc.head& TICKET_LOCK_HEAD_INC)) {
> + new.head = inc.head | TICKET_LOCK_HEAD_INC;
> + if (cmpxchg(&lock->tickets.head, inc.head, new.head)
> + == inc.head)
> + goto out;
> + }
> + cpu_relax();
> + }
> +
It had taken me some time to figure out the the LSB of inc.head is used
as a bit lock for the contending tasks in the spin loop. I would suggest
adding some comment here to make it easier to look at.
> diff --git a/arch/x86/include/asm/spinlock_types.h b/arch/x86/include/asm/spinlock_types.h
> index 4f1bea1..b04c03d 100644
> --- a/arch/x86/include/asm/spinlock_types.h
> +++ b/arch/x86/include/asm/spinlock_types.h
> @@ -3,15 +3,16 @@
>
> #include<linux/types.h>
>
> +#define TICKET_LOCK_INC_SHIFT 1
> +#define __TICKET_LOCK_TAIL_INC (1<<TICKET_LOCK_INC_SHIFT)
> +
> #ifdef CONFIG_PARAVIRT_SPINLOCKS
> -#define __TICKET_LOCK_INC 2
> #define TICKET_SLOWPATH_FLAG ((__ticket_t)1)
> #else
> -#define __TICKET_LOCK_INC 1
> #define TICKET_SLOWPATH_FLAG ((__ticket_t)0)
> #endif
>
> -#if (CONFIG_NR_CPUS< (256 / __TICKET_LOCK_INC))
> +#if (CONFIG_NR_CPUS< (256 / __TICKET_LOCK_TAIL_INC))
> typedef u8 __ticket_t;
> typedef u16 __ticketpair_t;
> #else
> @@ -19,7 +20,12 @@ typedef u16 __ticket_t;
> typedef u32 __ticketpair_t;
> #endif
>
> -#define TICKET_LOCK_INC ((__ticket_t)__TICKET_LOCK_INC)
> +#define TICKET_LOCK_TAIL_INC ((__ticket_t)__TICKET_LOCK_TAIL_INC)
> +
> +#define TICKET_LOCK_HEAD_INC ((__ticket_t)1)
> +#define TICKET_BATCH 0x4 /* 4 waiters can contend simultaneously */
> +#define TICKET_LOCK_BATCH_MASK (~(TICKET_BATCH<<TICKET_LOCK_INC_SHIFT) + \
> + TICKET_LOCK_TAIL_INC - 1)
I don't think TAIL_INC has anything to do with setting the BATCH_MASK.
It works here because TAIL_INC is 2. I think it is clearer to define it
as either "(~(TICKET_BATCH<<TICKET_LOCK_INC_SHIFT) + 1)" or
(~((TICKET_BATCH<<TICKET_LOCK_INC_SHIFT) - 1)).
-Longman
next prev parent reply other threads:[~2014-05-29 22:45 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-28 12:16 [RFC] Implement Batched (group) ticket lock Raghavendra K T
2014-05-28 21:55 ` Rik van Riel
2014-05-28 22:19 ` Linus Torvalds
2014-05-28 22:29 ` Thomas Gleixner
2014-05-29 1:18 ` Rik van Riel
2014-05-29 9:44 ` Raghavendra K T
2014-05-29 6:46 ` Peter Zijlstra
2014-05-29 9:51 ` Raghavendra K T
2014-05-29 22:45 ` Waiman Long [this message]
2014-05-30 8:53 ` 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=5387B87E.2010609@hp.com \
--to=waiman.long@hp.com \
--cc=ak@linux.intel.com \
--cc=chegu_vinod@hp.com \
--cc=davej@redhat.com \
--cc=fernando_b1@lab.ntt.co.jp \
--cc=gleb@redhat.com \
--cc=hpa@zytor.com \
--cc=jeremy@goop.org \
--cc=konrad.wilk@oracle.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=oleg@redhat.com \
--cc=paul.gortmaker@windriver.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=raghavendra.kt@linux.vnet.ibm.com \
--cc=riel@redhat.com \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
--cc=virtualization@lists.linux-foundation.org \
--cc=x86@kernel.org \
--cc=xen-devel@lists.xenproject.org \
/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;
as well as URLs for NNTP newsgroup(s).