hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/lib/locking-selftest.c
....@@ -28,6 +28,7 @@
2828 * Change this to 1 if you want to see the failure printouts:
2929 */
3030 static unsigned int debug_locks_verbose;
31
+unsigned int force_read_lock_recursive;
3132
3233 static DEFINE_WD_CLASS(ww_lockdep);
3334
....@@ -185,6 +186,7 @@
185186 #define HARDIRQ_ENTER() \
186187 local_irq_disable(); \
187188 __irq_enter(); \
189
+ lockdep_hardirq_threaded(); \
188190 WARN_ON(!in_irq());
189191
190192 #define HARDIRQ_EXIT() \
....@@ -393,6 +395,49 @@
393395 WSL(X1);
394396 WSU(X1);
395397 MU(Y1); // should fail
398
+}
399
+
400
+/*
401
+ * read_lock(A)
402
+ * spin_lock(B)
403
+ * spin_lock(B)
404
+ * write_lock(A)
405
+ *
406
+ * This test case is aimed at poking whether the chain cache prevents us from
407
+ * detecting a read-lock/lock-write deadlock: if the chain cache doesn't differ
408
+ * read/write locks, the following case may happen
409
+ *
410
+ * { read_lock(A)->lock(B) dependency exists }
411
+ *
412
+ * P0:
413
+ * lock(B);
414
+ * read_lock(A);
415
+ *
416
+ * { Not a deadlock, B -> A is added in the chain cache }
417
+ *
418
+ * P1:
419
+ * lock(B);
420
+ * write_lock(A);
421
+ *
422
+ * { B->A found in chain cache, not reported as a deadlock }
423
+ *
424
+ */
425
+static void rlock_chaincache_ABBA1(void)
426
+{
427
+ RL(X1);
428
+ L(Y1);
429
+ U(Y1);
430
+ RU(X1);
431
+
432
+ L(Y1);
433
+ RL(X1);
434
+ RU(X1);
435
+ U(Y1);
436
+
437
+ L(Y1);
438
+ WL(X1);
439
+ WU(X1);
440
+ U(Y1); // should fail
396441 }
397442
398443 /*
....@@ -742,6 +787,8 @@
742787 #include "locking-selftest-spin-hardirq.h"
743788 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin)
744789
790
+#ifndef CONFIG_PREEMPT_RT
791
+
745792 #include "locking-selftest-rlock-hardirq.h"
746793 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)
747794
....@@ -757,9 +804,12 @@
757804 #include "locking-selftest-wlock-softirq.h"
758805 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock)
759806
807
+#endif
808
+
760809 #undef E1
761810 #undef E2
762811
812
+#ifndef CONFIG_PREEMPT_RT
763813 /*
764814 * Enabling hardirqs with a softirq-safe lock held:
765815 */
....@@ -792,6 +842,8 @@
792842 #undef E1
793843 #undef E2
794844
845
+#endif
846
+
795847 /*
796848 * Enabling irqs with an irq-safe lock held:
797849 */
....@@ -815,6 +867,8 @@
815867 #include "locking-selftest-spin-hardirq.h"
816868 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin)
817869
870
+#ifndef CONFIG_PREEMPT_RT
871
+
818872 #include "locking-selftest-rlock-hardirq.h"
819873 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock)
820874
....@@ -829,6 +883,8 @@
829883
830884 #include "locking-selftest-wlock-softirq.h"
831885 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
886
+
887
+#endif
832888
833889 #undef E1
834890 #undef E2
....@@ -861,6 +917,8 @@
861917 #include "locking-selftest-spin-hardirq.h"
862918 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin)
863919
920
+#ifndef CONFIG_PREEMPT_RT
921
+
864922 #include "locking-selftest-rlock-hardirq.h"
865923 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock)
866924
....@@ -875,6 +933,8 @@
875933
876934 #include "locking-selftest-wlock-softirq.h"
877935 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
936
+
937
+#endif
878938
879939 #undef E1
880940 #undef E2
....@@ -909,6 +969,8 @@
909969 #include "locking-selftest-spin-hardirq.h"
910970 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin)
911971
972
+#ifndef CONFIG_PREEMPT_RT
973
+
912974 #include "locking-selftest-rlock-hardirq.h"
913975 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock)
914976
....@@ -924,9 +986,13 @@
924986 #include "locking-selftest-wlock-softirq.h"
925987 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock)
926988
989
+#endif
990
+
927991 #undef E1
928992 #undef E2
929993 #undef E3
994
+
995
+#ifndef CONFIG_PREEMPT_RT
930996
931997 /*
932998 * read-lock / write-lock irq inversion.
....@@ -991,6 +1057,138 @@
9911057 #undef E3
9921058
9931059 /*
1060
+ * write-read / write-read / write-read deadlock even if read is recursive
1061
+ */
1062
+
1063
+#define E1() \
1064
+ \
1065
+ WL(X1); \
1066
+ RL(Y1); \
1067
+ RU(Y1); \
1068
+ WU(X1);
1069
+
1070
+#define E2() \
1071
+ \
1072
+ WL(Y1); \
1073
+ RL(Z1); \
1074
+ RU(Z1); \
1075
+ WU(Y1);
1076
+
1077
+#define E3() \
1078
+ \
1079
+ WL(Z1); \
1080
+ RL(X1); \
1081
+ RU(X1); \
1082
+ WU(Z1);
1083
+
1084
+#include "locking-selftest-rlock.h"
1085
+GENERATE_PERMUTATIONS_3_EVENTS(W1R2_W2R3_W3R1)
1086
+
1087
+#undef E1
1088
+#undef E2
1089
+#undef E3
1090
+
1091
+/*
1092
+ * write-write / read-read / write-read deadlock even if read is recursive
1093
+ */
1094
+
1095
+#define E1() \
1096
+ \
1097
+ WL(X1); \
1098
+ WL(Y1); \
1099
+ WU(Y1); \
1100
+ WU(X1);
1101
+
1102
+#define E2() \
1103
+ \
1104
+ RL(Y1); \
1105
+ RL(Z1); \
1106
+ RU(Z1); \
1107
+ RU(Y1);
1108
+
1109
+#define E3() \
1110
+ \
1111
+ WL(Z1); \
1112
+ RL(X1); \
1113
+ RU(X1); \
1114
+ WU(Z1);
1115
+
1116
+#include "locking-selftest-rlock.h"
1117
+GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_W3R1)
1118
+
1119
+#undef E1
1120
+#undef E2
1121
+#undef E3
1122
+
1123
+/*
1124
+ * write-write / read-read / read-write is not deadlock when read is recursive
1125
+ */
1126
+
1127
+#define E1() \
1128
+ \
1129
+ WL(X1); \
1130
+ WL(Y1); \
1131
+ WU(Y1); \
1132
+ WU(X1);
1133
+
1134
+#define E2() \
1135
+ \
1136
+ RL(Y1); \
1137
+ RL(Z1); \
1138
+ RU(Z1); \
1139
+ RU(Y1);
1140
+
1141
+#define E3() \
1142
+ \
1143
+ RL(Z1); \
1144
+ WL(X1); \
1145
+ WU(X1); \
1146
+ RU(Z1);
1147
+
1148
+#include "locking-selftest-rlock.h"
1149
+GENERATE_PERMUTATIONS_3_EVENTS(W1R2_R2R3_W3W1)
1150
+
1151
+#undef E1
1152
+#undef E2
1153
+#undef E3
1154
+
1155
+/*
1156
+ * write-read / read-read / write-write is not deadlock when read is recursive
1157
+ */
1158
+
1159
+#define E1() \
1160
+ \
1161
+ WL(X1); \
1162
+ RL(Y1); \
1163
+ RU(Y1); \
1164
+ WU(X1);
1165
+
1166
+#define E2() \
1167
+ \
1168
+ RL(Y1); \
1169
+ RL(Z1); \
1170
+ RU(Z1); \
1171
+ RU(Y1);
1172
+
1173
+#define E3() \
1174
+ \
1175
+ WL(Z1); \
1176
+ WL(X1); \
1177
+ WU(X1); \
1178
+ WU(Z1);
1179
+
1180
+#include "locking-selftest-rlock.h"
1181
+GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_R3W1)
1182
+
1183
+#undef E1
1184
+#undef E2
1185
+#undef E3
1186
+
1187
+#endif
1188
+
1189
+#ifndef CONFIG_PREEMPT_RT
1190
+
1191
+/*
9941192 * read-lock / write-lock recursion that is actually safe.
9951193 */
9961194
....@@ -1009,24 +1207,34 @@
10091207 #define E3() \
10101208 \
10111209 IRQ_ENTER(); \
1012
- RL(A); \
1210
+ LOCK(A); \
10131211 L(B); \
10141212 U(B); \
1015
- RU(A); \
1213
+ UNLOCK(A); \
10161214 IRQ_EXIT();
10171215
10181216 /*
1019
- * Generate 12 testcases:
1217
+ * Generate 24 testcases:
10201218 */
10211219 #include "locking-selftest-hardirq.h"
1022
-GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard)
1220
+#include "locking-selftest-rlock.h"
1221
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_rlock)
1222
+
1223
+#include "locking-selftest-wlock.h"
1224
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_wlock)
10231225
10241226 #include "locking-selftest-softirq.h"
1025
-GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
1227
+#include "locking-selftest-rlock.h"
1228
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_rlock)
1229
+
1230
+#include "locking-selftest-wlock.h"
1231
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_wlock)
10261232
10271233 #undef E1
10281234 #undef E2
10291235 #undef E3
1236
+
1237
+#endif
10301238
10311239 /*
10321240 * read-lock / write-lock recursion that is unsafe.
....@@ -1036,8 +1244,8 @@
10361244 \
10371245 IRQ_DISABLE(); \
10381246 L(B); \
1039
- WL(A); \
1040
- WU(A); \
1247
+ LOCK(A); \
1248
+ UNLOCK(A); \
10411249 U(B); \
10421250 IRQ_ENABLE();
10431251
....@@ -1054,13 +1262,75 @@
10541262 IRQ_EXIT();
10551263
10561264 /*
1057
- * Generate 12 testcases:
1265
+ * Generate 24 testcases:
10581266 */
10591267 #include "locking-selftest-hardirq.h"
1060
-// GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard)
1268
+#include "locking-selftest-rlock.h"
1269
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_rlock)
1270
+
1271
+#include "locking-selftest-wlock.h"
1272
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_wlock)
10611273
10621274 #include "locking-selftest-softirq.h"
1063
-// GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft)
1275
+#include "locking-selftest-rlock.h"
1276
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_rlock)
1277
+
1278
+#include "locking-selftest-wlock.h"
1279
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_wlock)
1280
+
1281
+#undef E1
1282
+#undef E2
1283
+#undef E3
1284
+/*
1285
+ * read-lock / write-lock recursion that is unsafe.
1286
+ *
1287
+ * A is a ENABLED_*_READ lock
1288
+ * B is a USED_IN_*_READ lock
1289
+ *
1290
+ * read_lock(A);
1291
+ * write_lock(B);
1292
+ * <interrupt>
1293
+ * read_lock(B);
1294
+ * write_lock(A); // if this one is read_lock(), no deadlock
1295
+ */
1296
+
1297
+#define E1() \
1298
+ \
1299
+ IRQ_DISABLE(); \
1300
+ WL(B); \
1301
+ LOCK(A); \
1302
+ UNLOCK(A); \
1303
+ WU(B); \
1304
+ IRQ_ENABLE();
1305
+
1306
+#define E2() \
1307
+ \
1308
+ RL(A); \
1309
+ RU(A); \
1310
+
1311
+#define E3() \
1312
+ \
1313
+ IRQ_ENTER(); \
1314
+ RL(B); \
1315
+ RU(B); \
1316
+ IRQ_EXIT();
1317
+
1318
+/*
1319
+ * Generate 24 testcases:
1320
+ */
1321
+#include "locking-selftest-hardirq.h"
1322
+#include "locking-selftest-rlock.h"
1323
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_rlock)
1324
+
1325
+#include "locking-selftest-wlock.h"
1326
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_wlock)
1327
+
1328
+#include "locking-selftest-softirq.h"
1329
+#include "locking-selftest-rlock.h"
1330
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_rlock)
1331
+
1332
+#include "locking-selftest-wlock.h"
1333
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_wlock)
10641334
10651335 #ifdef CONFIG_DEBUG_LOCK_ALLOC
10661336 # define I_SPINLOCK(x) lockdep_reset_lock(&lock_##x.dep_map)
....@@ -1199,6 +1469,19 @@
11991469 dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK); \
12001470 pr_cont("\n");
12011471
1472
+#define DO_TESTCASE_1RR(desc, name, nr) \
1473
+ print_testname(desc"/"#nr); \
1474
+ pr_cont(" |"); \
1475
+ dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
1476
+ pr_cont("\n");
1477
+
1478
+#define DO_TESTCASE_1RRB(desc, name, nr) \
1479
+ print_testname(desc"/"#nr); \
1480
+ pr_cont(" |"); \
1481
+ dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1482
+ pr_cont("\n");
1483
+
1484
+
12021485 #define DO_TESTCASE_3(desc, name, nr) \
12031486 print_testname(desc"/"#nr); \
12041487 dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN); \
....@@ -1212,6 +1495,25 @@
12121495 dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \
12131496 dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
12141497 pr_cont("\n");
1498
+
1499
+#define DO_TESTCASE_2RW(desc, name, nr) \
1500
+ print_testname(desc"/"#nr); \
1501
+ pr_cont(" |"); \
1502
+ dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1503
+ dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
1504
+ pr_cont("\n");
1505
+
1506
+#define DO_TESTCASE_2x2RW(desc, name, nr) \
1507
+ DO_TESTCASE_2RW("hard-"desc, name##_hard, nr) \
1508
+ DO_TESTCASE_2RW("soft-"desc, name##_soft, nr) \
1509
+
1510
+#define DO_TESTCASE_6x2x2RW(desc, name) \
1511
+ DO_TESTCASE_2x2RW(desc, name, 123); \
1512
+ DO_TESTCASE_2x2RW(desc, name, 132); \
1513
+ DO_TESTCASE_2x2RW(desc, name, 213); \
1514
+ DO_TESTCASE_2x2RW(desc, name, 231); \
1515
+ DO_TESTCASE_2x2RW(desc, name, 312); \
1516
+ DO_TESTCASE_2x2RW(desc, name, 321);
12151517
12161518 #define DO_TESTCASE_6(desc, name) \
12171519 print_testname(desc); \
....@@ -1288,6 +1590,22 @@
12881590 DO_TESTCASE_2IB(desc, name, 231); \
12891591 DO_TESTCASE_2IB(desc, name, 312); \
12901592 DO_TESTCASE_2IB(desc, name, 321);
1593
+
1594
+#define DO_TESTCASE_6x1RR(desc, name) \
1595
+ DO_TESTCASE_1RR(desc, name, 123); \
1596
+ DO_TESTCASE_1RR(desc, name, 132); \
1597
+ DO_TESTCASE_1RR(desc, name, 213); \
1598
+ DO_TESTCASE_1RR(desc, name, 231); \
1599
+ DO_TESTCASE_1RR(desc, name, 312); \
1600
+ DO_TESTCASE_1RR(desc, name, 321);
1601
+
1602
+#define DO_TESTCASE_6x1RRB(desc, name) \
1603
+ DO_TESTCASE_1RRB(desc, name, 123); \
1604
+ DO_TESTCASE_1RRB(desc, name, 132); \
1605
+ DO_TESTCASE_1RRB(desc, name, 213); \
1606
+ DO_TESTCASE_1RRB(desc, name, 231); \
1607
+ DO_TESTCASE_1RRB(desc, name, 312); \
1608
+ DO_TESTCASE_1RRB(desc, name, 321);
12911609
12921610 #define DO_TESTCASE_6x6(desc, name) \
12931611 DO_TESTCASE_6I(desc, name, 123); \
....@@ -1475,7 +1793,7 @@
14751793
14761794 mutex_lock(&o2.base);
14771795 o2.ctx = &t2;
1478
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1796
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
14791797
14801798 WWAI(&t);
14811799 t2 = t;
....@@ -1500,7 +1818,7 @@
15001818 int ret;
15011819
15021820 mutex_lock(&o2.base);
1503
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1821
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
15041822 o2.ctx = &t2;
15051823
15061824 WWAI(&t);
....@@ -1527,7 +1845,7 @@
15271845
15281846 mutex_lock(&o2.base);
15291847 o2.ctx = &t2;
1530
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1848
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
15311849
15321850 WWAI(&t);
15331851 t2 = t;
....@@ -1551,7 +1869,7 @@
15511869 int ret;
15521870
15531871 mutex_lock(&o2.base);
1554
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1872
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
15551873 o2.ctx = &t2;
15561874
15571875 WWAI(&t);
....@@ -1576,7 +1894,7 @@
15761894 int ret;
15771895
15781896 mutex_lock(&o2.base);
1579
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1897
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
15801898 o2.ctx = &t2;
15811899
15821900 WWAI(&t);
....@@ -1597,7 +1915,7 @@
15971915 int ret;
15981916
15991917 mutex_lock(&o2.base);
1600
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1918
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
16011919 o2.ctx = &t2;
16021920
16031921 WWAI(&t);
....@@ -1618,11 +1936,11 @@
16181936 int ret;
16191937
16201938 mutex_lock(&o2.base);
1621
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1939
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
16221940 o2.ctx = &t2;
16231941
16241942 mutex_lock(&o3.base);
1625
- mutex_release(&o3.base.dep_map, 1, _THIS_IP_);
1943
+ mutex_release(&o3.base.dep_map, _THIS_IP_);
16261944 o3.ctx = &t2;
16271945
16281946 WWAI(&t);
....@@ -1644,11 +1962,11 @@
16441962 int ret;
16451963
16461964 mutex_lock(&o2.base);
1647
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1965
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
16481966 o2.ctx = &t2;
16491967
16501968 mutex_lock(&o3.base);
1651
- mutex_release(&o3.base.dep_map, 1, _THIS_IP_);
1969
+ mutex_release(&o3.base.dep_map, _THIS_IP_);
16521970 o3.ctx = &t2;
16531971
16541972 WWAI(&t);
....@@ -1669,7 +1987,7 @@
16691987 int ret;
16701988
16711989 mutex_lock(&o2.base);
1672
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1990
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
16731991 o2.ctx = &t2;
16741992
16751993 WWAI(&t);
....@@ -1694,7 +2012,7 @@
16942012 int ret;
16952013
16962014 mutex_lock(&o2.base);
1697
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
2015
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
16982016 o2.ctx = &t2;
16992017
17002018 WWAI(&t);
....@@ -1966,6 +2284,108 @@
19662284 pr_cont("\n");
19672285 }
19682286
2287
+
2288
+/*
2289
+ * <in hardirq handler>
2290
+ * read_lock(&A);
2291
+ * <hardirq disable>
2292
+ * spin_lock(&B);
2293
+ * spin_lock(&B);
2294
+ * read_lock(&A);
2295
+ *
2296
+ * is a deadlock.
2297
+ */
2298
+static void queued_read_lock_hardirq_RE_Er(void)
2299
+{
2300
+ HARDIRQ_ENTER();
2301
+ read_lock(&rwlock_A);
2302
+ LOCK(B);
2303
+ UNLOCK(B);
2304
+ read_unlock(&rwlock_A);
2305
+ HARDIRQ_EXIT();
2306
+
2307
+ HARDIRQ_DISABLE();
2308
+ LOCK(B);
2309
+ read_lock(&rwlock_A);
2310
+ read_unlock(&rwlock_A);
2311
+ UNLOCK(B);
2312
+ HARDIRQ_ENABLE();
2313
+}
2314
+
2315
+/*
2316
+ * <in hardirq handler>
2317
+ * spin_lock(&B);
2318
+ * <hardirq disable>
2319
+ * read_lock(&A);
2320
+ * read_lock(&A);
2321
+ * spin_lock(&B);
2322
+ *
2323
+ * is not a deadlock.
2324
+ */
2325
+static void queued_read_lock_hardirq_ER_rE(void)
2326
+{
2327
+ HARDIRQ_ENTER();
2328
+ LOCK(B);
2329
+ read_lock(&rwlock_A);
2330
+ read_unlock(&rwlock_A);
2331
+ UNLOCK(B);
2332
+ HARDIRQ_EXIT();
2333
+
2334
+ HARDIRQ_DISABLE();
2335
+ read_lock(&rwlock_A);
2336
+ LOCK(B);
2337
+ UNLOCK(B);
2338
+ read_unlock(&rwlock_A);
2339
+ HARDIRQ_ENABLE();
2340
+}
2341
+
2342
+/*
2343
+ * <hardirq disable>
2344
+ * spin_lock(&B);
2345
+ * read_lock(&A);
2346
+ * <in hardirq handler>
2347
+ * spin_lock(&B);
2348
+ * read_lock(&A);
2349
+ *
2350
+ * is a deadlock. Because the two read_lock()s are both non-recursive readers.
2351
+ */
2352
+static void queued_read_lock_hardirq_inversion(void)
2353
+{
2354
+
2355
+ HARDIRQ_ENTER();
2356
+ LOCK(B);
2357
+ UNLOCK(B);
2358
+ HARDIRQ_EXIT();
2359
+
2360
+ HARDIRQ_DISABLE();
2361
+ LOCK(B);
2362
+ read_lock(&rwlock_A);
2363
+ read_unlock(&rwlock_A);
2364
+ UNLOCK(B);
2365
+ HARDIRQ_ENABLE();
2366
+
2367
+ read_lock(&rwlock_A);
2368
+ read_unlock(&rwlock_A);
2369
+}
2370
+
2371
+static void queued_read_lock_tests(void)
2372
+{
2373
+ printk(" --------------------------------------------------------------------------\n");
2374
+ printk(" | queued read lock tests |\n");
2375
+ printk(" ---------------------------\n");
2376
+ print_testname("hardirq read-lock/lock-read");
2377
+ dotest(queued_read_lock_hardirq_RE_Er, FAILURE, LOCKTYPE_RWLOCK);
2378
+ pr_cont("\n");
2379
+
2380
+ print_testname("hardirq lock-read/read-lock");
2381
+ dotest(queued_read_lock_hardirq_ER_rE, SUCCESS, LOCKTYPE_RWLOCK);
2382
+ pr_cont("\n");
2383
+
2384
+ print_testname("hardirq inversion");
2385
+ dotest(queued_read_lock_hardirq_inversion, FAILURE, LOCKTYPE_RWLOCK);
2386
+ pr_cont("\n");
2387
+}
2388
+
19692389 void locking_selftest(void)
19702390 {
19712391 /*
....@@ -1979,6 +2399,11 @@
19792399 }
19802400
19812401 /*
2402
+ * treats read_lock() as recursive read locks for testing purpose
2403
+ */
2404
+ force_read_lock_recursive = 1;
2405
+
2406
+ /*
19822407 * Run the testsuite:
19832408 */
19842409 printk("------------------------\n");
....@@ -1989,6 +2414,7 @@
19892414
19902415 init_shared_classes();
19912416 debug_locks_silent = !debug_locks_verbose;
2417
+ lockdep_set_selftest_task(current);
19922418
19932419 DO_TESTCASE_6R("A-A deadlock", AA);
19942420 DO_TESTCASE_6R("A-B-B-A deadlock", ABBA);
....@@ -2032,14 +2458,6 @@
20322458 print_testname("mixed read-lock/lock-write ABBA");
20332459 pr_cont(" |");
20342460 dotest(rlock_ABBA1, FAILURE, LOCKTYPE_RWLOCK);
2035
-#ifdef CONFIG_PROVE_LOCKING
2036
- /*
2037
- * Lockdep does indeed fail here, but there's nothing we can do about
2038
- * that now. Don't kill lockdep for it.
2039
- */
2040
- unexpected_testcase_failures--;
2041
-#endif
2042
-
20432461 pr_cont(" |");
20442462 dotest(rwsem_ABBA1, FAILURE, LOCKTYPE_RWSEM);
20452463
....@@ -2055,8 +2473,18 @@
20552473 pr_cont(" |");
20562474 dotest(rwsem_ABBA3, FAILURE, LOCKTYPE_RWSEM);
20572475
2476
+ print_testname("chain cached mixed R-L/L-W ABBA");
2477
+ pr_cont(" |");
2478
+ dotest(rlock_chaincache_ABBA1, FAILURE, LOCKTYPE_RWLOCK);
2479
+
2480
+ DO_TESTCASE_6x1RRB("rlock W1R2/W2R3/W3R1", W1R2_W2R3_W3R1);
2481
+ DO_TESTCASE_6x1RRB("rlock W1W2/R2R3/W3R1", W1W2_R2R3_W3R1);
2482
+ DO_TESTCASE_6x1RR("rlock W1W2/R2R3/R3W1", W1W2_R2R3_R3W1);
2483
+ DO_TESTCASE_6x1RR("rlock W1R2/R2R3/W3W1", W1R2_R2R3_W3W1);
2484
+
20582485 printk(" --------------------------------------------------------------------------\n");
20592486
2487
+#ifndef CONFIG_PREEMPT_RT
20602488 /*
20612489 * irq-context testcases:
20622490 */
....@@ -2067,10 +2495,40 @@
20672495 DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4);
20682496 DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion);
20692497
2070
- DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion);
2071
-// DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2);
2498
+ DO_TESTCASE_6x2x2RW("irq read-recursion", irq_read_recursion);
2499
+ DO_TESTCASE_6x2x2RW("irq read-recursion #2", irq_read_recursion2);
2500
+ DO_TESTCASE_6x2x2RW("irq read-recursion #3", irq_read_recursion3);
20722501
2502
+#else
2503
+ /* On -rt, we only do hardirq context test for raw spinlock */
2504
+ DO_TESTCASE_1B("hard-irqs-on + irq-safe-A", irqsafe1_hard_spin, 12);
2505
+ DO_TESTCASE_1B("hard-irqs-on + irq-safe-A", irqsafe1_hard_spin, 21);
2506
+
2507
+ DO_TESTCASE_1B("hard-safe-A + irqs-on", irqsafe2B_hard_spin, 12);
2508
+ DO_TESTCASE_1B("hard-safe-A + irqs-on", irqsafe2B_hard_spin, 21);
2509
+
2510
+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 123);
2511
+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 132);
2512
+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 213);
2513
+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 231);
2514
+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 312);
2515
+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 321);
2516
+
2517
+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 123);
2518
+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 132);
2519
+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 213);
2520
+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 231);
2521
+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 312);
2522
+ DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 321);
2523
+#endif
20732524 ww_tests();
2525
+
2526
+ force_read_lock_recursive = 0;
2527
+ /*
2528
+ * queued_read_lock() specific test cases can be put here
2529
+ */
2530
+ if (IS_ENABLED(CONFIG_QUEUED_RWLOCKS))
2531
+ queued_read_lock_tests();
20742532
20752533 if (unexpected_testcase_failures) {
20762534 printk("-----------------------------------------------------------------\n");
....@@ -2097,5 +2555,6 @@
20972555 printk("---------------------------------\n");
20982556 debug_locks = 1;
20992557 }
2558
+ lockdep_set_selftest_task(NULL);
21002559 debug_locks_silent = 0;
21012560 }