From: "tip-bot2 for Matthew Wilcox (Oracle)" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>,
"Peter Zijlstra (Intel)" <peterz@infradead.org>,
x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [tip: locking/core] locking/semaphore: Remove the list_head from struct semaphore
Date: Mon, 09 Mar 2026 19:48:18 -0000 [thread overview]
Message-ID: <177308569817.1647592.9772716447530683158.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20260305195545.3707590-3-willy@infradead.org>
The following commit has been merged into the locking/core branch of tip:
Commit-ID: b9bdd4b6840454ef87f61b6506c9635c57a81650
Gitweb: https://git.kernel.org/tip/b9bdd4b6840454ef87f61b6506c9635c57a81650
Author: Matthew Wilcox (Oracle) <willy@infradead.org>
AuthorDate: Thu, 05 Mar 2026 19:55:42
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Sun, 08 Mar 2026 11:06:52 +01:00
locking/semaphore: Remove the list_head from struct semaphore
Instead of embedding a list_head in struct semaphore, store a pointer to
the first waiter. The list of waiters remains a doubly linked list so
we can efficiently add to the tail of the list and remove from the front
(or middle) of the list.
Some of the list manipulation becomes more complicated, but it's a
reasonable tradeoff on the slow paths to shrink data structures
which embed a semaphore.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260305195545.3707590-3-willy@infradead.org
---
drivers/acpi/osl.c | 2 +-
include/linux/semaphore.h | 4 ++--
kernel/locking/semaphore.c | 41 +++++++++++++++++++++++++++----------
3 files changed, 34 insertions(+), 13 deletions(-)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 5b77731..2af0db9 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1257,7 +1257,7 @@ acpi_status acpi_os_delete_semaphore(acpi_handle handle)
ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].\n", handle));
- BUG_ON(!list_empty(&sem->wait_list));
+ BUG_ON(sem->first_waiter);
kfree(sem);
sem = NULL;
diff --git a/include/linux/semaphore.h b/include/linux/semaphore.h
index 8970615..a4c8651 100644
--- a/include/linux/semaphore.h
+++ b/include/linux/semaphore.h
@@ -15,7 +15,7 @@
struct semaphore {
raw_spinlock_t lock;
unsigned int count;
- struct list_head wait_list;
+ struct semaphore_waiter *first_waiter;
#ifdef CONFIG_DETECT_HUNG_TASK_BLOCKER
unsigned long last_holder;
@@ -33,7 +33,7 @@ struct semaphore {
{ \
.lock = __RAW_SPIN_LOCK_UNLOCKED((name).lock), \
.count = n, \
- .wait_list = LIST_HEAD_INIT((name).wait_list) \
+ .first_waiter = NULL \
__LAST_HOLDER_SEMAPHORE_INITIALIZER \
}
diff --git a/kernel/locking/semaphore.c b/kernel/locking/semaphore.c
index 3ef032e..74d4143 100644
--- a/kernel/locking/semaphore.c
+++ b/kernel/locking/semaphore.c
@@ -21,7 +21,7 @@
* too.
*
* The ->count variable represents how many more tasks can acquire this
- * semaphore. If it's zero, there may be tasks waiting on the wait_list.
+ * semaphore. If it's zero, there may be waiters.
*/
#include <linux/compiler.h>
@@ -226,7 +226,7 @@ void __sched up(struct semaphore *sem)
hung_task_sem_clear_if_holder(sem);
- if (likely(list_empty(&sem->wait_list)))
+ if (likely(!sem->first_waiter))
sem->count++;
else
__up(sem, &wake_q);
@@ -244,6 +244,21 @@ struct semaphore_waiter {
bool up;
};
+static inline
+void sem_del_waiter(struct semaphore *sem, struct semaphore_waiter *waiter)
+{
+ if (list_empty(&waiter->list)) {
+ sem->first_waiter = NULL;
+ return;
+ }
+
+ if (sem->first_waiter == waiter) {
+ sem->first_waiter = list_first_entry(&waiter->list,
+ struct semaphore_waiter, list);
+ }
+ list_del(&waiter->list);
+}
+
/*
* Because this function is inlined, the 'state' parameter will be
* constant, and thus optimised away by the compiler. Likewise the
@@ -252,9 +267,15 @@ struct semaphore_waiter {
static inline int __sched ___down_common(struct semaphore *sem, long state,
long timeout)
{
- struct semaphore_waiter waiter;
-
- list_add_tail(&waiter.list, &sem->wait_list);
+ struct semaphore_waiter waiter, *first;
+
+ first = sem->first_waiter;
+ if (first) {
+ list_add_tail(&waiter.list, &first->list);
+ } else {
+ INIT_LIST_HEAD(&waiter.list);
+ sem->first_waiter = &waiter;
+ }
waiter.task = current;
waiter.up = false;
@@ -274,11 +295,11 @@ static inline int __sched ___down_common(struct semaphore *sem, long state,
}
timed_out:
- list_del(&waiter.list);
+ sem_del_waiter(sem, &waiter);
return -ETIME;
interrupted:
- list_del(&waiter.list);
+ sem_del_waiter(sem, &waiter);
return -EINTR;
}
@@ -321,9 +342,9 @@ static noinline int __sched __down_timeout(struct semaphore *sem, long timeout)
static noinline void __sched __up(struct semaphore *sem,
struct wake_q_head *wake_q)
{
- struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list,
- struct semaphore_waiter, list);
- list_del(&waiter->list);
+ struct semaphore_waiter *waiter = sem->first_waiter;
+
+ sem_del_waiter(sem, waiter);
waiter->up = true;
wake_q_add(wake_q, waiter->task);
}
next prev parent reply other threads:[~2026-03-09 19:48 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-05 19:55 [PATCH 0/3] Shrink size of sleeping locks Matthew Wilcox (Oracle)
2026-03-05 19:55 ` [PATCH 1/3] rwsem: Remove the list_head from struct rw_semaphore Matthew Wilcox (Oracle)
2026-03-09 19:48 ` [tip: locking/core] locking/rwsem: " tip-bot2 for Matthew Wilcox (Oracle)
2026-03-14 0:03 ` Andrei Vagin
2026-03-18 19:07 ` [PATCH 1/3] rwsem: " Mark Brown
2026-03-18 20:28 ` Peter Zijlstra
2026-03-19 13:47 ` Mark Brown
2026-03-05 19:55 ` [PATCH 2/3] semaphore: Remove the list_head from struct semaphore Matthew Wilcox (Oracle)
2026-03-09 19:48 ` tip-bot2 for Matthew Wilcox (Oracle) [this message]
2026-03-05 19:55 ` [PATCH 3/3] mutex: Remove the list_head from struct mutex Matthew Wilcox (Oracle)
2026-03-07 0:30 ` kernel test robot
2026-03-09 19:48 ` [tip: locking/core] locking/mutex: " tip-bot2 for Matthew Wilcox (Oracle)
2026-03-06 10:14 ` [PATCH 0/3] Shrink size of sleeping locks Peter Zijlstra
2026-03-09 19:48 ` [tip: locking/core] locking/rwsem: Add context analysis tip-bot2 for Peter Zijlstra
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=177308569817.1647592.9772716447530683158.tip-bot2@tip-bot2 \
--to=tip-bot2@linutronix.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=peterz@infradead.org \
--cc=willy@infradead.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®