hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
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,8 +787,6 @@
742787 #include "locking-selftest-spin-hardirq.h"
743788 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin)
744789
745
-#ifndef CONFIG_PREEMPT_RT_FULL
746
-
747790 #include "locking-selftest-rlock-hardirq.h"
748791 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock)
749792
....@@ -759,12 +802,9 @@
759802 #include "locking-selftest-wlock-softirq.h"
760803 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock)
761804
762
-#endif
763
-
764805 #undef E1
765806 #undef E2
766807
767
-#ifndef CONFIG_PREEMPT_RT_FULL
768808 /*
769809 * Enabling hardirqs with a softirq-safe lock held:
770810 */
....@@ -797,8 +837,6 @@
797837 #undef E1
798838 #undef E2
799839
800
-#endif
801
-
802840 /*
803841 * Enabling irqs with an irq-safe lock held:
804842 */
....@@ -822,8 +860,6 @@
822860 #include "locking-selftest-spin-hardirq.h"
823861 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin)
824862
825
-#ifndef CONFIG_PREEMPT_RT_FULL
826
-
827863 #include "locking-selftest-rlock-hardirq.h"
828864 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock)
829865
....@@ -838,8 +874,6 @@
838874
839875 #include "locking-selftest-wlock-softirq.h"
840876 GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock)
841
-
842
-#endif
843877
844878 #undef E1
845879 #undef E2
....@@ -872,8 +906,6 @@
872906 #include "locking-selftest-spin-hardirq.h"
873907 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin)
874908
875
-#ifndef CONFIG_PREEMPT_RT_FULL
876
-
877909 #include "locking-selftest-rlock-hardirq.h"
878910 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock)
879911
....@@ -888,8 +920,6 @@
888920
889921 #include "locking-selftest-wlock-softirq.h"
890922 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock)
891
-
892
-#endif
893923
894924 #undef E1
895925 #undef E2
....@@ -924,8 +954,6 @@
924954 #include "locking-selftest-spin-hardirq.h"
925955 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin)
926956
927
-#ifndef CONFIG_PREEMPT_RT_FULL
928
-
929957 #include "locking-selftest-rlock-hardirq.h"
930958 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock)
931959
....@@ -941,13 +969,9 @@
941969 #include "locking-selftest-wlock-softirq.h"
942970 GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock)
943971
944
-#endif
945
-
946972 #undef E1
947973 #undef E2
948974 #undef E3
949
-
950
-#ifndef CONFIG_PREEMPT_RT_FULL
951975
952976 /*
953977 * read-lock / write-lock irq inversion.
....@@ -1011,10 +1035,133 @@
10111035 #undef E2
10121036 #undef E3
10131037
1014
-#endif
1038
+/*
1039
+ * write-read / write-read / write-read deadlock even if read is recursive
1040
+ */
10151041
1016
-#ifndef CONFIG_PREEMPT_RT_FULL
1042
+#define E1() \
1043
+ \
1044
+ WL(X1); \
1045
+ RL(Y1); \
1046
+ RU(Y1); \
1047
+ WU(X1);
10171048
1049
+#define E2() \
1050
+ \
1051
+ WL(Y1); \
1052
+ RL(Z1); \
1053
+ RU(Z1); \
1054
+ WU(Y1);
1055
+
1056
+#define E3() \
1057
+ \
1058
+ WL(Z1); \
1059
+ RL(X1); \
1060
+ RU(X1); \
1061
+ WU(Z1);
1062
+
1063
+#include "locking-selftest-rlock.h"
1064
+GENERATE_PERMUTATIONS_3_EVENTS(W1R2_W2R3_W3R1)
1065
+
1066
+#undef E1
1067
+#undef E2
1068
+#undef E3
1069
+
1070
+/*
1071
+ * write-write / read-read / write-read deadlock even if read is recursive
1072
+ */
1073
+
1074
+#define E1() \
1075
+ \
1076
+ WL(X1); \
1077
+ WL(Y1); \
1078
+ WU(Y1); \
1079
+ WU(X1);
1080
+
1081
+#define E2() \
1082
+ \
1083
+ RL(Y1); \
1084
+ RL(Z1); \
1085
+ RU(Z1); \
1086
+ RU(Y1);
1087
+
1088
+#define E3() \
1089
+ \
1090
+ WL(Z1); \
1091
+ RL(X1); \
1092
+ RU(X1); \
1093
+ WU(Z1);
1094
+
1095
+#include "locking-selftest-rlock.h"
1096
+GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_W3R1)
1097
+
1098
+#undef E1
1099
+#undef E2
1100
+#undef E3
1101
+
1102
+/*
1103
+ * write-write / read-read / read-write is not deadlock when read is recursive
1104
+ */
1105
+
1106
+#define E1() \
1107
+ \
1108
+ WL(X1); \
1109
+ WL(Y1); \
1110
+ WU(Y1); \
1111
+ WU(X1);
1112
+
1113
+#define E2() \
1114
+ \
1115
+ RL(Y1); \
1116
+ RL(Z1); \
1117
+ RU(Z1); \
1118
+ RU(Y1);
1119
+
1120
+#define E3() \
1121
+ \
1122
+ RL(Z1); \
1123
+ WL(X1); \
1124
+ WU(X1); \
1125
+ RU(Z1);
1126
+
1127
+#include "locking-selftest-rlock.h"
1128
+GENERATE_PERMUTATIONS_3_EVENTS(W1R2_R2R3_W3W1)
1129
+
1130
+#undef E1
1131
+#undef E2
1132
+#undef E3
1133
+
1134
+/*
1135
+ * write-read / read-read / write-write is not deadlock when read is recursive
1136
+ */
1137
+
1138
+#define E1() \
1139
+ \
1140
+ WL(X1); \
1141
+ RL(Y1); \
1142
+ RU(Y1); \
1143
+ WU(X1);
1144
+
1145
+#define E2() \
1146
+ \
1147
+ RL(Y1); \
1148
+ RL(Z1); \
1149
+ RU(Z1); \
1150
+ RU(Y1);
1151
+
1152
+#define E3() \
1153
+ \
1154
+ WL(Z1); \
1155
+ WL(X1); \
1156
+ WU(X1); \
1157
+ WU(Z1);
1158
+
1159
+#include "locking-selftest-rlock.h"
1160
+GENERATE_PERMUTATIONS_3_EVENTS(W1W2_R2R3_R3W1)
1161
+
1162
+#undef E1
1163
+#undef E2
1164
+#undef E3
10181165 /*
10191166 * read-lock / write-lock recursion that is actually safe.
10201167 */
....@@ -1034,26 +1181,32 @@
10341181 #define E3() \
10351182 \
10361183 IRQ_ENTER(); \
1037
- RL(A); \
1184
+ LOCK(A); \
10381185 L(B); \
10391186 U(B); \
1040
- RU(A); \
1187
+ UNLOCK(A); \
10411188 IRQ_EXIT();
10421189
10431190 /*
1044
- * Generate 12 testcases:
1191
+ * Generate 24 testcases:
10451192 */
10461193 #include "locking-selftest-hardirq.h"
1047
-GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard)
1194
+#include "locking-selftest-rlock.h"
1195
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_rlock)
1196
+
1197
+#include "locking-selftest-wlock.h"
1198
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_hard_wlock)
10481199
10491200 #include "locking-selftest-softirq.h"
1050
-GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft)
1201
+#include "locking-selftest-rlock.h"
1202
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_rlock)
1203
+
1204
+#include "locking-selftest-wlock.h"
1205
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft_wlock)
10511206
10521207 #undef E1
10531208 #undef E2
10541209 #undef E3
1055
-
1056
-#endif
10571210
10581211 /*
10591212 * read-lock / write-lock recursion that is unsafe.
....@@ -1063,8 +1216,8 @@
10631216 \
10641217 IRQ_DISABLE(); \
10651218 L(B); \
1066
- WL(A); \
1067
- WU(A); \
1219
+ LOCK(A); \
1220
+ UNLOCK(A); \
10681221 U(B); \
10691222 IRQ_ENABLE();
10701223
....@@ -1081,13 +1234,75 @@
10811234 IRQ_EXIT();
10821235
10831236 /*
1084
- * Generate 12 testcases:
1237
+ * Generate 24 testcases:
10851238 */
10861239 #include "locking-selftest-hardirq.h"
1087
-// GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard)
1240
+#include "locking-selftest-rlock.h"
1241
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_rlock)
1242
+
1243
+#include "locking-selftest-wlock.h"
1244
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_hard_wlock)
10881245
10891246 #include "locking-selftest-softirq.h"
1090
-// GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft)
1247
+#include "locking-selftest-rlock.h"
1248
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_rlock)
1249
+
1250
+#include "locking-selftest-wlock.h"
1251
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion2_soft_wlock)
1252
+
1253
+#undef E1
1254
+#undef E2
1255
+#undef E3
1256
+/*
1257
+ * read-lock / write-lock recursion that is unsafe.
1258
+ *
1259
+ * A is a ENABLED_*_READ lock
1260
+ * B is a USED_IN_*_READ lock
1261
+ *
1262
+ * read_lock(A);
1263
+ * write_lock(B);
1264
+ * <interrupt>
1265
+ * read_lock(B);
1266
+ * write_lock(A); // if this one is read_lock(), no deadlock
1267
+ */
1268
+
1269
+#define E1() \
1270
+ \
1271
+ IRQ_DISABLE(); \
1272
+ WL(B); \
1273
+ LOCK(A); \
1274
+ UNLOCK(A); \
1275
+ WU(B); \
1276
+ IRQ_ENABLE();
1277
+
1278
+#define E2() \
1279
+ \
1280
+ RL(A); \
1281
+ RU(A); \
1282
+
1283
+#define E3() \
1284
+ \
1285
+ IRQ_ENTER(); \
1286
+ RL(B); \
1287
+ RU(B); \
1288
+ IRQ_EXIT();
1289
+
1290
+/*
1291
+ * Generate 24 testcases:
1292
+ */
1293
+#include "locking-selftest-hardirq.h"
1294
+#include "locking-selftest-rlock.h"
1295
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_rlock)
1296
+
1297
+#include "locking-selftest-wlock.h"
1298
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_hard_wlock)
1299
+
1300
+#include "locking-selftest-softirq.h"
1301
+#include "locking-selftest-rlock.h"
1302
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_rlock)
1303
+
1304
+#include "locking-selftest-wlock.h"
1305
+GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion3_soft_wlock)
10911306
10921307 #ifdef CONFIG_DEBUG_LOCK_ALLOC
10931308 # define I_SPINLOCK(x) lockdep_reset_lock(&lock_##x.dep_map)
....@@ -1226,6 +1441,19 @@
12261441 dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK); \
12271442 pr_cont("\n");
12281443
1444
+#define DO_TESTCASE_1RR(desc, name, nr) \
1445
+ print_testname(desc"/"#nr); \
1446
+ pr_cont(" |"); \
1447
+ dotest(name##_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
1448
+ pr_cont("\n");
1449
+
1450
+#define DO_TESTCASE_1RRB(desc, name, nr) \
1451
+ print_testname(desc"/"#nr); \
1452
+ pr_cont(" |"); \
1453
+ dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1454
+ pr_cont("\n");
1455
+
1456
+
12291457 #define DO_TESTCASE_3(desc, name, nr) \
12301458 print_testname(desc"/"#nr); \
12311459 dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN); \
....@@ -1239,6 +1467,25 @@
12391467 dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \
12401468 dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
12411469 pr_cont("\n");
1470
+
1471
+#define DO_TESTCASE_2RW(desc, name, nr) \
1472
+ print_testname(desc"/"#nr); \
1473
+ pr_cont(" |"); \
1474
+ dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \
1475
+ dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \
1476
+ pr_cont("\n");
1477
+
1478
+#define DO_TESTCASE_2x2RW(desc, name, nr) \
1479
+ DO_TESTCASE_2RW("hard-"desc, name##_hard, nr) \
1480
+ DO_TESTCASE_2RW("soft-"desc, name##_soft, nr) \
1481
+
1482
+#define DO_TESTCASE_6x2x2RW(desc, name) \
1483
+ DO_TESTCASE_2x2RW(desc, name, 123); \
1484
+ DO_TESTCASE_2x2RW(desc, name, 132); \
1485
+ DO_TESTCASE_2x2RW(desc, name, 213); \
1486
+ DO_TESTCASE_2x2RW(desc, name, 231); \
1487
+ DO_TESTCASE_2x2RW(desc, name, 312); \
1488
+ DO_TESTCASE_2x2RW(desc, name, 321);
12421489
12431490 #define DO_TESTCASE_6(desc, name) \
12441491 print_testname(desc); \
....@@ -1315,6 +1562,22 @@
13151562 DO_TESTCASE_2IB(desc, name, 231); \
13161563 DO_TESTCASE_2IB(desc, name, 312); \
13171564 DO_TESTCASE_2IB(desc, name, 321);
1565
+
1566
+#define DO_TESTCASE_6x1RR(desc, name) \
1567
+ DO_TESTCASE_1RR(desc, name, 123); \
1568
+ DO_TESTCASE_1RR(desc, name, 132); \
1569
+ DO_TESTCASE_1RR(desc, name, 213); \
1570
+ DO_TESTCASE_1RR(desc, name, 231); \
1571
+ DO_TESTCASE_1RR(desc, name, 312); \
1572
+ DO_TESTCASE_1RR(desc, name, 321);
1573
+
1574
+#define DO_TESTCASE_6x1RRB(desc, name) \
1575
+ DO_TESTCASE_1RRB(desc, name, 123); \
1576
+ DO_TESTCASE_1RRB(desc, name, 132); \
1577
+ DO_TESTCASE_1RRB(desc, name, 213); \
1578
+ DO_TESTCASE_1RRB(desc, name, 231); \
1579
+ DO_TESTCASE_1RRB(desc, name, 312); \
1580
+ DO_TESTCASE_1RRB(desc, name, 321);
13181581
13191582 #define DO_TESTCASE_6x6(desc, name) \
13201583 DO_TESTCASE_6I(desc, name, 123); \
....@@ -1502,7 +1765,7 @@
15021765
15031766 mutex_lock(&o2.base);
15041767 o2.ctx = &t2;
1505
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1768
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
15061769
15071770 WWAI(&t);
15081771 t2 = t;
....@@ -1527,7 +1790,7 @@
15271790 int ret;
15281791
15291792 mutex_lock(&o2.base);
1530
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1793
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
15311794 o2.ctx = &t2;
15321795
15331796 WWAI(&t);
....@@ -1554,7 +1817,7 @@
15541817
15551818 mutex_lock(&o2.base);
15561819 o2.ctx = &t2;
1557
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1820
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
15581821
15591822 WWAI(&t);
15601823 t2 = t;
....@@ -1578,7 +1841,7 @@
15781841 int ret;
15791842
15801843 mutex_lock(&o2.base);
1581
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1844
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
15821845 o2.ctx = &t2;
15831846
15841847 WWAI(&t);
....@@ -1603,7 +1866,7 @@
16031866 int ret;
16041867
16051868 mutex_lock(&o2.base);
1606
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1869
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
16071870 o2.ctx = &t2;
16081871
16091872 WWAI(&t);
....@@ -1624,7 +1887,7 @@
16241887 int ret;
16251888
16261889 mutex_lock(&o2.base);
1627
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1890
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
16281891 o2.ctx = &t2;
16291892
16301893 WWAI(&t);
....@@ -1645,11 +1908,11 @@
16451908 int ret;
16461909
16471910 mutex_lock(&o2.base);
1648
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1911
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
16491912 o2.ctx = &t2;
16501913
16511914 mutex_lock(&o3.base);
1652
- mutex_release(&o3.base.dep_map, 1, _THIS_IP_);
1915
+ mutex_release(&o3.base.dep_map, _THIS_IP_);
16531916 o3.ctx = &t2;
16541917
16551918 WWAI(&t);
....@@ -1671,11 +1934,11 @@
16711934 int ret;
16721935
16731936 mutex_lock(&o2.base);
1674
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1937
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
16751938 o2.ctx = &t2;
16761939
16771940 mutex_lock(&o3.base);
1678
- mutex_release(&o3.base.dep_map, 1, _THIS_IP_);
1941
+ mutex_release(&o3.base.dep_map, _THIS_IP_);
16791942 o3.ctx = &t2;
16801943
16811944 WWAI(&t);
....@@ -1696,7 +1959,7 @@
16961959 int ret;
16971960
16981961 mutex_lock(&o2.base);
1699
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1962
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
17001963 o2.ctx = &t2;
17011964
17021965 WWAI(&t);
....@@ -1721,7 +1984,7 @@
17211984 int ret;
17221985
17231986 mutex_lock(&o2.base);
1724
- mutex_release(&o2.base.dep_map, 1, _THIS_IP_);
1987
+ mutex_release(&o2.base.dep_map, _THIS_IP_);
17251988 o2.ctx = &t2;
17261989
17271990 WWAI(&t);
....@@ -1993,6 +2256,108 @@
19932256 pr_cont("\n");
19942257 }
19952258
2259
+
2260
+/*
2261
+ * <in hardirq handler>
2262
+ * read_lock(&A);
2263
+ * <hardirq disable>
2264
+ * spin_lock(&B);
2265
+ * spin_lock(&B);
2266
+ * read_lock(&A);
2267
+ *
2268
+ * is a deadlock.
2269
+ */
2270
+static void queued_read_lock_hardirq_RE_Er(void)
2271
+{
2272
+ HARDIRQ_ENTER();
2273
+ read_lock(&rwlock_A);
2274
+ LOCK(B);
2275
+ UNLOCK(B);
2276
+ read_unlock(&rwlock_A);
2277
+ HARDIRQ_EXIT();
2278
+
2279
+ HARDIRQ_DISABLE();
2280
+ LOCK(B);
2281
+ read_lock(&rwlock_A);
2282
+ read_unlock(&rwlock_A);
2283
+ UNLOCK(B);
2284
+ HARDIRQ_ENABLE();
2285
+}
2286
+
2287
+/*
2288
+ * <in hardirq handler>
2289
+ * spin_lock(&B);
2290
+ * <hardirq disable>
2291
+ * read_lock(&A);
2292
+ * read_lock(&A);
2293
+ * spin_lock(&B);
2294
+ *
2295
+ * is not a deadlock.
2296
+ */
2297
+static void queued_read_lock_hardirq_ER_rE(void)
2298
+{
2299
+ HARDIRQ_ENTER();
2300
+ LOCK(B);
2301
+ read_lock(&rwlock_A);
2302
+ read_unlock(&rwlock_A);
2303
+ UNLOCK(B);
2304
+ HARDIRQ_EXIT();
2305
+
2306
+ HARDIRQ_DISABLE();
2307
+ read_lock(&rwlock_A);
2308
+ LOCK(B);
2309
+ UNLOCK(B);
2310
+ read_unlock(&rwlock_A);
2311
+ HARDIRQ_ENABLE();
2312
+}
2313
+
2314
+/*
2315
+ * <hardirq disable>
2316
+ * spin_lock(&B);
2317
+ * read_lock(&A);
2318
+ * <in hardirq handler>
2319
+ * spin_lock(&B);
2320
+ * read_lock(&A);
2321
+ *
2322
+ * is a deadlock. Because the two read_lock()s are both non-recursive readers.
2323
+ */
2324
+static void queued_read_lock_hardirq_inversion(void)
2325
+{
2326
+
2327
+ HARDIRQ_ENTER();
2328
+ LOCK(B);
2329
+ UNLOCK(B);
2330
+ HARDIRQ_EXIT();
2331
+
2332
+ HARDIRQ_DISABLE();
2333
+ LOCK(B);
2334
+ read_lock(&rwlock_A);
2335
+ read_unlock(&rwlock_A);
2336
+ UNLOCK(B);
2337
+ HARDIRQ_ENABLE();
2338
+
2339
+ read_lock(&rwlock_A);
2340
+ read_unlock(&rwlock_A);
2341
+}
2342
+
2343
+static void queued_read_lock_tests(void)
2344
+{
2345
+ printk(" --------------------------------------------------------------------------\n");
2346
+ printk(" | queued read lock tests |\n");
2347
+ printk(" ---------------------------\n");
2348
+ print_testname("hardirq read-lock/lock-read");
2349
+ dotest(queued_read_lock_hardirq_RE_Er, FAILURE, LOCKTYPE_RWLOCK);
2350
+ pr_cont("\n");
2351
+
2352
+ print_testname("hardirq lock-read/read-lock");
2353
+ dotest(queued_read_lock_hardirq_ER_rE, SUCCESS, LOCKTYPE_RWLOCK);
2354
+ pr_cont("\n");
2355
+
2356
+ print_testname("hardirq inversion");
2357
+ dotest(queued_read_lock_hardirq_inversion, FAILURE, LOCKTYPE_RWLOCK);
2358
+ pr_cont("\n");
2359
+}
2360
+
19962361 void locking_selftest(void)
19972362 {
19982363 /*
....@@ -2006,6 +2371,11 @@
20062371 }
20072372
20082373 /*
2374
+ * treats read_lock() as recursive read locks for testing purpose
2375
+ */
2376
+ force_read_lock_recursive = 1;
2377
+
2378
+ /*
20092379 * Run the testsuite:
20102380 */
20112381 printk("------------------------\n");
....@@ -2016,6 +2386,7 @@
20162386
20172387 init_shared_classes();
20182388 debug_locks_silent = !debug_locks_verbose;
2389
+ lockdep_set_selftest_task(current);
20192390
20202391 DO_TESTCASE_6R("A-A deadlock", AA);
20212392 DO_TESTCASE_6R("A-B-B-A deadlock", ABBA);
....@@ -2059,14 +2430,6 @@
20592430 print_testname("mixed read-lock/lock-write ABBA");
20602431 pr_cont(" |");
20612432 dotest(rlock_ABBA1, FAILURE, LOCKTYPE_RWLOCK);
2062
-#ifdef CONFIG_PROVE_LOCKING
2063
- /*
2064
- * Lockdep does indeed fail here, but there's nothing we can do about
2065
- * that now. Don't kill lockdep for it.
2066
- */
2067
- unexpected_testcase_failures--;
2068
-#endif
2069
-
20702433 pr_cont(" |");
20712434 dotest(rwsem_ABBA1, FAILURE, LOCKTYPE_RWSEM);
20722435
....@@ -2082,9 +2445,17 @@
20822445 pr_cont(" |");
20832446 dotest(rwsem_ABBA3, FAILURE, LOCKTYPE_RWSEM);
20842447
2448
+ print_testname("chain cached mixed R-L/L-W ABBA");
2449
+ pr_cont(" |");
2450
+ dotest(rlock_chaincache_ABBA1, FAILURE, LOCKTYPE_RWLOCK);
2451
+
2452
+ DO_TESTCASE_6x1RRB("rlock W1R2/W2R3/W3R1", W1R2_W2R3_W3R1);
2453
+ DO_TESTCASE_6x1RRB("rlock W1W2/R2R3/W3R1", W1W2_R2R3_W3R1);
2454
+ DO_TESTCASE_6x1RR("rlock W1W2/R2R3/R3W1", W1W2_R2R3_R3W1);
2455
+ DO_TESTCASE_6x1RR("rlock W1R2/R2R3/W3W1", W1R2_R2R3_W3W1);
2456
+
20852457 printk(" --------------------------------------------------------------------------\n");
20862458
2087
-#ifndef CONFIG_PREEMPT_RT_FULL
20882459 /*
20892460 * irq-context testcases:
20902461 */
....@@ -2095,32 +2466,18 @@
20952466 DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4);
20962467 DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion);
20972468
2098
- DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion);
2099
-// DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2);
2100
-#else
2101
- /* On -rt, we only do hardirq context test for raw spinlock */
2102
- DO_TESTCASE_1B("hard-irqs-on + irq-safe-A", irqsafe1_hard_spin, 12);
2103
- DO_TESTCASE_1B("hard-irqs-on + irq-safe-A", irqsafe1_hard_spin, 21);
2104
-
2105
- DO_TESTCASE_1B("hard-safe-A + irqs-on", irqsafe2B_hard_spin, 12);
2106
- DO_TESTCASE_1B("hard-safe-A + irqs-on", irqsafe2B_hard_spin, 21);
2107
-
2108
- DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 123);
2109
- DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 132);
2110
- DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 213);
2111
- DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 231);
2112
- DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 312);
2113
- DO_TESTCASE_1B("hard-safe-A + unsafe-B #1", irqsafe3_hard_spin, 321);
2114
-
2115
- DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 123);
2116
- DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 132);
2117
- DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 213);
2118
- DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 231);
2119
- DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 312);
2120
- DO_TESTCASE_1B("hard-safe-A + unsafe-B #2", irqsafe4_hard_spin, 321);
2121
-#endif
2469
+ DO_TESTCASE_6x2x2RW("irq read-recursion", irq_read_recursion);
2470
+ DO_TESTCASE_6x2x2RW("irq read-recursion #2", irq_read_recursion2);
2471
+ DO_TESTCASE_6x2x2RW("irq read-recursion #3", irq_read_recursion3);
21222472
21232473 ww_tests();
2474
+
2475
+ force_read_lock_recursive = 0;
2476
+ /*
2477
+ * queued_read_lock() specific test cases can be put here
2478
+ */
2479
+ if (IS_ENABLED(CONFIG_QUEUED_RWLOCKS))
2480
+ queued_read_lock_tests();
21242481
21252482 if (unexpected_testcase_failures) {
21262483 printk("-----------------------------------------------------------------\n");
....@@ -2147,5 +2504,6 @@
21472504 printk("---------------------------------\n");
21482505 debug_locks = 1;
21492506 }
2507
+ lockdep_set_selftest_task(NULL);
21502508 debug_locks_silent = 0;
21512509 }