1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/types.h>
19#include <linux/kernel.h>
20#include <linux/sched.h>
21#include <linux/sched/rt.h>
22#include <linux/sched/task.h>
23#include <linux/sched/debug.h>
24#include <linux/sched/wake_q.h>
25#include <linux/sched/signal.h>
26#include <linux/sched/clock.h>
27#include <linux/export.h>
28#include <linux/rwsem.h>
29#include <linux/atomic.h>
30#include <trace/events/lock.h>
31
32#ifndef CONFIG_PREEMPT_RT
33#include "lock_events.h"
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63#define RWSEM_READER_OWNED (1UL << 0)
64#define RWSEM_NONSPINNABLE (1UL << 1)
65#define RWSEM_OWNER_FLAGS_MASK (RWSEM_READER_OWNED | RWSEM_NONSPINNABLE)
66
67#ifdef CONFIG_DEBUG_RWSEMS
68# define DEBUG_RWSEMS_WARN_ON(c, sem) do { \
69 if (!debug_locks_silent && \
70 WARN_ONCE(c, "DEBUG_RWSEMS_WARN_ON(%s): count = 0x%lx, magic = 0x%lx, owner = 0x%lx, curr 0x%lx, list %sempty\n",\
71 #c, atomic_long_read(&(sem)->count), \
72 (unsigned long) sem->magic, \
73 atomic_long_read(&(sem)->owner), (long)current, \
74 list_empty(&(sem)->wait_list) ? "" : "not ")) \
75 debug_locks_off(); \
76 } while (0)
77#else
78# define DEBUG_RWSEMS_WARN_ON(c, sem)
79#endif
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117#define RWSEM_WRITER_LOCKED (1UL << 0)
118#define RWSEM_FLAG_WAITERS (1UL << 1)
119#define RWSEM_FLAG_HANDOFF (1UL << 2)
120#define RWSEM_FLAG_READFAIL (1UL << (BITS_PER_LONG - 1))
121
122#define RWSEM_READER_SHIFT 8
123#define RWSEM_READER_BIAS (1UL << RWSEM_READER_SHIFT)
124#define RWSEM_READER_MASK (~(RWSEM_READER_BIAS - 1))
125#define RWSEM_WRITER_MASK RWSEM_WRITER_LOCKED
126#define RWSEM_LOCK_MASK (RWSEM_WRITER_MASK|RWSEM_READER_MASK)
127#define RWSEM_READ_FAILED_MASK (RWSEM_WRITER_MASK|RWSEM_FLAG_WAITERS|\
128 RWSEM_FLAG_HANDOFF|RWSEM_FLAG_READFAIL)
129
130
131
132
133
134
135
136
137static inline void rwsem_set_owner(struct rw_semaphore *sem)
138{
139 atomic_long_set(&sem->owner, (long)current);
140}
141
142static inline void rwsem_clear_owner(struct rw_semaphore *sem)
143{
144 atomic_long_set(&sem->owner, 0);
145}
146
147
148
149
150static inline bool rwsem_test_oflags(struct rw_semaphore *sem, long flags)
151{
152 return atomic_long_read(&sem->owner) & flags;
153}
154
155
156
157
158
159
160
161
162
163
164
165static inline void __rwsem_set_reader_owned(struct rw_semaphore *sem,
166 struct task_struct *owner)
167{
168 unsigned long val = (unsigned long)owner | RWSEM_READER_OWNED |
169 (atomic_long_read(&sem->owner) & RWSEM_NONSPINNABLE);
170
171 atomic_long_set(&sem->owner, val);
172}
173
174static inline void rwsem_set_reader_owned(struct rw_semaphore *sem)
175{
176 __rwsem_set_reader_owned(sem, current);
177}
178
179
180
181
182static inline bool is_rwsem_reader_owned(struct rw_semaphore *sem)
183{
184#ifdef CONFIG_DEBUG_RWSEMS
185
186
187
188 long count = atomic_long_read(&sem->count);
189
190 if (count & RWSEM_WRITER_MASK)
191 return false;
192#endif
193 return rwsem_test_oflags(sem, RWSEM_READER_OWNED);
194}
195
196#ifdef CONFIG_DEBUG_RWSEMS
197
198
199
200
201
202
203static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem)
204{
205 unsigned long val = atomic_long_read(&sem->owner);
206
207 while ((val & ~RWSEM_OWNER_FLAGS_MASK) == (unsigned long)current) {
208 if (atomic_long_try_cmpxchg(&sem->owner, &val,
209 val & RWSEM_OWNER_FLAGS_MASK))
210 return;
211 }
212}
213#else
214static inline void rwsem_clear_reader_owned(struct rw_semaphore *sem)
215{
216}
217#endif
218
219
220
221
222
223static inline void rwsem_set_nonspinnable(struct rw_semaphore *sem)
224{
225 unsigned long owner = atomic_long_read(&sem->owner);
226
227 do {
228 if (!(owner & RWSEM_READER_OWNED))
229 break;
230 if (owner & RWSEM_NONSPINNABLE)
231 break;
232 } while (!atomic_long_try_cmpxchg(&sem->owner, &owner,
233 owner | RWSEM_NONSPINNABLE));
234}
235
236static inline bool rwsem_read_trylock(struct rw_semaphore *sem, long *cntp)
237{
238 *cntp = atomic_long_add_return_acquire(RWSEM_READER_BIAS, &sem->count);
239
240 if (WARN_ON_ONCE(*cntp < 0))
241 rwsem_set_nonspinnable(sem);
242
243 if (!(*cntp & RWSEM_READ_FAILED_MASK)) {
244 rwsem_set_reader_owned(sem);
245 return true;
246 }
247
248 return false;
249}
250
251static inline bool rwsem_write_trylock(struct rw_semaphore *sem)
252{
253 long tmp = RWSEM_UNLOCKED_VALUE;
254
255 if (atomic_long_try_cmpxchg_acquire(&sem->count, &tmp, RWSEM_WRITER_LOCKED)) {
256 rwsem_set_owner(sem);
257 return true;
258 }
259
260 return false;
261}
262
263
264
265
266static inline struct task_struct *rwsem_owner(struct rw_semaphore *sem)
267{
268 return (struct task_struct *)
269 (atomic_long_read(&sem->owner) & ~RWSEM_OWNER_FLAGS_MASK);
270}
271
272
273
274
275
276static inline struct task_struct *
277rwsem_owner_flags(struct rw_semaphore *sem, unsigned long *pflags)
278{
279 unsigned long owner = atomic_long_read(&sem->owner);
280
281 *pflags = owner & RWSEM_OWNER_FLAGS_MASK;
282 return (struct task_struct *)(owner & ~RWSEM_OWNER_FLAGS_MASK);
283}
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305void __init_rwsem(struct rw_semaphore *sem, const char *name,
306 struct lock_class_key *key)
307{
308#ifdef CONFIG_DEBUG_LOCK_ALLOC
309
310
311
312 debug_check_no_locks_freed((void *)sem, sizeof(*sem));
313 lockdep_init_map_wait(&sem->dep_map, name, key, 0, LD_WAIT_SLEEP);
314#endif
315#ifdef CONFIG_DEBUG_RWSEMS
316 sem->magic = sem;
317#endif
318 atomic_long_set(&sem->count, RWSEM_UNLOCKED_VALUE);
319 raw_spin_lock_init(&sem->wait_lock);
320 INIT_LIST_HEAD(&sem->wait_list);
321 atomic_long_set(&sem->owner, 0L);
322#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
323 osq_lock_init(&sem->osq);
324#endif
325}
326EXPORT_SYMBOL(__init_rwsem);
327
328enum rwsem_waiter_type {
329 RWSEM_WAITING_FOR_WRITE,
330 RWSEM_WAITING_FOR_READ
331};
332
333struct rwsem_waiter {
334 struct list_head list;
335 struct task_struct *task;
336 enum rwsem_waiter_type type;
337 unsigned long timeout;
338 bool handoff_set;
339};
340#define rwsem_first_waiter(sem) \
341 list_first_entry(&sem->wait_list, struct rwsem_waiter, list)
342
343enum rwsem_wake_type {
344 RWSEM_WAKE_ANY,
345 RWSEM_WAKE_READERS,
346 RWSEM_WAKE_READ_OWNED
347};
348
349
350
351
352
353
354#define RWSEM_WAIT_TIMEOUT DIV_ROUND_UP(HZ, 250)
355
356
357
358
359
360
361
362#define MAX_READERS_WAKEUP 0x100
363
364static inline void
365rwsem_add_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter)
366{
367 lockdep_assert_held(&sem->wait_lock);
368 list_add_tail(&waiter->list, &sem->wait_list);
369
370}
371
372
373
374
375
376
377
378
379
380static inline bool
381rwsem_del_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter)
382{
383 lockdep_assert_held(&sem->wait_lock);
384 list_del(&waiter->list);
385 if (likely(!list_empty(&sem->wait_list)))
386 return true;
387
388 atomic_long_andnot(RWSEM_FLAG_HANDOFF | RWSEM_FLAG_WAITERS, &sem->count);
389 return false;
390}
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406static void rwsem_mark_wake(struct rw_semaphore *sem,
407 enum rwsem_wake_type wake_type,
408 struct wake_q_head *wake_q)
409{
410 struct rwsem_waiter *waiter, *tmp;
411 long oldcount, woken = 0, adjustment = 0;
412 struct list_head wlist;
413
414 lockdep_assert_held(&sem->wait_lock);
415
416
417
418
419
420 waiter = rwsem_first_waiter(sem);
421
422 if (waiter->type == RWSEM_WAITING_FOR_WRITE) {
423 if (wake_type == RWSEM_WAKE_ANY) {
424
425
426
427
428
429
430
431 wake_q_add(wake_q, waiter->task);
432 lockevent_inc(rwsem_wake_writer);
433 }
434
435 return;
436 }
437
438
439
440
441 if (unlikely(atomic_long_read(&sem->count) < 0))
442 return;
443
444
445
446
447
448
449 if (wake_type != RWSEM_WAKE_READ_OWNED) {
450 struct task_struct *owner;
451
452 adjustment = RWSEM_READER_BIAS;
453 oldcount = atomic_long_fetch_add(adjustment, &sem->count);
454 if (unlikely(oldcount & RWSEM_WRITER_MASK)) {
455
456
457
458
459
460 if (time_after(jiffies, waiter->timeout)) {
461 if (!(oldcount & RWSEM_FLAG_HANDOFF)) {
462 adjustment -= RWSEM_FLAG_HANDOFF;
463 lockevent_inc(rwsem_rlock_handoff);
464 }
465 waiter->handoff_set = true;
466 }
467
468 atomic_long_add(-adjustment, &sem->count);
469 return;
470 }
471
472
473
474
475
476
477 owner = waiter->task;
478 __rwsem_set_reader_owned(sem, owner);
479 }
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504 INIT_LIST_HEAD(&wlist);
505 list_for_each_entry_safe(waiter, tmp, &sem->wait_list, list) {
506 if (waiter->type == RWSEM_WAITING_FOR_WRITE)
507 continue;
508
509 woken++;
510 list_move_tail(&waiter->list, &wlist);
511
512
513
514
515 if (unlikely(woken >= MAX_READERS_WAKEUP))
516 break;
517 }
518
519 adjustment = woken * RWSEM_READER_BIAS - adjustment;
520 lockevent_cond_inc(rwsem_wake_reader, woken);
521
522 oldcount = atomic_long_read(&sem->count);
523 if (list_empty(&sem->wait_list)) {
524
525
526
527
528 adjustment -= RWSEM_FLAG_WAITERS;
529 if (oldcount & RWSEM_FLAG_HANDOFF)
530 adjustment -= RWSEM_FLAG_HANDOFF;
531 } else if (woken) {
532
533
534
535
536 if (oldcount & RWSEM_FLAG_HANDOFF)
537 adjustment -= RWSEM_FLAG_HANDOFF;
538 }
539
540 if (adjustment)
541 atomic_long_add(adjustment, &sem->count);
542
543
544 list_for_each_entry_safe(waiter, tmp, &wlist, list) {
545 struct task_struct *tsk;
546
547 tsk = waiter->task;
548 get_task_struct(tsk);
549
550
551
552
553
554
555
556 smp_store_release(&waiter->task, NULL);
557
558
559
560
561 wake_q_add_safe(wake_q, tsk);
562 }
563}
564
565
566
567
568
569
570
571static inline void
572rwsem_del_wake_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter,
573 struct wake_q_head *wake_q)
574 __releases(&sem->wait_lock)
575{
576 bool first = rwsem_first_waiter(sem) == waiter;
577
578 wake_q_init(wake_q);
579
580
581
582
583
584
585 if (rwsem_del_waiter(sem, waiter) && first)
586 rwsem_mark_wake(sem, RWSEM_WAKE_ANY, wake_q);
587 raw_spin_unlock_irq(&sem->wait_lock);
588 if (!wake_q_empty(wake_q))
589 wake_up_q(wake_q);
590}
591
592
593
594
595
596
597
598
599static inline bool rwsem_try_write_lock(struct rw_semaphore *sem,
600 struct rwsem_waiter *waiter)
601{
602 struct rwsem_waiter *first = rwsem_first_waiter(sem);
603 long count, new;
604
605 lockdep_assert_held(&sem->wait_lock);
606
607 count = atomic_long_read(&sem->count);
608 do {
609 bool has_handoff = !!(count & RWSEM_FLAG_HANDOFF);
610
611 if (has_handoff) {
612
613
614
615
616
617 if (first->handoff_set && (waiter != first))
618 return false;
619
620
621
622
623
624 if (waiter == first)
625 waiter->handoff_set = true;
626 }
627
628 new = count;
629
630 if (count & RWSEM_LOCK_MASK) {
631 if (has_handoff || (!rt_task(waiter->task) &&
632 !time_after(jiffies, waiter->timeout)))
633 return false;
634
635 new |= RWSEM_FLAG_HANDOFF;
636 } else {
637 new |= RWSEM_WRITER_LOCKED;
638 new &= ~RWSEM_FLAG_HANDOFF;
639
640 if (list_is_singular(&sem->wait_list))
641 new &= ~RWSEM_FLAG_WAITERS;
642 }
643 } while (!atomic_long_try_cmpxchg_acquire(&sem->count, &count, new));
644
645
646
647
648
649 if (new & RWSEM_FLAG_HANDOFF) {
650 waiter->handoff_set = true;
651 lockevent_inc(rwsem_wlock_handoff);
652 return false;
653 }
654
655
656
657
658
659 list_del(&waiter->list);
660 rwsem_set_owner(sem);
661 return true;
662}
663
664
665
666
667
668
669
670
671
672
673
674
675enum owner_state {
676 OWNER_NULL = 1 << 0,
677 OWNER_WRITER = 1 << 1,
678 OWNER_READER = 1 << 2,
679 OWNER_NONSPINNABLE = 1 << 3,
680};
681
682#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
683
684
685
686static inline bool rwsem_try_write_lock_unqueued(struct rw_semaphore *sem)
687{
688 long count = atomic_long_read(&sem->count);
689
690 while (!(count & (RWSEM_LOCK_MASK|RWSEM_FLAG_HANDOFF))) {
691 if (atomic_long_try_cmpxchg_acquire(&sem->count, &count,
692 count | RWSEM_WRITER_LOCKED)) {
693 rwsem_set_owner(sem);
694 lockevent_inc(rwsem_opt_lock);
695 return true;
696 }
697 }
698 return false;
699}
700
701static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem)
702{
703 struct task_struct *owner;
704 unsigned long flags;
705 bool ret = true;
706
707 if (need_resched()) {
708 lockevent_inc(rwsem_opt_fail);
709 return false;
710 }
711
712 preempt_disable();
713
714
715
716
717 owner = rwsem_owner_flags(sem, &flags);
718
719
720
721 if ((flags & RWSEM_NONSPINNABLE) ||
722 (owner && !(flags & RWSEM_READER_OWNED) && !owner_on_cpu(owner)))
723 ret = false;
724 preempt_enable();
725
726 lockevent_cond_inc(rwsem_opt_fail, !ret);
727 return ret;
728}
729
730#define OWNER_SPINNABLE (OWNER_NULL | OWNER_WRITER | OWNER_READER)
731
732static inline enum owner_state
733rwsem_owner_state(struct task_struct *owner, unsigned long flags)
734{
735 if (flags & RWSEM_NONSPINNABLE)
736 return OWNER_NONSPINNABLE;
737
738 if (flags & RWSEM_READER_OWNED)
739 return OWNER_READER;
740
741 return owner ? OWNER_WRITER : OWNER_NULL;
742}
743
744static noinline enum owner_state
745rwsem_spin_on_owner(struct rw_semaphore *sem)
746{
747 struct task_struct *new, *owner;
748 unsigned long flags, new_flags;
749 enum owner_state state;
750
751 lockdep_assert_preemption_disabled();
752
753 owner = rwsem_owner_flags(sem, &flags);
754 state = rwsem_owner_state(owner, flags);
755 if (state != OWNER_WRITER)
756 return state;
757
758 for (;;) {
759
760
761
762
763
764
765 new = rwsem_owner_flags(sem, &new_flags);
766 if ((new != owner) || (new_flags != flags)) {
767 state = rwsem_owner_state(new, new_flags);
768 break;
769 }
770
771
772
773
774
775
776
777
778
779 barrier();
780
781 if (need_resched() || !owner_on_cpu(owner)) {
782 state = OWNER_NONSPINNABLE;
783 break;
784 }
785
786 cpu_relax();
787 }
788
789 return state;
790}
791
792
793
794
795
796
797
798
799
800
801
802
803
804static inline u64 rwsem_rspin_threshold(struct rw_semaphore *sem)
805{
806 long count = atomic_long_read(&sem->count);
807 int readers = count >> RWSEM_READER_SHIFT;
808 u64 delta;
809
810 if (readers > 30)
811 readers = 30;
812 delta = (20 + readers) * NSEC_PER_USEC / 2;
813
814 return sched_clock() + delta;
815}
816
817static bool rwsem_optimistic_spin(struct rw_semaphore *sem)
818{
819 bool taken = false;
820 int prev_owner_state = OWNER_NULL;
821 int loop = 0;
822 u64 rspin_threshold = 0;
823
824 preempt_disable();
825
826
827 if (!osq_lock(&sem->osq))
828 goto done;
829
830
831
832
833
834
835
836 for (;;) {
837 enum owner_state owner_state;
838
839 owner_state = rwsem_spin_on_owner(sem);
840 if (!(owner_state & OWNER_SPINNABLE))
841 break;
842
843
844
845
846 taken = rwsem_try_write_lock_unqueued(sem);
847
848 if (taken)
849 break;
850
851
852
853
854 if (owner_state == OWNER_READER) {
855
856
857
858
859
860
861
862 if (prev_owner_state != OWNER_READER) {
863 if (rwsem_test_oflags(sem, RWSEM_NONSPINNABLE))
864 break;
865 rspin_threshold = rwsem_rspin_threshold(sem);
866 loop = 0;
867 }
868
869
870
871
872
873
874
875
876 else if (!(++loop & 0xf) && (sched_clock() > rspin_threshold)) {
877 rwsem_set_nonspinnable(sem);
878 lockevent_inc(rwsem_opt_nospin);
879 break;
880 }
881 }
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914 if (owner_state != OWNER_WRITER) {
915 if (need_resched())
916 break;
917 if (rt_task(current) &&
918 (prev_owner_state != OWNER_WRITER))
919 break;
920 }
921 prev_owner_state = owner_state;
922
923
924
925
926
927
928
929 cpu_relax();
930 }
931 osq_unlock(&sem->osq);
932done:
933 preempt_enable();
934 lockevent_cond_inc(rwsem_opt_fail, !taken);
935 return taken;
936}
937
938
939
940
941
942static inline void clear_nonspinnable(struct rw_semaphore *sem)
943{
944 if (unlikely(rwsem_test_oflags(sem, RWSEM_NONSPINNABLE)))
945 atomic_long_andnot(RWSEM_NONSPINNABLE, &sem->owner);
946}
947
948#else
949static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem)
950{
951 return false;
952}
953
954static inline bool rwsem_optimistic_spin(struct rw_semaphore *sem)
955{
956 return false;
957}
958
959static inline void clear_nonspinnable(struct rw_semaphore *sem) { }
960
961static inline enum owner_state
962rwsem_spin_on_owner(struct rw_semaphore *sem)
963{
964 return OWNER_NONSPINNABLE;
965}
966#endif
967
968
969
970
971
972
973
974
975
976static inline void rwsem_cond_wake_waiter(struct rw_semaphore *sem, long count,
977 struct wake_q_head *wake_q)
978{
979 enum rwsem_wake_type wake_type;
980
981 if (count & RWSEM_WRITER_MASK)
982 return;
983
984 if (count & RWSEM_READER_MASK) {
985 wake_type = RWSEM_WAKE_READERS;
986 } else {
987 wake_type = RWSEM_WAKE_ANY;
988 clear_nonspinnable(sem);
989 }
990 rwsem_mark_wake(sem, wake_type, wake_q);
991}
992
993
994
995
996static struct rw_semaphore __sched *
997rwsem_down_read_slowpath(struct rw_semaphore *sem, long count, unsigned int state)
998{
999 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
1035queue:
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
1096out_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
1107static struct rw_semaphore __sched *
1108rwsem_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);
1185trylock_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
1194out_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
1207static 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
1228static 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
1247static 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
1259static inline void __down_read(struct rw_semaphore *sem)
1260{
1261 __down_read_common(sem, TASK_UNINTERRUPTIBLE);
1262}
1263
1264static inline int __down_read_interruptible(struct rw_semaphore *sem)
1265{
1266 return __down_read_common(sem, TASK_INTERRUPTIBLE);
1267}
1268
1269static inline int __down_read_killable(struct rw_semaphore *sem)
1270{
1271 return __down_read_common(sem, TASK_KILLABLE);
1272}
1273
1274static 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
1294static 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
1304static inline void __down_write(struct rw_semaphore *sem)
1305{
1306 __down_write_common(sem, TASK_UNINTERRUPTIBLE);
1307}
1308
1309static inline int __down_write_killable(struct rw_semaphore *sem)
1310{
1311 return __down_write_common(sem, TASK_KILLABLE);
1312}
1313
1314static 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
1323static 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
1343static 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
1364static 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
1414void __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}
1424EXPORT_SYMBOL(__init_rwsem);
1425
1426static inline void __down_read(struct rw_semaphore *sem)
1427{
1428 rwbase_read_lock(&sem->rwbase, TASK_UNINTERRUPTIBLE);
1429}
1430
1431static inline int __down_read_interruptible(struct rw_semaphore *sem)
1432{
1433 return rwbase_read_lock(&sem->rwbase, TASK_INTERRUPTIBLE);
1434}
1435
1436static inline int __down_read_killable(struct rw_semaphore *sem)
1437{
1438 return rwbase_read_lock(&sem->rwbase, TASK_KILLABLE);
1439}
1440
1441static inline int __down_read_trylock(struct rw_semaphore *sem)
1442{
1443 return rwbase_read_trylock(&sem->rwbase);
1444}
1445
1446static inline void __up_read(struct rw_semaphore *sem)
1447{
1448 rwbase_read_unlock(&sem->rwbase, TASK_NORMAL);
1449}
1450
1451static inline void __sched __down_write(struct rw_semaphore *sem)
1452{
1453 rwbase_write_lock(&sem->rwbase, TASK_UNINTERRUPTIBLE);
1454}
1455
1456static inline int __sched __down_write_killable(struct rw_semaphore *sem)
1457{
1458 return rwbase_write_lock(&sem->rwbase, TASK_KILLABLE);
1459}
1460
1461static inline int __down_write_trylock(struct rw_semaphore *sem)
1462{
1463 return rwbase_write_trylock(&sem->rwbase);
1464}
1465
1466static inline void __up_write(struct rw_semaphore *sem)
1467{
1468 rwbase_write_unlock(&sem->rwbase);
1469}
1470
1471static 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
1479static inline void __rwsem_set_reader_owned(struct rw_semaphore *sem,
1480 struct task_struct *owner)
1481{
1482}
1483
1484static 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
1496void __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}
1503EXPORT_SYMBOL(down_read);
1504
1505int __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}
1517EXPORT_SYMBOL(down_read_interruptible);
1518
1519int __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}
1531EXPORT_SYMBOL(down_read_killable);
1532
1533
1534
1535
1536int 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}
1544EXPORT_SYMBOL(down_read_trylock);
1545
1546
1547
1548
1549void __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}
1555EXPORT_SYMBOL(down_write);
1556
1557
1558
1559
1560int __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}
1573EXPORT_SYMBOL(down_write_killable);
1574
1575
1576
1577
1578int 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}
1587EXPORT_SYMBOL(down_write_trylock);
1588
1589
1590
1591
1592void up_read(struct rw_semaphore *sem)
1593{
1594 rwsem_release(&sem->dep_map, _RET_IP_);
1595 __up_read(sem);
1596}
1597EXPORT_SYMBOL(up_read);
1598
1599
1600
1601
1602void up_write(struct rw_semaphore *sem)
1603{
1604 rwsem_release(&sem->dep_map, _RET_IP_);
1605 __up_write(sem);
1606}
1607EXPORT_SYMBOL(up_write);
1608
1609
1610
1611
1612void downgrade_write(struct rw_semaphore *sem)
1613{
1614 lock_downgrade(&sem->dep_map, _RET_IP_);
1615 __downgrade_write(sem);
1616}
1617EXPORT_SYMBOL(downgrade_write);
1618
1619#ifdef CONFIG_DEBUG_LOCK_ALLOC
1620
1621void 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}
1627EXPORT_SYMBOL(down_read_nested);
1628
1629int 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}
1641EXPORT_SYMBOL(down_read_killable_nested);
1642
1643void _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}
1649EXPORT_SYMBOL(_down_write_nest_lock);
1650
1651void down_read_non_owner(struct rw_semaphore *sem)
1652{
1653 might_sleep();
1654 __down_read(sem);
1655 __rwsem_set_reader_owned(sem, NULL);
1656}
1657EXPORT_SYMBOL(down_read_non_owner);
1658
1659void 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}
1665EXPORT_SYMBOL(down_write_nested);
1666
1667int __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}
1680EXPORT_SYMBOL(down_write_killable_nested);
1681
1682void 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}
1687EXPORT_SYMBOL(up_read_non_owner);
1688
1689#endif
1690