mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "tip-bot2 for David Laight" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: David Laight <david.laight.linux@gmail.com>,
	"Peter Zijlstra (Intel)" <peterz@infradead.org>,
	Ingo Molnar <mingo@kernel.org>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Waiman Long <longman@redhat.com>,
	x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [tip: locking/core] locking/osq: Use CPU number for 'next' pointer
Date: Fri, 06 Nov 2026 10:25:33 -0000	[thread overview]
Message-ID: <179396073328.1009794.8798304514620219910.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20260907084133.3696-7-david.laight.linux@gmail.com>

The following commit has been merged into the locking/core branch of tip:

Commit-ID:     8e7c6217be7f8c016975f5b0954f6736b9ac42cf
Gitweb:        https://git.kernel.org/tip/8e7c6217be7f8c016975f5b0954f6736b9ac42cf
Author:        David Laight <david.laight.linux@gmail.com>
AuthorDate:    Mon, 07 Sep 2026 09:41:30 +01:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Fri, 06 Nov 2026 11:16:24 +01:00

locking/osq: Use CPU number for 'next' pointer

There is only one write done through node->next (setting prev) when
'node' is being removed. So the code can consistently use the CPU
numbers pretty much throughout (this was suggested by Linus a while
back).

This reduces struct optimistic_spin_node to 8 bytes. This is currently
padded out to a cache line which is silly. Change to be __aligned(8) so
that it isn't split between cache lines.

Accesses to 'other CPU' data are very limited and only happen during
the enqueue and dequeue operation.

[ peterz: Rewrote it completely ]

Signed-off-by: David Laight <david.laight.linux@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Waiman Long <longman@redhat.com>
Link: https://patch.msgid.link/20260907084133.3696-7-david.laight.linux@gmail.com
---
 kernel/locking/osq_lock.c | 49 ++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 25 deletions(-)

diff --git a/kernel/locking/osq_lock.c b/kernel/locking/osq_lock.c
index a6c89e5..735bf62 100644
--- a/kernel/locking/osq_lock.c
+++ b/kernel/locking/osq_lock.c
@@ -13,11 +13,11 @@
  */
 
 struct optimistic_spin_node {
-	struct optimistic_spin_node *next;
+	int next_cpu; /* CPU number offset by 1 */
 	int prev_cpu; /* CPU number offset by 1 */
-};
+} __aligned(8);
 
-static DEFINE_PER_CPU_SHARED_ALIGNED(struct optimistic_spin_node, osq_node);
+static DEFINE_PER_CPU(struct optimistic_spin_node, osq_node);
 
 /*
  * We use the value 0 to represent "no CPU", thus the encoded value
@@ -44,22 +44,21 @@ static inline struct optimistic_spin_node *decode_cpu(int encoded_cpu_val)
  * For osq_unlock() there is never a previous node and old_cpu is
  * set to OSQ_UNLOCKED_VAL.
  */
