Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
C
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495/* SPDX-License-Identifier: GPL-2.0 */#ifndef __LINUX_SEQLOCK_TYPES_H#define __LINUX_SEQLOCK_TYPES_H
#include <linux/lockdep_types.h>#include <linux/mutex_types.h>#include <linux/spinlock_types.h>
/* * Sequence counters (seqcount_t) * * This is the raw counting mechanism, without any writer protection. * * Write side critical sections must be serialized and non-preemptible. * * If readers can be invoked from hardirq or softirq contexts, * interrupts or bottom halves must also be respectively disabled before * entering the write section. * * This mechanism can't be used if the protected data contains pointers, * as the writer can invalidate a pointer that a reader is following. * * If the write serialization mechanism is one of the common kernel * locking primitives, use a sequence counter with associated lock * (seqcount_LOCKNAME_t) instead. * * If it's desired to automatically handle the sequence counter writer * serialization and non-preemptibility requirements, use a sequential * lock (seqlock_t) instead. * * See Documentation/locking/seqlock.rst */typedef struct seqcount { unsigned sequence;#ifdef CONFIG_DEBUG_LOCK_ALLOC struct lockdep_map dep_map;#endif} seqcount_t;
/* * For PREEMPT_RT, seqcount_LOCKNAME_t write side critical sections cannot * disable preemption. It can lead to higher latencies, and the write side * sections will not be able to acquire locks which become sleeping locks * (e.g. spinlock_t). * * To remain preemptible while avoiding a possible livelock caused by the * reader preempting the writer, use a different technique: let the reader * detect if a seqcount_LOCKNAME_t writer is in progress. If that is the * case, acquire then release the associated LOCKNAME writer serialization * lock. This will allow any possibly-preempted writer to make progress * until the end of its writer serialization lock critical section. * * This lock-unlock technique must be implemented for all of PREEMPT_RT * sleeping locks. See Documentation/locking/locktypes.rst */#if defined(CONFIG_LOCKDEP) || defined(CONFIG_PREEMPT_RT)#define __SEQ_LOCK(expr) expr#else#define __SEQ_LOCK(expr)#endif
#define SEQCOUNT_LOCKNAME(lockname, locktype, preemptible, lockbase) \typedef struct seqcount_##lockname { \ seqcount_t seqcount; \ __SEQ_LOCK(locktype *lock); \} seqcount_##lockname##_t;
SEQCOUNT_LOCKNAME(raw_spinlock, raw_spinlock_t, false, raw_spin)SEQCOUNT_LOCKNAME(spinlock, spinlock_t, __SEQ_RT, spin)SEQCOUNT_LOCKNAME(rwlock, rwlock_t, __SEQ_RT, read)SEQCOUNT_LOCKNAME(mutex, struct mutex, true, mutex)#undef SEQCOUNT_LOCKNAME
/* * Sequential locks (seqlock_t) * * Sequence counters with an embedded spinlock for writer serialization * and non-preemptibility. * * For more info, see: * - Comments on top of seqcount_t * - Documentation/locking/seqlock.rst */context_lock_struct(seqlock) { /* * Make sure that readers don't starve writers on PREEMPT_RT: use * seqcount_spinlock_t instead of seqcount_t. Check __SEQ_LOCK(). */ seqcount_spinlock_t seqcount; spinlock_t lock;};typedef struct seqlock seqlock_t;
#endif /* __LINUX_SEQLOCK_TYPES_H */