All of lore.kernel.org
 help / color / mirror / Atom feed
From: Waiman Long <waiman.long@hp.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Tim Chen <tim.c.chen@linux.intel.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
	Arnd Bergmann <arnd@arndb.de>,
	linux-arch@vger.kernel.org, x86@kernel.org,
	linux-kernel@vger.kernel.org,
	Steven Rostedt <rostedt@goodmis.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Michel Lespinasse <walken@google.com>,
	Andi Kleen <andi@firstfloor.org>, Rik van Riel <riel@redhat.com>,
	"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Raghavendra K T <raghavendra.kt@linux.vnet.ibm.com>,
	George Spelvin <linux@horizon.com>,
	Daniel J Blueman <daniel@numascale.com>,
	Alexander Fyodorov <halcy@yandex.ru>,
	Aswin Chandramouleeswaran <aswin@hp.com>,
	Scott J Norton <scott.norton@hp.com>,
	Thavatchai Makphaibulchoke <thavatchai.makpahibulchoke@hp.com>
Subject: Re: [PATCH v3 1/2] qspinlock: Introducing a 4-byte queue spinlock implementation
Date: Fri, 31 Jan 2014 13:26:29 -0500	[thread overview]
Message-ID: <52EBEAD5.3000502@hp.com> (raw)
In-Reply-To: <20140130192835.GK5002@laptop.programming.kicks-ass.net>

