2#ifndef __LINUX_SEQLOCK_H
3#define __LINUX_SEQLOCK_H
40#define KCSAN_SEQLOCK_REGION_MAX 1000
52#ifdef CONFIG_DEBUG_LOCK_ALLOC
54# define SEQCOUNT_DEP_MAP_INIT(lockname) \
55 .dep_map = { .name = #lockname }
61# define seqcount_init(s) \
63 static struct lock_class_key __key; \
64 __seqcount_init((s), #s, &__key); \
72 local_irq_save(
flags);
73 seqcount_acquire_read(&l->dep_map, 0, 0,
_RET_IP_);
75 local_irq_restore(
flags);
79# define SEQCOUNT_DEP_MAP_INIT(lockname)
80# define seqcount_init(s) __seqcount_init(s, NULL, NULL)
81# define seqcount_lockdep_reader_access(x)
88#define SEQCNT_ZERO(name) { .sequence = 0, SEQCOUNT_DEP_MAP_INIT(name) }
124#define seqcount_LOCKNAME_init(s, _lock, lockname) \
126 seqcount_##lockname##_t *____s = (s); \
127 seqcount_init(&____s->seqcount); \
128 __SEQ_LOCK(____s->lock = (_lock)); \
131#define seqcount_raw_spinlock_init(s, lock) seqcount_LOCKNAME_init(s, lock, raw_spinlock)
132#define seqcount_spinlock_init(s, lock) seqcount_LOCKNAME_init(s, lock, spinlock)
133#define seqcount_rwlock_init(s, lock) seqcount_LOCKNAME_init(s, lock, rwlock)
134#define seqcount_mutex_init(s, lock) seqcount_LOCKNAME_init(s, lock, mutex)
145#define SEQCOUNT_LOCKNAME(lockname, locktype, preemptible, lockbase) \
146static __always_inline seqcount_t * \
147__seqprop_##lockname##_ptr(seqcount_##lockname##_t *s) \
149 return &s->seqcount; \
152static __always_inline const seqcount_t * \
153__seqprop_##lockname##_const_ptr(const seqcount_##lockname##_t *s) \
155 return &s->seqcount; \
158static __always_inline unsigned \
159__seqprop_##lockname##_sequence(const seqcount_##lockname##_t *s) \
161 unsigned seq = smp_load_acquire(&s->seqcount.sequence); \
163 if (!IS_ENABLED(CONFIG_PREEMPT_RT)) \
166 if (preemptible && unlikely(seq & 1)) { \
167 __SEQ_LOCK(lockbase##_lock(s->lock)); \
168 __SEQ_LOCK(lockbase##_unlock(s->lock)); \
174 seq = smp_load_acquire(&s->seqcount.sequence); \
180static __always_inline bool \
181__seqprop_##lockname##_preemptible(const seqcount_##lockname##_t *s) \
183 if (!IS_ENABLED(CONFIG_PREEMPT_RT)) \
184 return preemptible; \
190static __always_inline void \
191__seqprop_##lockname##_assert(const seqcount_##lockname##_t *s) \
193 __SEQ_LOCK(lockdep_assert_held(s->lock)); \
210static inline unsigned __seqprop_sequence(
const seqcount_t *s)
215static inline bool __seqprop_preemptible(
const seqcount_t *s)
220static inline void __seqprop_assert(
const seqcount_t *s)
225#define __SEQ_RT IS_ENABLED(CONFIG_PREEMPT_RT)
231#undef SEQCOUNT_LOCKNAME
239#define SEQCOUNT_LOCKNAME_ZERO(seq_name, assoc_lock) { \
240 .seqcount = SEQCNT_ZERO(seq_name.seqcount), \
241 __SEQ_LOCK(.lock = (assoc_lock)) \
244#define SEQCNT_RAW_SPINLOCK_ZERO(name, lock) SEQCOUNT_LOCKNAME_ZERO(name, lock)
245#define SEQCNT_SPINLOCK_ZERO(name, lock) SEQCOUNT_LOCKNAME_ZERO(name, lock)
246#define SEQCNT_RWLOCK_ZERO(name, lock) SEQCOUNT_LOCKNAME_ZERO(name, lock)
247#define SEQCNT_MUTEX_ZERO(name, lock) SEQCOUNT_LOCKNAME_ZERO(name, lock)
248#define SEQCNT_WW_MUTEX_ZERO(name, lock) SEQCOUNT_LOCKNAME_ZERO(name, lock)
250#define __seqprop_case(s, lockname, prop) \
251 seqcount_##lockname##_t: __seqprop_##lockname##_##prop
253#define __seqprop(s, prop) _Generic(*(s), \
254 seqcount_t: __seqprop_##prop, \
255 __seqprop_case((s), raw_spinlock, prop), \
256 __seqprop_case((s), spinlock, prop), \
257 __seqprop_case((s), rwlock, prop), \
258 __seqprop_case((s), mutex, prop))
260#define seqprop_ptr(s) __seqprop(s, ptr)(s)
261#define seqprop_const_ptr(s) __seqprop(s, const_ptr)(s)
262#define seqprop_sequence(s) __seqprop(s, sequence)(s)
263#define seqprop_preemptible(s) __seqprop(s, preemptible)(s)
264#define seqprop_assert(s) __seqprop(s, assert)(s)
272#define __read_seqcount_begin(s) \
276 while (unlikely((__seq = seqprop_sequence(s)) & 1)) \
279 kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX); \
289#define raw_read_seqcount_begin(s) __read_seqcount_begin(s)
297#define read_seqcount_begin(s) \
299 seqcount_lockdep_reader_access(seqprop_const_ptr(s)); \
300 raw_read_seqcount_begin(s); \
314#define raw_read_seqcount(s) \
316 unsigned __seq = seqprop_sequence(s); \
318 kcsan_atomic_next(KCSAN_SEQLOCK_REGION_MAX); \
339#define raw_seqcount_try_begin(s, start) \
341 start = raw_read_seqcount(s); \
362#define raw_seqcount_begin(s) \
368 raw_read_seqcount(s) & ~1; \
386#define __read_seqcount_retry(s, start) \
387 do___read_seqcount_retry(seqprop_const_ptr(s), start)
389static inline int do___read_seqcount_retry(
const seqcount_t *s,
unsigned start)
391 kcsan_atomic_next(0);
406#define read_seqcount_retry(s, start) \
407 do_read_seqcount_retry(seqprop_const_ptr(s), start)
409static inline int do_read_seqcount_retry(
const seqcount_t *s,
unsigned start)
412 return do___read_seqcount_retry(s, start);
421#define raw_write_seqcount_begin(s) \
423 if (seqprop_preemptible(s)) \
426 do_raw_write_seqcount_begin(seqprop_ptr(s)); \
429static inline void do_raw_write_seqcount_begin(
seqcount_t *s)
431 kcsan_nestable_atomic_begin();
442#define raw_write_seqcount_end(s) \
444 do_raw_write_seqcount_end(seqprop_ptr(s)); \
446 if (seqprop_preemptible(s)) \
450static inline void do_raw_write_seqcount_end(
seqcount_t *s)
454 kcsan_nestable_atomic_end();
466#define write_seqcount_begin_nested(s, subclass) \
470 if (seqprop_preemptible(s)) \
473 do_write_seqcount_begin_nested(seqprop_ptr(s), subclass); \
476static inline void do_write_seqcount_begin_nested(
seqcount_t *s,
int subclass)
479 do_raw_write_seqcount_begin(s);
492#define write_seqcount_begin(s) \
496 if (seqprop_preemptible(s)) \
499 do_write_seqcount_begin(seqprop_ptr(s)); \
502static inline void do_write_seqcount_begin(
seqcount_t *s)
504 do_write_seqcount_begin_nested(s, 0);
514#define write_seqcount_end(s) \
516 do_write_seqcount_end(seqprop_ptr(s)); \
518 if (seqprop_preemptible(s)) \
522static inline void do_write_seqcount_end(
seqcount_t *s)
525 do_raw_write_seqcount_end(s);
569#define raw_write_seqcount_barrier(s) \
570 do_raw_write_seqcount_barrier(seqprop_ptr(s))
572static inline void do_raw_write_seqcount_barrier(
seqcount_t *s)
574 kcsan_nestable_atomic_begin();
578 kcsan_nestable_atomic_end();
589#define write_seqcount_invalidate(s) \
590 do_write_seqcount_invalidate(seqprop_ptr(s))
592static inline void do_write_seqcount_invalidate(
seqcount_t *s)
595 kcsan_nestable_atomic_begin();
597 kcsan_nestable_atomic_end();
618#define SEQCNT_LATCH_ZERO(seq_name) { \
619 .seqcount = SEQCNT_ZERO(seq_name.seqcount), \
626#define seqcount_latch_init(s) seqcount_init(&(s)->seqcount)
662 return raw_read_seqcount_latch(s);
689 kcsan_atomic_next(0);
690 return raw_read_seqcount_latch_retry(s, start);
781 kcsan_nestable_atomic_begin();
782 raw_write_seqcount_latch(s);
791 raw_write_seqcount_latch(s);
803 kcsan_nestable_atomic_end();
806#define __SEQLOCK_UNLOCKED(lockname) \
808 .seqcount = SEQCNT_SPINLOCK_ZERO(lockname, &(lockname).lock), \
809 .lock = __SPIN_LOCK_UNLOCKED(lockname) \
816#define seqlock_init(sl) \
818 spin_lock_init(&(sl)->lock); \
819 seqcount_spinlock_init(&(sl)->seqcount, &(sl)->lock); \
826#define DEFINE_SEQLOCK(sl) \
827 seqlock_t sl = __SEQLOCK_UNLOCKED(sl)
835static inline unsigned read_seqbegin(
const seqlock_t *sl)
852static inline unsigned read_seqretry(
const seqlock_t *sl,
unsigned start)
877static inline void write_seqlock(
seqlock_t *sl)
881 do_write_seqcount_begin(&sl->seqcount.seqcount);
891static inline void write_sequnlock(
seqlock_t *sl)
894 do_write_seqcount_end(&sl->seqcount.seqcount);
905static inline void write_seqlock_bh(
seqlock_t *sl)
909 do_write_seqcount_begin(&sl->seqcount.seqcount);
920static inline void write_sequnlock_bh(
seqlock_t *sl)
923 do_write_seqcount_end(&sl->seqcount.seqcount);
934static inline void write_seqlock_irq(
seqlock_t *sl)
938 do_write_seqcount_begin(&sl->seqcount.seqcount);
948static inline void write_sequnlock_irq(
seqlock_t *sl)
951 do_write_seqcount_end(&sl->seqcount.seqcount);
955static inline unsigned long __write_seqlock_irqsave(
seqlock_t *sl)
961 do_write_seqcount_begin(&sl->seqcount.seqcount);
975#define write_seqlock_irqsave(lock, flags) \
976 do { flags = __write_seqlock_irqsave(lock); } while (0)
991 do_write_seqcount_end(&sl->seqcount.seqcount);
1011static inline void read_seqlock_excl(
seqlock_t *sl)
1021static inline void read_sequnlock_excl(
seqlock_t *sl)
1036static inline void read_seqlock_excl_bh(
seqlock_t *sl)
1047static inline void read_sequnlock_excl_bh(
seqlock_t *sl)
1062static inline void read_seqlock_excl_irq(
seqlock_t *sl)
1073static inline void read_sequnlock_excl_irq(
seqlock_t *sl)
1079static inline unsigned long __read_seqlock_excl_irqsave(
seqlock_t *sl)
1082 unsigned long flags;
1099#define read_seqlock_excl_irqsave(lock, flags) \
1100 do { flags = __read_seqlock_excl_irqsave(lock); } while (0)
1109read_sequnlock_excl_irqrestore(
seqlock_t *sl,
unsigned long flags)
1146static inline void read_seqbegin_or_lock(
seqlock_t *lock,
int *seq)
1150 *seq = read_seqbegin(lock);
1152 read_seqlock_excl(lock);
1162static inline int need_seqretry(
seqlock_t *lock,
int seq)
1165 return !(seq & 1) && read_seqretry(lock, seq);
1176static inline void done_seqretry(
seqlock_t *lock,
int seq)
1180 read_sequnlock_excl(lock);
1203static inline unsigned long
1204read_seqbegin_or_lock_irqsave(
seqlock_t *lock,
int *seq)
1207 unsigned long flags = 0;
1210 *seq = read_seqbegin(lock);
1230done_seqretry_irqrestore(
seqlock_t *lock,
int seq,
unsigned long flags)
1234 read_sequnlock_excl_irqrestore(lock,
flags);
1256 if (sst->lock_irqsave)
1262#if (defined(CONFIG_CC_IS_GCC) && CONFIG_GCC_VERSION < 90000) || \
1263 defined(CONFIG_KASAN) || defined(CONFIG_UBSAN_ALIGNMENT)
1285 switch (sst->state) {
1296 if (!read_seqretry(lock, sst->data)) {
1309 sst->lock = &lock->lock;
1315 sst->lock_irqsave = &lock->lock;
1321 sst->data = read_seqbegin(lock);
1334#define __scoped_seqlock_read(_seqlock, _target, _s) \
1335 for (struct ss_tmp _s __cleanup(__scoped_seqlock_cleanup) = \
1336 { .state = ss_lockless, .data = read_seqbegin(_seqlock) }, \
1337 *__UNIQUE_ID(ctx) __cleanup(__scoped_seqlock_cleanup_ctx) =\
1338 (struct ss_tmp *)_seqlock; \
1339 _s.state != ss_done; \
1340 __scoped_seqlock_next(&_s, _seqlock, _target))
1359#define scoped_seqlock_read(_seqlock, _target) \
1360 __scoped_seqlock_read(_seqlock, _target, __UNIQUE_ID(seqlock))
1364#define class_seqlock_init_constructor(_T) WITH_LOCK_GUARD_1_ATTRS(seqlock_init, _T)
uint8_t flags
Definition virtio.h:0
#define read
Definition acwin.h:180
#define DEFINE_LOCK_GUARD_1(_name, _type, _lock, _unlock,...)
Definition cleanup.h:255
#define DECLARE_LOCK_GUARD_1_ATTRS(_name, _lock, _unlock)
Definition cleanup.h:290
#define __acquires(...)
Definition compiler-context-analysis.h:299
#define __releases_shared(...)
Definition compiler-context-analysis.h:423
#define __no_context_analysis
Definition compiler-context-analysis.h:191
#define __releases(...)
Definition compiler-context-analysis.h:335
#define __acquires_shared(...)
Definition compiler-context-analysis.h:399
#define unlikely(x)
Definition compiler.h:30
#define __always_inline
Definition compiler_attributes.h:55
struct drm_crtc struct drm_plane struct drm_plane const struct drm_crtc_funcs const char * name
Definition drm_crtc.h:1242
#define _RET_IP_
Definition instruction_pointer.h:22
#define smp_load_acquire(p)
Definition kernel.h:611
#define READ_ONCE(x)
Definition kernel.h:605
#define smp_rmb()
Definition kernel.h:620
#define spin_unlock_irqrestore(l, f)
Definition kernel.h:227
#define spin_lock_irqsave(l, f)
Definition kernel.h:226
int spinlock_t
Definition kernel.h:44
#define smp_wmb()
Definition kernel.h:623
#define spin_lock(l)
Definition spinlock.h:36
#define spin_lock_bh(l)
Definition spinlock.h:40
#define spin_unlock_bh(l)
Definition spinlock.h:41
#define spin_unlock(l)
Definition spinlock.h:37
spinlock_t rwlock_t
Definition spinlock.h:200
#define spin_lock_irq(l)
Definition spinlock.h:38
#define spin_unlock_irq(l)
Definition spinlock.h:39
#define lockdep_assert_preemption_disabled()
Definition lockdep.h:77
#define lockdep_init_map(lock, name, key, sub)
Definition lockdep.h:57
#define seqcount_acquire(l, s, t, i)
Definition lockdep.h:62
#define seqcount_release(l, i)
Definition lockdep.h:63
void __scoped_seqlock_bug(void)
#define SEQCOUNT_LOCKNAME(lockname, locktype, preemptible, lockbase)
Definition seqlock.h:145
void __scoped_seqlock_invalid_target(void)
#define read_seqcount_retry(s, start)
Definition seqlock.h:400
#define seqlock_init(sl)
Definition seqlock.h:810
#define KCSAN_SEQLOCK_REGION_MAX
Definition seqlock.h:40
#define read_seqlock_excl_irqsave(lock, flags)
Definition seqlock.h:1093
#define seqcount_lockdep_reader_access(x)
Definition seqlock.h:81
ss_state
Definition seqlock.h:1231
@ ss_lock
Definition seqlock.h:1233
@ ss_done
Definition seqlock.h:1232
@ ss_lockless
Definition seqlock.h:1235
@ ss_lock_irqsave
Definition seqlock.h:1234
#define __SEQ_RT
Definition seqlock.h:222
#define read_seqcount_begin(s)
Definition seqlock.h:294
struct seqlock seqlock_t
Definition seqlock_types.h:108
Definition spinlock.h:210
seqcount_t seqcount
Definition seqlock.h:605
Definition seqlock_types.h:49
unsigned sequence
Definition seqlock_types.h:50
Definition seqlock.h:1238
unsigned long data
Definition seqlock.h:1240
enum ss_state state
Definition seqlock.h:1239
spinlock_t * lock
Definition seqlock.h:1241
spinlock_t * lock_irqsave
Definition seqlock.h:1242