summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorMatthew Wilcox (Oracle) <willy@infradead.org>2026-03-05 22:55:41 +0300
committerPeter Zijlstra <peterz@infradead.org>2026-03-08 13:06:51 +0300
commit1ea4b473504b6dc6a0d21c298519aff2d52433c9 (patch)
tree85e8f91f16ceff2a26c8eb479e848ab78cbb3663 /include/linux
parentb91d5d4bcf1266257a9e0199e1b4ad7fa8771baa (diff)
downloadlinux-1ea4b473504b6dc6a0d21c298519aff2d52433c9.tar.xz
locking/rwsem: Remove the list_head from struct rw_semaphore
Instead of embedding a list_head in struct rw_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, 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 some core data structures like struct inode. 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-2-willy@infradead.org
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/rwsem.h8
1 files changed, 4 insertions, 4 deletions
diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h
index 9bf1d93d3d7b..e7829531c4ba 100644
--- a/include/linux/rwsem.h
+++ b/include/linux/rwsem.h
@@ -57,7 +57,7 @@ context_lock_struct(rw_semaphore) {
struct optimistic_spin_queue osq; /* spinner MCS lock */
#endif
raw_spinlock_t wait_lock;
- struct list_head wait_list;
+ struct rwsem_waiter *first_waiter;
#ifdef CONFIG_DEBUG_RWSEMS
void *magic;
#endif
@@ -106,7 +106,7 @@ static inline void rwsem_assert_held_write_nolockdep(const struct rw_semaphore *
.owner = ATOMIC_LONG_INIT(0), \
__RWSEM_OPT_INIT(name) \
.wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock),\
- .wait_list = LIST_HEAD_INIT((name).wait_list), \
+ .first_waiter = NULL, \
__RWSEM_DEBUG_INIT(name) \
__RWSEM_DEP_MAP_INIT(name) }
@@ -129,9 +129,9 @@ do { \
* rwsem to see if somebody from an incompatible type is wanting access to the
* lock.
*/
-static inline int rwsem_is_contended(struct rw_semaphore *sem)
+static inline bool rwsem_is_contended(struct rw_semaphore *sem)
{
- return !list_empty(&sem->wait_list);
+ return sem->first_waiter != NULL;
}
#if defined(CONFIG_DEBUG_RWSEMS) || defined(CONFIG_DETECT_HUNG_TASK_BLOCKER)