On 01/30/2014 02:28 PM, Peter Zijlstra wrote:
> On Thu, Jan 30, 2014 at 11:00:30AM -0800, Tim Chen wrote:
>> On Tue, 2014-01-28 at 13:19 -0500, Waiman Long wrote:
>>
>>> +/**
>>> + * queue_spin_lock_slowpath - acquire the queue spinlock
>>> + * @lock: Pointer to queue spinlock structure
>>> + */
>>> +void queue_spin_lock_slowpath(struct qspinlock *lock)
>>> +{
>>> +	unsigned int cpu_nr, qn_idx;
>>> +	struct qnode *node, *next = NULL;
>>> +	u32 prev_qcode, my_qcode;
>>> +
>>> +	/*
>>> +	 * Get the queue node
>>> +	 */
>>> +	cpu_nr = smp_processor_id();
>>> +	node   = this_cpu_ptr(&qnodes[0]);
>>> +	qn_idx = 0;
>>> +
>>> +	if (unlikely(node->used)) {
>>> +		/*
>>> +		 * This node has been used, try to find an empty queue
>>> +		 * node entry.
>>> +		 */
>>> +		for (qn_idx = 1; qn_idx<  MAX_QNODES; qn_idx++)
>>> +			if (!node[qn_idx].used)
>>> +				break;
>>> +		if (unlikely(qn_idx == MAX_QNODES)) {
>>> +			/*
>>> +			 * This shouldn't happen, print a warning message
>>> +			 *&  busy spinning on the lock.
>>> +			 */
>>> +			printk_sched(
>>> +			  "qspinlock: queue node table exhausted at cpu %d!\n",
>>> +			  cpu_nr);
>>> +			while (!unfair_trylock(lock))
>>> +				arch_mutex_cpu_relax();
>>> +			return;
>>> +		}
>>> +		/* Adjust node pointer */
>>> +		node += qn_idx;
>>> +	}
>>> +
>>> +	/*
>>> +	 * Set up the new cpu code to be exchanged
>>> +	 */
>>> +	my_qcode = SET_QCODE(cpu_nr, qn_idx);
>>> +
>> If we get interrupted here before we have a chance to set the used flag,
>> the interrupt handler could pick up the same qnode if it tries to
>> acquire queued spin lock.  Then we could overwrite the qcode we have set
>> here.
>>
>> Perhaps an exchange operation for the used flag to prevent this race
>> condition?
> I don't get why we need the used thing at all; something like:
>
> struct qna {
> 	int cnt;
> 	struct qnode nodes[4];
> };
>
> DEFINE_PER_CPU(struct qna, qna);
>
> struct qnode *get_qnode(void)
> {
> 	struct qna *qna = this_cpu_ptr(&qna);
>
> 	return qna->nodes[qna->cnt++]; /* RMW */
> }
>
> void put_qnode(struct qnode *qnode)
> {
> 	struct qna *qna = this_cpu_ptr(&qna);
> 	qna->cnt--;
> }
>
> Should do fine, right?

Yes, we can do something like that. However I think put_qnode() needs to 
use atomic dec as well. As a result, we will need 2 additional atomic 
operations per slowpath invocation. The code may look simpler, but I 
don't think it will be faster than what I am currently doing as the 
cases where the used flag is set will be relatively rare.

>
> If we interrupt the RMW above the interrupted context hasn't yet used
> the queue and once we return its free again, so all should be well even
> on load-store archs.
>
> The nodes array might as well be 3, because NMIs should never contend on
> a spinlock, so all we're left with is task, softirq and hardirq context.

I am not so sure about NMI not taking a spinlock. I seem to remember 
seeing code that did that. Actually, I think the NMI code is trying to 
printk something which, in turn, need to acquire a spinlock.

-Longman

  parent reply	other threads:[~2014-01-31 18:26 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-01-28 18:19 [PATCH v3 0/2] qspinlock: Introducing a 4-byte queue spinlock Waiman Long
2014-01-28 18:19 ` [PATCH v3 1/2] qspinlock: Introducing a 4-byte queue spinlock implementation Waiman Long
2014-01-29  0:20   ` Andi Kleen
2014-01-29  0:20     ` Andi Kleen
2014-01-29  2:57     ` George Spelvin
2014-01-29  2:57       ` George Spelvin
2014-01-29 17:57     ` Waiman Long
2014-01-30 17:43   ` Rik van Riel
2014-01-30 19:00   ` Tim Chen
2014-01-30 19:28     ` Peter Zijlstra
2014-01-30 22:27       ` Tim Chen
2014-01-31 18:26       ` Waiman Long [this message]
2014-01-31 19:14         ` George Spelvin
2014-01-31 19:28           ` Waiman Long
2014-01-31 19:45         ` Peter Zijlstra
2014-01-31 18:16     ` Waiman Long
2014-01-30 19:35   ` Peter Zijlstra
2014-01-31 18:28     ` Waiman Long
2014-01-31 15:08   ` Peter Zijlstra
2014-01-31 19:24     ` Waiman Long
2014-01-31 19:51       ` Peter Zijlstra
2014-02-03 11:40       ` Peter Zijlstra
2014-02-06  3:10         ` Waiman Long
2014-02-07 18:17           ` Paul E. McKenney
2014-02-03  8:51   ` Raghavendra K T
2014-01-28 18:19 ` [PATCH v3 2/2] qspinlock, x86: Enable x86-64 to use queue spinlock Waiman Long
2014-01-30 17:45   ` Rik van Riel
2014-01-30  8:55 ` [PATCH v3 0/2] qspinlock: Introducing a 4-byte " Raghavendra K T
2014-01-30 15:38   ` Waiman Long
2014-01-30 18:49     ` Raghavendra K T
2014-02-03  8:51       ` Raghavendra K T
2014-02-06  3:09         ` Waiman Long

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=52EBEAD5.3000502@hp.com \
    --to=waiman.long@hp.com \
    --cc=akpm@linux-foundation.org \
    --cc=andi@firstfloor.org \
    --cc=arnd@arndb.de \
    --cc=aswin@hp.com \
    --cc=daniel@numascale.com \
    --cc=halcy@yandex.ru \
    --cc=hpa@zytor.com \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@horizon.com \
    --cc=mingo@redhat.com \
    --cc=paulmck@linux.vnet.ibm.com \
    --cc=peterz@infradead.org \
    --cc=raghavendra.kt@linux.vnet.ibm.com \
    --cc=riel@redhat.com \
    --cc=rostedt@goodmis.org \
    --cc=scott.norton@hp.com \
    --cc=tglx@linutronix.de \
    --cc=thavatchai.makpahibulchoke@hp.com \
    --cc=tim.c.chen@linux.intel.com \
    --cc=torvalds@linux-foundation.org \
    --cc=walken@google.com \
    --cc=x86@kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.