-static inline struct optimistic_spin_node *
-osq_wait_unlink_next(struct optimistic_spin_queue *lock,
-		     int old_cpu)
+static inline int
+osq_wait_unlink_next(struct optimistic_spin_queue *lock, int old_cpu)
 {
 	struct optimistic_spin_node *next, *node = this_cpu_ptr(&osq_node);
-	int curr = encode_cpu(smp_processor_id());
+	int next_cpu, node_cpu = encode_cpu(smp_processor_id());
 
 	for (;;) {
-		if (atomic_read(&lock->tail) == curr &&
-		    atomic_cmpxchg_release(&lock->tail, curr, old_cpu) == curr) {
+		if (atomic_read(&lock->tail) == node_cpu &&
+		    atomic_cmpxchg_release(&lock->tail, node_cpu, old_cpu) == node_cpu) {
 			/*
 			 * We were the last queued, we moved @lock back. @prev
 			 * will now observe @lock and will complete its
 			 * unlock()/unqueue().
 			 */
-			return NULL;
+			return 0;
 		}
 
 		/*
@@ -72,9 +71,9 @@ osq_wait_unlink_next(struct optimistic_spin_queue *lock,
 		 * wait for either @lock to point to us, through its Step-B, or
 		 * wait for a new @node->next from its Step-C.
 		 */
-		if (node->next) {
-			next = xchg(&node->next, NULL);
-			if (next)
+		if (node->next_cpu) {
+			next_cpu = xchg(&node->next_cpu, 0);
+			if (next_cpu)
 				break;
 		}
 
@@ -84,16 +83,16 @@ osq_wait_unlink_next(struct optimistic_spin_queue *lock,
 	/*
 	 * Unlink @node from @next.
 	 */
+	next = decode_cpu(next_cpu);
 	WRITE_ONCE(next->prev_cpu, old_cpu);
-	return next;
+	return next_cpu;
 }
 
 /*
  * Set prev->next; this is the counterpart of osq_wait_unlink_next() in that
  * by setting ->next the wait is terminated and progress is resumed.
  */
-static inline void osq_link_next(struct optimistic_spin_node *prev,
-				 struct optimistic_spin_node *next)
+static inline void osq_link_next(struct optimistic_spin_node *prev, int next_cpu)
 {
 	/*
 	 * Suppose:
@@ -128,17 +127,17 @@ static inline void osq_link_next(struct optimistic_spin_node *prev,
 	 *
 	 * Which would result in list corruption.
 	 */
-	smp_store_release(&prev->next, next);
+	smp_store_release(&prev->next_cpu, next_cpu);
 }
 
 bool osq_lock(struct optimistic_spin_queue *lock)
 {
 	struct optimistic_spin_node *node = this_cpu_ptr(&osq_node);
-	struct optimistic_spin_node *prev, *next;
-	int curr = encode_cpu(smp_processor_id());
-	int prev_cpu;
+	int node_cpu = encode_cpu(smp_processor_id());
+	struct optimistic_spin_node *prev;
+	int prev_cpu, next_cpu;
 
-	node->next = NULL;
+	node->next_cpu = 0;
 
 	/*
 	 * We need both ACQUIRE (pairs with corresponding RELEASE in
@@ -146,13 +145,13 @@ bool osq_lock(struct optimistic_spin_queue *lock)
 	 * the node fields we just initialised) semantics when updating
 	 * the lock tail.
 	 */
-	prev_cpu = atomic_xchg(&lock->tail, curr);
+	prev_cpu = atomic_xchg(&lock->tail, node_cpu);
 	if (prev_cpu == OSQ_UNLOCKED_VAL)
 		return true;
 
 	prev = decode_cpu(prev_cpu);
 	node->prev_cpu = prev_cpu;
-	osq_link_next(prev, node);
+	osq_link_next(prev, node_cpu);
 
 	/*
 	 * Normally @prev is untouchable after the above store; because at that
@@ -191,8 +190,8 @@ bool osq_lock(struct optimistic_spin_queue *lock)
 
 		prev = decode_cpu(prev_cpu);
 
-		if (data_race(prev->next) == node &&
-		    cmpxchg(&prev->next, node, NULL) == node)
+		if (data_race(prev->next_cpu) == node_cpu &&
+		    cmpxchg(&prev->next_cpu, node_cpu, 0) == node_cpu)
 			break;
 
 		/*

  reply	other threads:[~2026-11-06 10:25 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-07  8:41 [PATCH v4 next 0/9] locking/osq_lock: Optimisations to osq_lock code David Laight
2026-09-07  8:41 ` [PATCH v4 next 1/9] locking/osq_lock: Add some comments about how it works David Laight
2026-09-09 14:57   ` Waiman Long
2026-09-07  8:41 ` [PATCH v4 next 2/9] locking/osq_lock: Save the cpu number for 'prev' not the node address David Laight
2026-09-09 17:36   ` Waiman Long
2026-09-15  8:33   ` Peter Zijlstra
2026-09-15 10:26     ` Peter Zijlstra
2026-09-15 11:11       ` David Laight
2026-09-15 17:27       ` Waiman Long
2026-11-06 10:25   ` [tip: locking/core] locking/osq: Save the CPU number for 'prev', " tip-bot2 for David Laight
2026-09-07  8:41 ` [PATCH v4 next 3/9] locking/osq_lock: Set prev_cpu=0 instead of locked=1 David Laight
2026-09-09 18:01   ` Waiman Long
2026-09-09 18:52     ` David Laight
2026-09-14 12:01       ` Peter Zijlstra
2026-09-14 13:10         ` David Laight
2026-09-14 12:03   ` Peter Zijlstra
2026-09-14 13:08     ` David Laight
2026-09-15  8:40       ` Peter Zijlstra
2026-09-15 10:14         ` David Laight
2026-09-15  8:50   ` Peter Zijlstra
2026-09-15 10:20     ` David Laight
2026-09-15 10:40       ` Peter Zijlstra
2026-09-15 13:13   ` Peter Zijlstra
2026-09-15 13:15     ` Peter Zijlstra
2026-09-15 13:55       ` David Laight
2026-09-15 14:01         ` Peter Zijlstra
2026-09-15 17:47           ` David Laight
2026-09-16  8:08             ` Peter Zijlstra
2026-11-06 10:25   ` [tip: locking/core] locking/osq: " tip-bot2 for David Laight
2026-09-07  8:41 ` [PATCH v4 next 4/9] locking/osq_lock: Delete 'fast path' code from osq_unlock() David Laight
2026-09-15 14:15   ` Peter Zijlstra
2026-09-16 10:56     ` Peter Zijlstra
2026-09-07  8:41 ` [PATCH v4 next 5/9] locking/osq_lock: Avoid writing to node->next in the osq_lock() fast path David Laight
2026-09-07  8:41 ` [PATCH v4 next 6/9] locking/osq: Use cpu number for 'next' pointer David Laight
2026-11-06 10:25   ` tip-bot2 for David Laight [this message]
2026-09-07  8:41 ` [PATCH v4 next 7/9] locking/osq: Use 'unsigned int' for next/prev/tail David Laight
2026-09-07  8:41 ` [PATCH v4 next 8/9] locking/osq: inline encode_cpu() and rename decode_cpu() David Laight
2026-09-07  8:41 ` [PATCH v4 next 9/9] locking/osq_lock: Swap next<->prev and tail<->head David Laight
2026-09-07 16:08 ` [PATCH v4 next 0/9] locking/osq_lock: Optimisations to osq_lock code Linus Torvalds
2026-09-07 17:27   ` David Laight
2026-09-09 14:15     ` Haakon Bugge
2026-09-09 19:09       ` David Laight
2026-09-09 20:14       ` Waiman Long
2026-09-09 20:33         ` Waiman Long
2026-09-10  9:45           ` Haakon Bugge
2026-09-10 11:00             ` David Laight
2026-09-10 11:31               ` Haakon Bugge
2026-09-10 12:05                 ` David Laight
2026-09-10 15:30                   ` Haakon Bugge
2026-09-10 16:22                     ` Waiman Long
2026-09-11 17:15                     ` David Laight
2026-09-14 11:46                       ` Haakon Bugge
2026-09-14 13:24                         ` David Laight
2026-09-11 10:08                 ` David Laight

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=179396073328.1009794.8798304514620219910.tip-bot2@tip-bot2 \
    --to=tip-bot2@linutronix.de \
    --cc=david.laight.linux@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=longman@redhat.com \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=torvalds@linux-foundation.org \
    --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 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®