0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/types.h>
0019 #include <linux/kernel.h>
0020 #include <linux/sched.h>
0021 #include <linux/sched/rt.h>
0022 #include <linux/sched/task.h>
0023 #include <linux/sched/debug.h>
0024 #include <linux/sched/wake_q.h>
0025 #include <linux/sched/signal.h>
0026 #include <linux/sched/clock.h>
0027 #include <linux/export.h>
0028 #include <linux/rwsem.h>
0029 #include <linux/atomic.h>
0030 #include <trace/events/lock.h>
0031
0032 #ifndef CONFIG_PREEMPT_RT
0033 #include "lock_events.h"
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 #define RWSEM_READER_OWNED (1UL << 0)
0064 #define RWSEM_NONSPINNABLE (1UL << 1)
0065 #define RWSEM_OWNER_FLAGS_MASK (RWSEM_READER_OWNED | RWSEM_NONSPINNABLE)
0066
0067 #ifdef CONFIG_DEBUG_RWSEMS
0068 # define DEBUG_RWSEMS_WARN_ON(c, sem) do { \
0069 if (!debug_locks_silent && \
0070 WARN_ONCE(c, "DEBUG_RWSEMS_WARN_ON(%s): count = 0x%lx, magic = 0x%lx, owner = 0x%lx, curr 0x%lx, list %sempty\n",\
0071 #c, atomic_long_read(&(sem)->count), \
0072 (unsigned long) sem->magic, \
0073 atomic_long_read(&(sem)->owner), (long)current, \
0074 list_empty(&(sem)->wait_list) ? "" : "not ")) \
0075 debug_locks_off(); \
0076 } while (0)
0077 #else
0078 # define DEBUG_RWSEMS_WARN_ON(c, sem)
0079 #endif
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 #define RWSEM_WRITER_LOCKED (1UL << 0)
0118 #define RWSEM_FLAG_WAITERS (1UL << 1)
0119 #define RWSEM_FLAG_HANDOFF (1UL << 2)
0120 #define RWSEM_FLAG_READFAIL (1UL << (BITS_PER_LONG - 1))
0121
0122 #define RWSEM_READER_SHIFT 8
0123 #define RWSEM_READER_BIAS (1UL << RWSEM_READER_SHIFT)
0124 #define RWSEM_READER_MASK (~(RWSEM_READER_BIAS - 1))
0125 #define RWSEM_WRITER_MASK RWSEM_WRITER_LOCKED
0126 #define RWSEM_LOCK_MASK (RWSEM_WRITER_MASK|RWSEM_READER_MASK)
0127 #define RWSEM_READ_FAILED_MASK (RWSEM_WRITER_MASK|RWSEM_FLAG_WAITERS|\
0128 RWSEM_FLAG_HANDOFF|RWSEM_FLAG_READFAIL)
0129
0130
0131
0132
0133
0134
0135
0136
0137 static inline void rwsem_set_owner(struct rw_semaphore *sem)
0138 {
0139 atomic_long_set(&sem->owner, (long)current);
0140 }
0141
0142 static inline void rwsem_clear_owner(struct rw_semaphore *sem)
0143 {
0144 atomic_long_set(&sem->owner, 0);
0145 }
0146
0147
0148
0149
0150 static inline bool rwsem_test_oflags(struct rw_semaphore *sem, long flags)
0151 {
0152 return atomic_long_read(&sem->owner) & flags;
0153 }
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165 static inline void __rwsem_set_reader_owned(struct rw_semaphore *sem,
0166 struct task_struct *owner)
0167 {
0168 unsigned long val = (unsigned long)owner | RWSEM_READER_OWNED |
0169 (atomic_long_read(&sem->owner) & RWSEM_NONSPINNABLE);
0170
0171 atomic_long_set(&sem->owner, val);
0172 }
0173
0174 static inline void rwsem_set_reader_owned(struct rw_semaphore *sem)
0175 {
0176 __rwsem_set_reader_owned(sem, current);
0177 }
0178
0179
0180
0181
0182 static inline bool is_rwsem_reader_owned(struct rw_semaphore *sem)
0183 {
0184 #ifdef CONFIG_DEBUG_RWSEMS
0185
0186
0187
0188 long count = atomic_long_read(&sem->count);
0189
0190 if (count & RWSEM_WRITER_MASK)
0191 return false;
0192 #endif
0193 return rwsem_test_oflags(sem, RWSEM_READER_OWNED);
0194 }
0195
0196 #ifdef CONFIG_DEBUG_RWSEMS
0197
0198
0199
0200
0201
0202
0203 static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem)
0204 {
0205 unsigned long val = atomic_long_read(&sem->owner);
0206
0207 while ((val & ~RWSEM_OWNER_FLAGS_MASK) == (unsigned long)current) {
0208 if (atomic_long_try_cmpxchg(&sem->owner, &val,
0209 val & RWSEM_OWNER_FLAGS_MASK))
0210 return;
0211 }
0212 }
0213 #else
0214 static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem)
0215 {
0216 }
0217 #endif
0218
0219
0220
0221
0222
0223 static inline void rwsem_set_nonspinnable(struct rw_semaphore *sem)
0224 {
0225 unsigned long owner = atomic_long_read(&sem->owner);
0226
0227 do {
0228 if (!(owner & RWSEM_READER_OWNED))
0229 break;
0230 if (owner & RWSEM_NONSPINNABLE)
0231 break;
0232 } while (!atomic_long_try_cmpxchg(&sem->owner, &owner,
0233 owner | RWSEM_NONSPINNABLE));
0234 }
0235
0236 static inline bool rwsem_read_trylock(struct rw_semaphore *sem, long *cntp)
0237 {
0238 *cntp = atomic_long_add_return_acquire(RWSEM_READER_BIAS, &sem->count);
0239
0240 if (WARN_ON_ONCE(*cntp < 0))
0241 rwsem_set_nonspinnable(sem);
0242
0243 if (!(*cntp & RWSEM_READ_FAILED_MASK)) {
0244 rwsem_set_reader_owned(sem);
0245 return true;
0246 }
0247
0248 return false;
0249 }
0250
0251 static inline bool rwsem_write_trylock(struct rw_semaphore *sem)
0252 {
0253 long tmp = RWSEM_UNLOCKED_VALUE;
0254
0255 if (atomic_long_try_cmpxchg_acquire(&sem->count, &tmp, RWSEM_WRITER_LOCKED)) {
0256 rwsem_set_owner(sem);
0257 return true;
0258 }
0259
0260 return false;
0261 }
0262
0263
0264
0265
0266 static inline struct task_struct *rwsem_owner(struct rw_semaphore *sem)
0267 {
0268 return (struct task_struct *)
0269 (atomic_long_read(&sem->owner) & ~RWSEM_OWNER_FLAGS_MASK);
0270 }
0271
0272
0273
0274
0275
0276 static inline struct task_struct *
0277 rwsem_owner_flags(struct rw_semaphore *sem, unsigned long *pflags)
0278 {
0279 unsigned long owner = atomic_long_read(&sem->owner);
0280
0281 *pflags = owner & RWSEM_OWNER_FLAGS_MASK;
0282 return (struct task_struct *)(owner & ~RWSEM_OWNER_FLAGS_MASK);
0283 }
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305 void __init_rwsem(struct rw_semaphore *sem, const char *name,
0306 struct lock_class_key *key)
0307 {
0308 #ifdef CONFIG_DEBUG_LOCK_ALLOC
0309
0310
0311
0312 debug_check_no_locks_freed((void *)sem, sizeof(*sem));
0313 lockdep_init_map_wait(&sem->dep_map, name, key, 0, LD_WAIT_SLEEP);
0314 #endif
0315 #ifdef CONFIG_DEBUG_RWSEMS
0316 sem->magic = sem;
0317 #endif
0318 atomic_long_set(&sem->count, RWSEM_UNLOCKED_VALUE);
0319 raw_spin_lock_init(&sem->wait_lock);
0320 INIT_LIST_HEAD(&sem->wait_list);
0321 atomic_long_set(&sem->owner, 0L);
0322 #ifdef CONFIG_RWSEM_SPIN_ON_OWNER
0323 osq_lock_init(&sem->osq);
0324 #endif
0325 }
0326 EXPORT_SYMBOL(__init_rwsem);
0327
0328 enum rwsem_waiter_type {
0329 RWSEM_WAITING_FOR_WRITE,
0330 RWSEM_WAITING_FOR_READ
0331 };
0332
0333 struct rwsem_waiter {
0334 struct list_head list;
0335 struct task_struct *task;
0336 enum rwsem_waiter_type type;
0337 unsigned long timeout;
0338 bool handoff_set;
0339 };
0340 #define rwsem_first_waiter(sem) \
0341 list_first_entry(&sem->wait_list, struct rwsem_waiter, list)
0342
0343 enum rwsem_wake_type {
0344 RWSEM_WAKE_ANY,
0345 RWSEM_WAKE_READERS,
0346 RWSEM_WAKE_READ_OWNED
0347 };
0348
0349
0350
0351
0352
0353
0354 #define RWSEM_WAIT_TIMEOUT DIV_ROUND_UP(HZ, 250)
0355
0356
0357
0358
0359
0360
0361
0362 #define MAX_READERS_WAKEUP 0x100
0363
0364 static inline void
0365 rwsem_add_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter)
0366 {
0367 lockdep_assert_held(&sem->wait_lock);
0368 list_add_tail(&waiter->list, &sem->wait_list);
0369
0370 }
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380 static inline bool
0381 rwsem_del_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter)
0382 {
0383 lockdep_assert_held(&sem->wait_lock);
0384 list_del(&waiter->list);
0385 if (likely(!list_empty(&sem->wait_list)))
0386 return true;
0387
0388 atomic_long_andnot(RWSEM_FLAG_HANDOFF | RWSEM_FLAG_WAITERS, &sem->count);
0389 return false;
0390 }
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406 static void rwsem_mark_wake(struct rw_semaphore *sem,
0407 enum rwsem_wake_type wake_type,
0408 struct wake_q_head *wake_q)
0409 {
0410 struct rwsem_waiter *waiter, *tmp;
0411 long oldcount, woken = 0, adjustment = 0;
0412 struct list_head wlist;
0413
0414 lockdep_assert_held(&sem->wait_lock);
0415
0416
0417
0418
0419
0420 waiter = rwsem_first_waiter(sem);
0421
0422 if (waiter->type == RWSEM_WAITING_FOR_WRITE) {
0423 if (wake_type == RWSEM_WAKE_ANY) {
0424
0425
0426
0427
0428
0429
0430
0431 wake_q_add(wake_q, waiter->task);
0432 lockevent_inc(rwsem_wake_writer);
0433 }
0434
0435 return;
0436 }
0437
0438
0439
0440
0441 if (unlikely(atomic_long_read(&sem->count) < 0))
0442 return;
0443
0444
0445
0446
0447
0448
0449 if (wake_type != RWSEM_WAKE_READ_OWNED) {
0450 struct task_struct *owner;
0451
0452 adjustment = RWSEM_READER_BIAS;
0453 oldcount = atomic_long_fetch_add(adjustment, &sem->count);
0454 if (unlikely(oldcount & RWSEM_WRITER_MASK)) {
0455
0456
0457
0458
0459
0460 if (time_after(jiffies, waiter->timeout)) {
0461 if (!(oldcount & RWSEM_FLAG_HANDOFF)) {
0462 adjustment -= RWSEM_FLAG_HANDOFF;
0463 lockevent_inc(rwsem_rlock_handoff);
0464 }
0465 waiter->handoff_set = true;
0466 }
0467
0468 atomic_long_add(-adjustment, &sem->count);
0469 return;
0470 }
0471
0472
0473
0474
0475
0476
0477 owner = waiter->task;
0478 __rwsem_set_reader_owned(sem, owner);
0479 }
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504 INIT_LIST_HEAD(&wlist);
0505 list_for_each_entry_safe(waiter, tmp, &sem->wait_list, list) {
0506 if (waiter->type == RWSEM_WAITING_FOR_WRITE)
0507 continue;
0508
0509 woken++;
0510 list_move_tail(&waiter->list, &wlist);
0511
0512
0513
0514
0515 if (unlikely(woken >= MAX_READERS_WAKEUP))
0516 break;
0517 }
0518
0519 adjustment = woken * RWSEM_READER_BIAS - adjustment;
0520 lockevent_cond_inc(rwsem_wake_reader, woken);
0521
0522 oldcount = atomic_long_read(&sem->count);
0523 if (list_empty(&sem->wait_list)) {
0524
0525
0526
0527
0528 adjustment -= RWSEM_FLAG_WAITERS;
0529 if (oldcount & RWSEM_FLAG_HANDOFF)
0530 adjustment -= RWSEM_FLAG_HANDOFF;
0531 } else if (woken) {
0532
0533
0534
0535
0536 if (oldcount & RWSEM_FLAG_HANDOFF)
0537 adjustment -= RWSEM_FLAG_HANDOFF;
0538 }
0539
0540 if (adjustment)
0541 atomic_long_add(adjustment, &sem->count);
0542
0543
0544 list_for_each_entry_safe(waiter, tmp, &wlist, list) {
0545 struct task_struct *tsk;
0546
0547 tsk = waiter->task;
0548 get_task_struct(tsk);
0549
0550
0551
0552
0553
0554
0555
0556 smp_store_release(&waiter->task, NULL);
0557
0558
0559
0560
0561 wake_q_add_safe(wake_q, tsk);
0562 }
0563 }
0564
0565
0566
0567
0568
0569
0570
0571 static inline void
0572 rwsem_del_wake_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter,
0573 struct wake_q_head *wake_q)
0574 __releases(&sem->wait_lock)
0575 {
0576 bool first = rwsem_first_waiter(sem) == waiter;
0577
0578 wake_q_init(wake_q);
0579
0580
0581
0582
0583
0584
0585 if (rwsem_del_waiter(sem, waiter) && first)
0586 rwsem_mark_wake(sem, RWSEM_WAKE_ANY, wake_q);
0587 raw_spin_unlock_irq(&sem->wait_lock);
0588 if (!wake_q_empty(wake_q))
0589 wake_up_q(wake_q);
0590 }
0591
0592
0593
0594
0595
0596
0597
0598
0599 static inline bool rwsem_try_write_lock(struct rw_semaphore *sem,
0600 struct rwsem_waiter *waiter)
0601 {
0602 struct rwsem_waiter *first = rwsem_first_waiter(sem);
0603 long count, new;
0604
0605 lockdep_assert_held(&sem->wait_lock);
0606
0607 count = atomic_long_read(&sem->count);
0608 do {
0609 bool has_handoff = !!(count & RWSEM_FLAG_HANDOFF);
0610
0611 if (has_handoff) {
0612
0613
0614
0615
0616
0617 if (first->handoff_set && (waiter != first))
0618 return false;
0619
0620
0621
0622
0623
0624 if (waiter == first)
0625 waiter->handoff_set = true;
0626 }
0627
0628 new = count;
0629
0630 if (count & RWSEM_LOCK_MASK) {
0631 if (has_handoff || (!rt_task(waiter->task) &&
0632 !time_after(jiffies, waiter->timeout)))
0633 return false;
0634
0635 new |= RWSEM_FLAG_HANDOFF;
0636 } else {
0637 new |= RWSEM_WRITER_LOCKED;
0638 new &= ~RWSEM_FLAG_HANDOFF;
0639
0640 if (list_is_singular(&sem->wait_list))
0641 new &= ~RWSEM_FLAG_WAITERS;
0642 }
0643 } while (!atomic_long_try_cmpxchg_acquire(&sem->count, &count, new));
0644
0645
0646
0647
0648
0649 if (new & RWSEM_FLAG_HANDOFF) {
0650 waiter->handoff_set = true;
0651 lockevent_inc(rwsem_wlock_handoff);
0652 return false;
0653 }
0654
0655
0656
0657
0658
0659 list_del(&waiter->list);
0660 rwsem_set_owner(sem);
0661 return true;
0662 }
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675 enum owner_state {
0676 OWNER_NULL = 1 << 0,
0677 OWNER_WRITER = 1 << 1,
0678 OWNER_READER = 1 << 2,
0679 OWNER_NONSPINNABLE = 1 << 3,
0680 };
0681
0682 #ifdef CONFIG_RWSEM_SPIN_ON_OWNER
0683
0684
0685
0686 static inline bool rwsem_try_write_lock_unqueued(struct rw_semaphore *sem)
0687 {
0688 long count = atomic_long_read(&sem->count);
0689
0690 while (!(count & (RWSEM_LOCK_MASK|RWSEM_FLAG_HANDOFF))) {
0691 if (atomic_long_try_cmpxchg_acquire(&sem->count, &count,
0692 count | RWSEM_WRITER_LOCKED)) {
0693 rwsem_set_owner(sem);
0694 lockevent_inc(rwsem_opt_lock);
0695 return true;
0696 }
0697 }
0698 return false;
0699 }
0700
0701 static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem)
0702 {
0703 struct task_struct *owner;
0704 unsigned long flags;
0705 bool ret = true;
0706
0707 if (need_resched()) {
0708 lockevent_inc(rwsem_opt_fail);
0709 return false;
0710 }
0711
0712 preempt_disable();
0713
0714
0715
0716
0717 owner = rwsem_owner_flags(sem, &flags);
0718
0719
0720
0721 if ((flags & RWSEM_NONSPINNABLE) ||
0722 (owner && !(flags & RWSEM_READER_OWNED) && !owner_on_cpu(owner)))
0723 ret = false;
0724 preempt_enable();
0725
0726 lockevent_cond_inc(rwsem_opt_fail, !ret);
0727 return ret;
0728 }
0729
0730 #define OWNER_SPINNABLE (OWNER_NULL | OWNER_WRITER | OWNER_READER)
0731
0732 static inline enum owner_state
0733 rwsem_owner_state(struct task_struct *owner, unsigned long flags)
0734 {
0735 if (flags & RWSEM_NONSPINNABLE)
0736 return OWNER_NONSPINNABLE;
0737
0738 if (flags & RWSEM_READER_OWNED)
0739 return OWNER_READER;
0740
0741 return owner ? OWNER_WRITER : OWNER_NULL;
0742 }
0743
0744 static noinline enum owner_state
0745 rwsem_spin_on_owner(struct rw_semaphore *sem)
0746 {
0747 struct task_struct *new, *owner;
0748 unsigned long flags, new_flags;
0749 enum owner_state state;
0750
0751 lockdep_assert_preemption_disabled();
0752
0753 owner = rwsem_owner_flags(sem, &flags);
0754 state = rwsem_owner_state(owner, flags);
0755 if (state != OWNER_WRITER)
0756 return state;
0757
0758 for (;;) {
0759
0760
0761
0762
0763
0764
0765 new = rwsem_owner_flags(sem, &new_flags);
0766 if ((new != owner) || (new_flags != flags)) {
0767 state = rwsem_owner_state(new, new_flags);
0768 break;
0769 }
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779 barrier();
0780
0781 if (need_resched() || !owner_on_cpu(owner)) {
0782 state = OWNER_NONSPINNABLE;
0783 break;
0784 }
0785
0786 cpu_relax();
0787 }
0788
0789 return state;
0790 }
0791
0792
0793
0794
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804 static inline u64 rwsem_rspin_threshold(struct rw_semaphore *sem)
0805 {
0806 long count = atomic_long_read(&sem->count);
0807 int readers = count >> RWSEM_READER_SHIFT;
0808 u64 delta;
0809
0810 if (readers > 30)
0811 readers = 30;
0812 delta = (20 + readers) * NSEC_PER_USEC / 2;
0813
0814 return sched_clock() + delta;
0815 }
0816
0817 static bool rwsem_optimistic_spin(struct rw_semaphore *sem)
0818 {
0819 bool taken = false;
0820 int prev_owner_state = OWNER_NULL;
0821 int loop = 0;
0822 u64 rspin_threshold = 0;
0823
0824 preempt_disable();
0825
0826
0827 if (!osq_lock(&sem->osq))
0828 goto done;
0829
0830
0831
0832
0833
0834
0835
0836 for (;;) {
0837 enum owner_state owner_state;
0838
0839 owner_state = rwsem_spin_on_owner(sem);
0840 if (!(owner_state & OWNER_SPINNABLE))
0841 break;
0842
0843
0844
0845
0846 taken = rwsem_try_write_lock_unqueued(sem);
0847
0848 if (taken)
0849 break;
0850
0851
0852
0853
0854 if (owner_state == OWNER_READER) {
0855
0856
0857
0858
0859
0860
0861
0862 if (prev_owner_state != OWNER_READER) {
0863 if (rwsem_test_oflags(sem, RWSEM_NONSPINNABLE))
0864 break;
0865 rspin_threshold = rwsem_rspin_threshold(sem);
0866 loop = 0;
0867 }
0868
0869
0870
0871
0872
0873
0874
0875
0876 else if (!(++loop & 0xf) && (sched_clock() > rspin_threshold)) {
0877 rwsem_set_nonspinnable(sem);
0878 lockevent_inc(rwsem_opt_nospin);
0879 break;
0880 }
0881 }
0882
0883
0884
0885
0886
0887
0888
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914 if (owner_state != OWNER_WRITER) {
0915 if (need_resched())
0916 break;
0917 if (rt_task(current) &&
0918 (prev_owner_state != OWNER_WRITER))
0919 break;
0920 }
0921 prev_owner_state = owner_state;
0922
0923
0924
0925
0926
0927
0928
0929 cpu_relax();
0930 }
0931 osq_unlock(&sem->osq);
0932 done:
0933 preempt_enable();
0934 lockevent_cond_inc(rwsem_opt_fail, !taken);
0935 return taken;
0936 }
0937
0938
0939
0940
0941
0942 static inline void clear_nonspinnable(struct rw_semaphore *sem)
0943 {
0944 if (unlikely(rwsem_test_oflags(sem, RWSEM_NONSPINNABLE)))
0945 atomic_long_andnot(RWSEM_NONSPINNABLE, &sem->owner);
0946 }
0947
0948 #else
0949 static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem)
0950 {
0951 return false;
0952 }
0953
0954 static inline bool rwsem_optimistic_spin(struct rw_semaphore *sem)
0955 {
0956 return false;
0957 }
0958
0959 static inline void clear_nonspinnable(struct rw_semaphore *sem) { }
0960
0961 static inline enum owner_state
0962 rwsem_spin_on_owner(struct rw_semaphore *sem)
0963 {
0964 return OWNER_NONSPINNABLE;
0965 }
0966 #endif
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976 static inline void rwsem_cond_wake_waiter(struct rw_semaphore *sem, long count,
0977 struct wake_q_head *wake_q)
0978 {
0979 enum rwsem_wake_type wake_type;
0980
0981 if (count & RWSEM_WRITER_MASK)
0982 return;
0983
0984 if (count & RWSEM_READER_MASK) {
0985 wake_type = RWSEM_WAKE_READERS;
0986 } else {
0987 wake_type = RWSEM_WAKE_ANY;
0988 clear_nonspinnable(sem);
0989 }
0990 rwsem_mark_wake(sem, wake_type, wake_q);
0991 }
0992
0993
0994
0995
0996 static struct rw_semaphore __sched *
0997 rwsem_down_read_slowpath(struct rw_semaphore *sem, long count, unsigned int state)
0998 {
0999 long adjustment = -RWSEM_READER_BIAS;
1000 long rcnt = (count >> RWSEM_READER_SHIFT);
1001 struct rwsem_waiter waiter;
1002 DEFINE_WAKE_Q(wake_q);
1003
1004
1005
1006
1007
1008
1009 if ((atomic_long_read(&sem->owner) & RWSEM_READER_OWNED) &&
1010 (rcnt > 1) && !(count & RWSEM_WRITER_LOCKED))
1011 goto queue;
1012
1013
1014
1015
1016 if (!(count & (RWSEM_WRITER_LOCKED | RWSEM_FLAG_HANDOFF))) {
1017 rwsem_set_reader_owned(sem);
1018 lockevent_inc(rwsem_rlock_steal);
1019
1020
1021
1022
1023
1024 if ((rcnt == 1) && (count & RWSEM_FLAG_WAITERS)) {
1025 raw_spin_lock_irq(&sem->wait_lock);
1026 if (!list_empty(&sem->wait_list))
1027 rwsem_mark_wake(sem, RWSEM_WAKE_READ_OWNED,
1028 &wake_q);
1029 raw_spin_unlock_irq(&sem->wait_lock);
1030 wake_up_q(&wake_q);
1031 }
1032 return sem;
1033 }
1034
1035 queue:
1036 waiter.task = current;
1037 waiter.type = RWSEM_WAITING_FOR_READ;
1038 waiter.timeout = jiffies + RWSEM_WAIT_TIMEOUT;
1039 waiter.handoff_set = false;
1040
1041 raw_spin_lock_irq(&sem->wait_lock);
1042 if (list_empty(&sem->wait_list)) {
1043
1044
1045
1046
1047
1048
1049 if (!(atomic_long_read(&sem->count) & RWSEM_WRITER_MASK)) {
1050
1051 smp_acquire__after_ctrl_dep();
1052 raw_spin_unlock_irq(&sem->wait_lock);
1053 rwsem_set_reader_owned(sem);
1054 lockevent_inc(rwsem_rlock_fast);
1055 return sem;
1056 }
1057 adjustment += RWSEM_FLAG_WAITERS;
1058 }
1059 rwsem_add_waiter(sem, &waiter);
1060
1061
1062 count = atomic_long_add_return(adjustment, &sem->count);
1063
1064 rwsem_cond_wake_waiter(sem, count, &wake_q);
1065 raw_spin_unlock_irq(&sem->wait_lock);
1066
1067 if (!wake_q_empty(&wake_q))
1068 wake_up_q(&wake_q);
1069
1070 trace_contention_begin(sem, LCB_F_READ);
1071
1072
1073 for (;;) {
1074 set_current_state(state);
1075 if (!smp_load_acquire(&waiter.task)) {
1076
1077 break;
1078 }
1079 if (signal_pending_state(state, current)) {
1080 raw_spin_lock_irq(&sem->wait_lock);
1081 if (waiter.task)
1082 goto out_nolock;
1083 raw_spin_unlock_irq(&sem->wait_lock);
1084
1085 break;
1086 }
1087 schedule();
1088 lockevent_inc(rwsem_sleep_reader);
1089 }
1090
1091 __set_current_state(TASK_RUNNING);
1092 lockevent_inc(rwsem_rlock);
1093 trace_contention_end(sem, 0);
1094 return sem;
1095
1096 out_nolock:
1097 rwsem_del_wake_waiter(sem, &waiter, &wake_q);
1098 __set_current_state(TASK_RUNNING);
1099 lockevent_inc(rwsem_rlock_fail);
1100 trace_contention_end(sem, -EINTR);
1101 return ERR_PTR(-EINTR);
1102 }
1103
1104
1105
1106
1107 static struct rw_semaphore __sched *
1108 rwsem_down_write_slowpath(struct rw_semaphore *sem, int state)
1109 {
1110 struct rwsem_waiter waiter;
1111 DEFINE_WAKE_Q(wake_q);
1112
1113
1114 if (rwsem_can_spin_on_owner(sem) && rwsem_optimistic_spin(sem)) {
1115
1116 return sem;
1117 }
1118
1119
1120
1121
1122
1123 waiter.task = current;
1124 waiter.type = RWSEM_WAITING_FOR_WRITE;
1125 waiter.timeout = jiffies + RWSEM_WAIT_TIMEOUT;
1126 waiter.handoff_set = false;
1127
1128 raw_spin_lock_irq(&sem->wait_lock);
1129 rwsem_add_waiter(sem, &waiter);
1130
1131
1132 if (rwsem_first_waiter(sem) != &waiter) {
1133 rwsem_cond_wake_waiter(sem, atomic_long_read(&sem->count),
1134 &wake_q);
1135 if (!wake_q_empty(&wake_q)) {
1136
1137
1138
1139
1140 raw_spin_unlock_irq(&sem->wait_lock);
1141 wake_up_q(&wake_q);
1142 raw_spin_lock_irq(&sem->wait_lock);
1143 }
1144 } else {
1145 atomic_long_or(RWSEM_FLAG_WAITERS, &sem->count);
1146 }
1147
1148
1149 set_current_state(state);
1150 trace_contention_begin(sem, LCB_F_WRITE);
1151
1152 for (;;) {
1153 if (rwsem_try_write_lock(sem, &waiter)) {
1154
1155 break;
1156 }
1157
1158 raw_spin_unlock_irq(&sem->wait_lock);
1159
1160 if (signal_pending_state(state, current))
1161 goto out_nolock;
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171 if (waiter.handoff_set) {
1172 enum owner_state owner_state;
1173
1174 preempt_disable();
1175 owner_state = rwsem_spin_on_owner(sem);
1176 preempt_enable();
1177
1178 if (owner_state == OWNER_NULL)
1179 goto trylock_again;
1180 }
1181
1182 schedule();
1183 lockevent_inc(rwsem_sleep_writer);
1184 set_current_state(state);
1185 trylock_again:
1186 raw_spin_lock_irq(&sem->wait_lock);
1187 }
1188 __set_current_state(TASK_RUNNING);
1189 raw_spin_unlock_irq(&sem->wait_lock);
1190 lockevent_inc(rwsem_wlock);
1191 trace_contention_end(sem, 0);
1192 return sem;
1193
1194 out_nolock:
1195 __set_current_state(TASK_RUNNING);
1196 raw_spin_lock_irq(&sem->wait_lock);
1197 rwsem_del_wake_waiter(sem, &waiter, &wake_q);
1198 lockevent_inc(rwsem_wlock_fail);
1199 trace_contention_end(sem, -EINTR);
1200 return ERR_PTR(-EINTR);
1201 }
1202
1203
1204
1205
1206
1207 static struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem)
1208 {
1209 unsigned long flags;
1210 DEFINE_WAKE_Q(wake_q);
1211
1212 raw_spin_lock_irqsave(&sem->wait_lock, flags);
1213
1214 if (!list_empty(&sem->wait_list))
1215 rwsem_mark_wake(sem, RWSEM_WAKE_ANY, &wake_q);
1216
1217 raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
1218 wake_up_q(&wake_q);
1219
1220 return sem;
1221 }
1222
1223
1224
1225
1226
1227
1228 static struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem)
1229 {
1230 unsigned long flags;
1231 DEFINE_WAKE_Q(wake_q);
1232
1233 raw_spin_lock_irqsave(&sem->wait_lock, flags);
1234
1235 if (!list_empty(&sem->wait_list))
1236 rwsem_mark_wake(sem, RWSEM_WAKE_READ_OWNED, &wake_q);
1237
1238 raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
1239 wake_up_q(&wake_q);
1240
1241 return sem;
1242 }
1243
1244
1245
1246
1247 static inline int __down_read_common(struct rw_semaphore *sem, int state)
1248 {
1249 long count;
1250
1251 if (!rwsem_read_trylock(sem, &count)) {
1252 if (IS_ERR(rwsem_down_read_slowpath(sem, count, state)))
1253 return -EINTR;
1254 DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem);
1255 }
1256 return 0;
1257 }
1258
1259 static inline void __down_read(struct rw_semaphore *sem)
1260 {
1261 __down_read_common(sem, TASK_UNINTERRUPTIBLE);
1262 }
1263
1264 static inline int __down_read_interruptible(struct rw_semaphore *sem)
1265 {
1266 return __down_read_common(sem, TASK_INTERRUPTIBLE);
1267 }
1268
1269 static inline int __down_read_killable(struct rw_semaphore *sem)
1270 {
1271 return __down_read_common(sem, TASK_KILLABLE);
1272 }
1273
1274 static inline int __down_read_trylock(struct rw_semaphore *sem)
1275 {
1276 long tmp;
1277
1278 DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem);
1279
1280 tmp = atomic_long_read(&sem->count);
1281 while (!(tmp & RWSEM_READ_FAILED_MASK)) {
1282 if (atomic_long_try_cmpxchg_acquire(&sem->count, &tmp,
1283 tmp + RWSEM_READER_BIAS)) {
1284 rwsem_set_reader_owned(sem);
1285 return 1;
1286 }
1287 }
1288 return 0;
1289 }
1290
1291
1292
1293
1294 static inline int __down_write_common(struct rw_semaphore *sem, int state)
1295 {
1296 if (unlikely(!rwsem_write_trylock(sem))) {
1297 if (IS_ERR(rwsem_down_write_slowpath(sem, state)))
1298 return -EINTR;
1299 }
1300
1301 return 0;
1302 }
1303
1304 static inline void __down_write(struct rw_semaphore *sem)
1305 {
1306 __down_write_common(sem, TASK_UNINTERRUPTIBLE);
1307 }
1308
1309 static inline int __down_write_killable(struct rw_semaphore *sem)
1310 {
1311 return __down_write_common(sem, TASK_KILLABLE);
1312 }
1313
1314 static inline int __down_write_trylock(struct rw_semaphore *sem)
1315 {
1316 DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem);
1317 return rwsem_write_trylock(sem);
1318 }
1319
1320
1321
1322
1323 static inline void __up_read(struct rw_semaphore *sem)
1324 {
1325 long tmp;
1326
1327 DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem);
1328 DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem);
1329
1330 rwsem_clear_reader_owned(sem);
1331 tmp = atomic_long_add_return_release(-RWSEM_READER_BIAS, &sem->count);
1332 DEBUG_RWSEMS_WARN_ON(tmp < 0, sem);
1333 if (unlikely((tmp & (RWSEM_LOCK_MASK|RWSEM_FLAG_WAITERS)) ==
1334 RWSEM_FLAG_WAITERS)) {
1335 clear_nonspinnable(sem);
1336 rwsem_wake(sem);
1337 }
1338 }
1339
1340
1341
1342
1343 static inline void __up_write(struct rw_semaphore *sem)
1344 {
1345 long tmp;
1346
1347 DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem);
1348
1349
1350
1351
1352 DEBUG_RWSEMS_WARN_ON((rwsem_owner(sem) != current) &&
1353 !rwsem_test_oflags(sem, RWSEM_NONSPINNABLE), sem);
1354
1355 rwsem_clear_owner(sem);
1356 tmp = atomic_long_fetch_add_release(-RWSEM_WRITER_LOCKED, &sem->count);
1357 if (unlikely(tmp & RWSEM_FLAG_WAITERS))
1358 rwsem_wake(sem);
1359 }
1360
1361
1362
1363
1364 static inline void __downgrade_write(struct rw_semaphore *sem)
1365 {
1366 long tmp;
1367
1368
1369
1370
1371
1372
1373
1374
1375 DEBUG_RWSEMS_WARN_ON(rwsem_owner(sem) != current, sem);
1376 tmp = atomic_long_fetch_add_release(
1377 -RWSEM_WRITER_LOCKED+RWSEM_READER_BIAS, &sem->count);
1378 rwsem_set_reader_owned(sem);
1379 if (tmp & RWSEM_FLAG_WAITERS)
1380 rwsem_downgrade_wake(sem);
1381 }
1382
1383 #else
1384
1385 #define RT_MUTEX_BUILD_MUTEX
1386 #include "rtmutex.c"
1387
1388 #define rwbase_set_and_save_current_state(state) \
1389 set_current_state(state)
1390
1391 #define rwbase_restore_current_state() \
1392 __set_current_state(TASK_RUNNING)
1393
1394 #define rwbase_rtmutex_lock_state(rtm, state) \
1395 __rt_mutex_lock(rtm, state)
1396
1397 #define rwbase_rtmutex_slowlock_locked(rtm, state) \
1398 __rt_mutex_slowlock_locked(rtm, NULL, state)
1399
1400 #define rwbase_rtmutex_unlock(rtm) \
1401 __rt_mutex_unlock(rtm)
1402
1403 #define rwbase_rtmutex_trylock(rtm) \
1404 __rt_mutex_trylock(rtm)
1405
1406 #define rwbase_signal_pending_state(state, current) \
1407 signal_pending_state(state, current)
1408
1409 #define rwbase_schedule() \
1410 schedule()
1411
1412 #include "rwbase_rt.c"
1413
1414 void __init_rwsem(struct rw_semaphore *sem, const char *name,
1415 struct lock_class_key *key)
1416 {
1417 init_rwbase_rt(&(sem)->rwbase);
1418
1419 #ifdef CONFIG_DEBUG_LOCK_ALLOC
1420 debug_check_no_locks_freed((void *)sem, sizeof(*sem));
1421 lockdep_init_map_wait(&sem->dep_map, name, key, 0, LD_WAIT_SLEEP);
1422 #endif
1423 }
1424 EXPORT_SYMBOL(__init_rwsem);
1425
1426 static inline void __down_read(struct rw_semaphore *sem)
1427 {
1428 rwbase_read_lock(&sem->rwbase, TASK_UNINTERRUPTIBLE);
1429 }
1430
1431 static inline int __down_read_interruptible(struct rw_semaphore *sem)
1432 {
1433 return rwbase_read_lock(&sem->rwbase, TASK_INTERRUPTIBLE);
1434 }
1435
1436 static inline int __down_read_killable(struct rw_semaphore *sem)
1437 {
1438 return rwbase_read_lock(&sem->rwbase, TASK_KILLABLE);
1439 }
1440
1441 static inline int __down_read_trylock(struct rw_semaphore *sem)
1442 {
1443 return rwbase_read_trylock(&sem->rwbase);
1444 }
1445
1446 static inline void __up_read(struct rw_semaphore *sem)
1447 {
1448 rwbase_read_unlock(&sem->rwbase, TASK_NORMAL);
1449 }
1450
1451 static inline void __sched __down_write(struct rw_semaphore *sem)
1452 {
1453 rwbase_write_lock(&sem->rwbase, TASK_UNINTERRUPTIBLE);
1454 }
1455
1456 static inline int __sched __down_write_killable(struct rw_semaphore *sem)
1457 {
1458 return rwbase_write_lock(&sem->rwbase, TASK_KILLABLE);
1459 }
1460
1461 static inline int __down_write_trylock(struct rw_semaphore *sem)
1462 {
1463 return rwbase_write_trylock(&sem->rwbase);
1464 }
1465
1466 static inline void __up_write(struct rw_semaphore *sem)
1467 {
1468 rwbase_write_unlock(&sem->rwbase);
1469 }
1470
1471 static inline void __downgrade_write(struct rw_semaphore *sem)
1472 {
1473 rwbase_write_downgrade(&sem->rwbase);
1474 }
1475
1476
1477 #define DEBUG_RWSEMS_WARN_ON(c, sem)
1478
1479 static inline void __rwsem_set_reader_owned(struct rw_semaphore *sem,
1480 struct task_struct *owner)
1481 {
1482 }
1483
1484 static inline bool is_rwsem_reader_owned(struct rw_semaphore *sem)
1485 {
1486 int count = atomic_read(&sem->rwbase.readers);
1487
1488 return count < 0 && count != READER_BIAS;
1489 }
1490
1491 #endif
1492
1493
1494
1495
1496 void __sched down_read(struct rw_semaphore *sem)
1497 {
1498 might_sleep();
1499 rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_);
1500
1501 LOCK_CONTENDED(sem, __down_read_trylock, __down_read);
1502 }
1503 EXPORT_SYMBOL(down_read);
1504
1505 int __sched down_read_interruptible(struct rw_semaphore *sem)
1506 {
1507 might_sleep();
1508 rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_);
1509
1510 if (LOCK_CONTENDED_RETURN(sem, __down_read_trylock, __down_read_interruptible)) {
1511 rwsem_release(&sem->dep_map, _RET_IP_);
1512 return -EINTR;
1513 }
1514
1515 return 0;
1516 }
1517 EXPORT_SYMBOL(down_read_interruptible);
1518
1519 int __sched down_read_killable(struct rw_semaphore *sem)
1520 {
1521 might_sleep();
1522 rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_);
1523
1524 if (LOCK_CONTENDED_RETURN(sem, __down_read_trylock, __down_read_killable)) {
1525 rwsem_release(&sem->dep_map, _RET_IP_);
1526 return -EINTR;
1527 }
1528
1529 return 0;
1530 }
1531 EXPORT_SYMBOL(down_read_killable);
1532
1533
1534
1535
1536 int down_read_trylock(struct rw_semaphore *sem)
1537 {
1538 int ret = __down_read_trylock(sem);
1539
1540 if (ret == 1)
1541 rwsem_acquire_read(&sem->dep_map, 0, 1, _RET_IP_);
1542 return ret;
1543 }
1544 EXPORT_SYMBOL(down_read_trylock);
1545
1546
1547
1548
1549 void __sched down_write(struct rw_semaphore *sem)
1550 {
1551 might_sleep();
1552 rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
1553 LOCK_CONTENDED(sem, __down_write_trylock, __down_write);
1554 }
1555 EXPORT_SYMBOL(down_write);
1556
1557
1558
1559
1560 int __sched down_write_killable(struct rw_semaphore *sem)
1561 {
1562 might_sleep();
1563 rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
1564
1565 if (LOCK_CONTENDED_RETURN(sem, __down_write_trylock,
1566 __down_write_killable)) {
1567 rwsem_release(&sem->dep_map, _RET_IP_);
1568 return -EINTR;
1569 }
1570
1571 return 0;
1572 }
1573 EXPORT_SYMBOL(down_write_killable);
1574
1575
1576
1577
1578 int down_write_trylock(struct rw_semaphore *sem)
1579 {
1580 int ret = __down_write_trylock(sem);
1581
1582 if (ret == 1)
1583 rwsem_acquire(&sem->dep_map, 0, 1, _RET_IP_);
1584
1585 return ret;
1586 }
1587 EXPORT_SYMBOL(down_write_trylock);
1588
1589
1590
1591
1592 void up_read(struct rw_semaphore *sem)
1593 {
1594 rwsem_release(&sem->dep_map, _RET_IP_);
1595 __up_read(sem);
1596 }
1597 EXPORT_SYMBOL(up_read);
1598
1599
1600
1601
1602 void up_write(struct rw_semaphore *sem)
1603 {
1604 rwsem_release(&sem->dep_map, _RET_IP_);
1605 __up_write(sem);
1606 }
1607 EXPORT_SYMBOL(up_write);
1608
1609
1610
1611
1612 void downgrade_write(struct rw_semaphore *sem)
1613 {
1614 lock_downgrade(&sem->dep_map, _RET_IP_);
1615 __downgrade_write(sem);
1616 }
1617 EXPORT_SYMBOL(downgrade_write);
1618
1619 #ifdef CONFIG_DEBUG_LOCK_ALLOC
1620
1621 void down_read_nested(struct rw_semaphore *sem, int subclass)
1622 {
1623 might_sleep();
1624 rwsem_acquire_read(&sem->dep_map, subclass, 0, _RET_IP_);
1625 LOCK_CONTENDED(sem, __down_read_trylock, __down_read);
1626 }
1627 EXPORT_SYMBOL(down_read_nested);
1628
1629 int down_read_killable_nested(struct rw_semaphore *sem, int subclass)
1630 {
1631 might_sleep();
1632 rwsem_acquire_read(&sem->dep_map, subclass, 0, _RET_IP_);
1633
1634 if (LOCK_CONTENDED_RETURN(sem, __down_read_trylock, __down_read_killable)) {
1635 rwsem_release(&sem->dep_map, _RET_IP_);
1636 return -EINTR;
1637 }
1638
1639 return 0;
1640 }
1641 EXPORT_SYMBOL(down_read_killable_nested);
1642
1643 void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest)
1644 {
1645 might_sleep();
1646 rwsem_acquire_nest(&sem->dep_map, 0, 0, nest, _RET_IP_);
1647 LOCK_CONTENDED(sem, __down_write_trylock, __down_write);
1648 }
1649 EXPORT_SYMBOL(_down_write_nest_lock);
1650
1651 void down_read_non_owner(struct rw_semaphore *sem)
1652 {
1653 might_sleep();
1654 __down_read(sem);
1655 __rwsem_set_reader_owned(sem, NULL);
1656 }
1657 EXPORT_SYMBOL(down_read_non_owner);
1658
1659 void down_write_nested(struct rw_semaphore *sem, int subclass)
1660 {
1661 might_sleep();
1662 rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_);
1663 LOCK_CONTENDED(sem, __down_write_trylock, __down_write);
1664 }
1665 EXPORT_SYMBOL(down_write_nested);
1666
1667 int __sched down_write_killable_nested(struct rw_semaphore *sem, int subclass)
1668 {
1669 might_sleep();
1670 rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_);
1671
1672 if (LOCK_CONTENDED_RETURN(sem, __down_write_trylock,
1673 __down_write_killable)) {
1674 rwsem_release(&sem->dep_map, _RET_IP_);
1675 return -EINTR;
1676 }
1677
1678 return 0;
1679 }
1680 EXPORT_SYMBOL(down_write_killable_nested);
1681
1682 void up_read_non_owner(struct rw_semaphore *sem)
1683 {
1684 DEBUG_RWSEMS_WARN_ON(!is_rwsem_reader_owned(sem), sem);
1685 __up_read(sem);
1686 }
1687 EXPORT_SYMBOL(up_read_non_owner);
1688
1689 #endif