kernel/locking/rwsem.c
Source file repositories/reference/linux-study-clean/kernel/locking/rwsem.c
File Facts
- System
- Linux kernel
- Corpus path
kernel/locking/rwsem.c- Extension
.c- Size
- 48683 bytes
- Lines
- 1787
- Domain
- Core OS
- Bucket
- Scheduler, Processes, Timers, Sync, And Syscalls
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/types.hlinux/kernel.hlinux/sched.hlinux/sched/rt.hlinux/sched/task.hlinux/sched/debug.hlinux/sched/wake_q.hlinux/sched/signal.hlinux/sched/clock.hlinux/export.hlinux/rwsem.hlinux/atomic.hlinux/hung_task.htrace/events/lock.hlock_events.hrtmutex.crwbase_rt.c
Detected Declarations
struct rwsem_waiterenum rwsem_waiter_typeenum rwsem_wake_typeenum owner_statefunction bitfunction rwsem_clear_ownerfunction rwsem_test_oflagsfunction __rwsem_set_reader_ownedfunction rwsem_set_reader_ownedfunction is_rwsem_reader_ownedfunction up_read_non_ownerfunction rwsem_clear_reader_ownedfunction rwsem_read_trylockfunction rwsem_write_trylockfunction rwsem_owner_flagsfunction __init_rwsemfunction jiffyfunction rwsem_mark_wakefunction taskfunction rwsem_del_wake_waiterfunction rwsem_del_waiterfunction rwsem_try_write_lock_unqueuedfunction rwsem_can_spin_on_ownerfunction rwsem_owner_statefunction rwsem_spin_on_ownerfunction rwsem_rspin_thresholdfunction rwsem_optimistic_spinfunction sched_clockfunction rwsem_spin_on_ownerfunction clear_nonspinnablefunction rwsem_can_spin_on_ownerfunction rwsem_optimistic_spinfunction clear_nonspinnablefunction waiterfunction rwsem_down_read_slowpathfunction rwsem_down_write_slowpathfunction __down_read_commonfunction __down_readfunction __down_read_interruptiblefunction __down_read_killablefunction __down_read_trylockfunction __down_write_commonfunction __down_writefunction __down_write_killablefunction __down_write_trylockfunction __up_readfunction __up_writefunction __downgrade_write
Annotated Snippet
struct rwsem_waiter {
struct list_head list;
struct task_struct *task;
enum rwsem_waiter_type type;
unsigned long timeout;
bool handoff_set;
};
enum rwsem_wake_type {
RWSEM_WAKE_ANY, /* Wake whatever's at head of wait list */
RWSEM_WAKE_READERS, /* Wake readers only */
RWSEM_WAKE_READ_OWNED /* Waker thread holds the read lock */
};
/*
* The typical HZ value is either 250 or 1000. So set the minimum waiting
* time to at least 4ms or 1 jiffy (if it is higher than 4ms) in the wait
* queue before initiating the handoff protocol.
*/
#define RWSEM_WAIT_TIMEOUT DIV_ROUND_UP(HZ, 250)
/*
* Magic number to batch-wakeup waiting readers, even when writers are
* also present in the queue. This both limits the amount of work the
* waking thread must do and also prevents any potential counter overflow,
* however unlikely.
*/
#define MAX_READERS_WAKEUP 0x100
static inline
bool __rwsem_del_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter)
__must_hold(&sem->wait_lock)
{
if (list_empty(&waiter->list)) {
sem->first_waiter = NULL;
return false;
}
if (sem->first_waiter == waiter) {
sem->first_waiter = list_first_entry(&waiter->list,
struct rwsem_waiter, list);
}
list_del(&waiter->list);
return true;
}
/*
* Remove a waiter from the wait_list and clear flags.
*
* Both rwsem_mark_wake() and rwsem_try_write_lock() contain a full 'copy' of
* this function. Modify with care.
*
* Return: true if wait_list isn't empty and false otherwise
*/
static inline bool
rwsem_del_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter)
{
lockdep_assert_held(&sem->wait_lock);
if (__rwsem_del_waiter(sem, waiter))
return true;
atomic_long_andnot(RWSEM_FLAG_HANDOFF | RWSEM_FLAG_WAITERS, &sem->count);
return false;
}
static inline
struct rwsem_waiter *next_waiter(const struct rw_semaphore *sem,
const struct rwsem_waiter *waiter)
__must_hold(&sem->wait_lock)
{
struct rwsem_waiter *next = list_first_entry(&waiter->list,
struct rwsem_waiter, list);
if (next == sem->first_waiter)
return NULL;
return next;
}
/*
* handle the lock release when processes blocked on it that can now run
* - if we come here from up_xxxx(), then the RWSEM_FLAG_WAITERS bit must
* have been set.
* - there must be someone on the queue
* - the wait_lock must be held by the caller
* - tasks are marked for wakeup, the caller must later invoke wake_up_q()
* to actually wakeup the blocked task(s) and drop the reference count,
* preferably when the wait_lock is released
* - woken process blocks are discarded from the list after having task zeroed
* - writers are only marked woken if downgrading is false
*
* Implies rwsem_del_waiter() for all woken readers.
Annotation
- Immediate include surface: `linux/types.h`, `linux/kernel.h`, `linux/sched.h`, `linux/sched/rt.h`, `linux/sched/task.h`, `linux/sched/debug.h`, `linux/sched/wake_q.h`, `linux/sched/signal.h`.
- Detected declarations: `struct rwsem_waiter`, `enum rwsem_waiter_type`, `enum rwsem_wake_type`, `enum owner_state`, `function bit`, `function rwsem_clear_owner`, `function rwsem_test_oflags`, `function __rwsem_set_reader_owned`, `function rwsem_set_reader_owned`, `function is_rwsem_reader_owned`.
- Atlas domain: Core OS / Scheduler, Processes, Timers, Sync, And Syscalls.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.