.. | .. |
---|
28 | 28 | * Change this to 1 if you want to see the failure printouts: |
---|
29 | 29 | */ |
---|
30 | 30 | static unsigned int debug_locks_verbose; |
---|
| 31 | +unsigned int force_read_lock_recursive; |
---|
31 | 32 | |
---|
32 | 33 | static DEFINE_WD_CLASS(ww_lockdep); |
---|
33 | 34 | |
---|
.. | .. |
---|
185 | 186 | #define HARDIRQ_ENTER() \ |
---|
186 | 187 | local_irq_disable(); \ |
---|
187 | 188 | __irq_enter(); \ |
---|
| 189 | + lockdep_hardirq_threaded(); \ |
---|
188 | 190 | WARN_ON(!in_irq()); |
---|
189 | 191 | |
---|
190 | 192 | #define HARDIRQ_EXIT() \ |
---|
.. | .. |
---|
393 | 395 | WSL(X1); |
---|
394 | 396 | WSU(X1); |
---|
395 | 397 | 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 |
---|
396 | 441 | } |
---|
397 | 442 | |
---|
398 | 443 | /* |
---|
.. | .. |
---|
742 | 787 | #include "locking-selftest-spin-hardirq.h" |
---|
743 | 788 | GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin) |
---|
744 | 789 | |
---|
| 790 | +#ifndef CONFIG_PREEMPT_RT |
---|
| 791 | + |
---|
745 | 792 | #include "locking-selftest-rlock-hardirq.h" |
---|
746 | 793 | GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock) |
---|
747 | 794 | |
---|
.. | .. |
---|
757 | 804 | #include "locking-selftest-wlock-softirq.h" |
---|
758 | 805 | GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock) |
---|
759 | 806 | |
---|
| 807 | +#endif |
---|
| 808 | + |
---|
760 | 809 | #undef E1 |
---|
761 | 810 | #undef E2 |
---|
762 | 811 | |
---|
| 812 | +#ifndef CONFIG_PREEMPT_RT |
---|
763 | 813 | /* |
---|
764 | 814 | * Enabling hardirqs with a softirq-safe lock held: |
---|
765 | 815 | */ |
---|
.. | .. |
---|
792 | 842 | #undef E1 |
---|
793 | 843 | #undef E2 |
---|
794 | 844 | |
---|
| 845 | +#endif |
---|
| 846 | + |
---|
795 | 847 | /* |
---|
796 | 848 | * Enabling irqs with an irq-safe lock held: |
---|
797 | 849 | */ |
---|
.. | .. |
---|
815 | 867 | #include "locking-selftest-spin-hardirq.h" |
---|
816 | 868 | GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin) |
---|
817 | 869 | |
---|
| 870 | +#ifndef CONFIG_PREEMPT_RT |
---|
| 871 | + |
---|
818 | 872 | #include "locking-selftest-rlock-hardirq.h" |
---|
819 | 873 | GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock) |
---|
820 | 874 | |
---|
.. | .. |
---|
829 | 883 | |
---|
830 | 884 | #include "locking-selftest-wlock-softirq.h" |
---|
831 | 885 | GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock) |
---|
| 886 | + |
---|
| 887 | +#endif |
---|
832 | 888 | |
---|
833 | 889 | #undef E1 |
---|
834 | 890 | #undef E2 |
---|
.. | .. |
---|
861 | 917 | #include "locking-selftest-spin-hardirq.h" |
---|
862 | 918 | GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin) |
---|
863 | 919 | |
---|
| 920 | +#ifndef CONFIG_PREEMPT_RT |
---|
| 921 | + |
---|
864 | 922 | #include "locking-selftest-rlock-hardirq.h" |
---|
865 | 923 | GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock) |
---|
866 | 924 | |
---|
.. | .. |
---|
875 | 933 | |
---|
876 | 934 | #include "locking-selftest-wlock-softirq.h" |
---|
877 | 935 | GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock) |
---|
| 936 | + |
---|
| 937 | +#endif |
---|
878 | 938 | |
---|
879 | 939 | #undef E1 |
---|
880 | 940 | #undef E2 |
---|
.. | .. |
---|
909 | 969 | #include "locking-selftest-spin-hardirq.h" |
---|
910 | 970 | GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin) |
---|
911 | 971 | |
---|
| 972 | +#ifndef CONFIG_PREEMPT_RT |
---|
| 973 | + |
---|
912 | 974 | #include "locking-selftest-rlock-hardirq.h" |
---|
913 | 975 | GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock) |
---|
914 | 976 | |
---|
.. | .. |
---|
924 | 986 | #include "locking-selftest-wlock-softirq.h" |
---|
925 | 987 | GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock) |
---|
926 | 988 | |
---|
| 989 | +#endif |
---|
| 990 | + |
---|
927 | 991 | #undef E1 |
---|
928 | 992 | #undef E2 |
---|
929 | 993 | #undef E3 |
---|
| 994 | + |
---|
| 995 | +#ifndef CONFIG_PREEMPT_RT |
---|
930 | 996 | |
---|
931 | 997 | /* |
---|
932 | 998 | * read-lock / write-lock irq inversion. |
---|
.. | .. |
---|
991 | 1057 | #undef E3 |
---|
992 | 1058 | |
---|
993 | 1059 | /* |
---|
| 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 | +/* |
---|
994 | 1192 | * read-lock / write-lock recursion that is actually safe. |
---|
995 | 1193 | */ |
---|
996 | 1194 | |
---|
.. | .. |
---|
1009 | 1207 | #define E3() \ |
---|
1010 | 1208 | \ |
---|
1011 | 1209 | IRQ_ENTER(); \ |
---|
1012 | | - RL(A); \ |
---|
| 1210 | + LOCK(A); \ |
---|
1013 | 1211 | L(B); \ |
---|
1014 | 1212 | U(B); \ |
---|
1015 | | - RU(A); \ |
---|
| 1213 | + UNLOCK(A); \ |
---|
1016 | 1214 | IRQ_EXIT(); |
---|
1017 | 1215 | |
---|
1018 | 1216 | /* |
---|
1019 | | - * Generate 12 testcases: |
---|
| 1217 | + * Generate 24 testcases: |
---|
1020 | 1218 | */ |
---|
1021 | 1219 | #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) |
---|
1023 | 1225 | |
---|
1024 | 1226 | #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) |
---|
1026 | 1232 | |
---|
1027 | 1233 | #undef E1 |
---|
1028 | 1234 | #undef E2 |
---|
1029 | 1235 | #undef E3 |
---|
| 1236 | + |
---|
| 1237 | +#endif |
---|
1030 | 1238 | |
---|
1031 | 1239 | /* |
---|
1032 | 1240 | * read-lock / write-lock recursion that is unsafe. |
---|
.. | .. |
---|
1036 | 1244 | \ |
---|
1037 | 1245 | IRQ_DISABLE(); \ |
---|
1038 | 1246 | L(B); \ |
---|
1039 | | - WL(A); \ |
---|
1040 | | - WU(A); \ |
---|
| 1247 | + LOCK(A); \ |
---|
| 1248 | + UNLOCK(A); \ |
---|
1041 | 1249 | U(B); \ |
---|
1042 | 1250 | IRQ_ENABLE(); |
---|
1043 | 1251 | |
---|
.. | .. |
---|
1054 | 1262 | IRQ_EXIT(); |
---|
1055 | 1263 | |
---|
1056 | 1264 | /* |
---|
1057 | | - * Generate 12 testcases: |
---|
| 1265 | + * Generate 24 testcases: |
---|
1058 | 1266 | */ |
---|
1059 | 1267 | #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) |
---|
1061 | 1273 | |
---|
1062 | 1274 | #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) |
---|
1064 | 1334 | |
---|
1065 | 1335 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
---|
1066 | 1336 | # define I_SPINLOCK(x) lockdep_reset_lock(&lock_##x.dep_map) |
---|
.. | .. |
---|
1199 | 1469 | dotest(name##_##nr, FAILURE, LOCKTYPE_RWLOCK); \ |
---|
1200 | 1470 | pr_cont("\n"); |
---|
1201 | 1471 | |
---|
| 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 | + |
---|
1202 | 1485 | #define DO_TESTCASE_3(desc, name, nr) \ |
---|
1203 | 1486 | print_testname(desc"/"#nr); \ |
---|
1204 | 1487 | dotest(name##_spin_##nr, FAILURE, LOCKTYPE_SPIN); \ |
---|
.. | .. |
---|
1212 | 1495 | dotest(name##_wlock_##nr, FAILURE, LOCKTYPE_RWLOCK); \ |
---|
1213 | 1496 | dotest(name##_rlock_##nr, SUCCESS, LOCKTYPE_RWLOCK); \ |
---|
1214 | 1497 | 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); |
---|
1215 | 1517 | |
---|
1216 | 1518 | #define DO_TESTCASE_6(desc, name) \ |
---|
1217 | 1519 | print_testname(desc); \ |
---|
.. | .. |
---|
1288 | 1590 | DO_TESTCASE_2IB(desc, name, 231); \ |
---|
1289 | 1591 | DO_TESTCASE_2IB(desc, name, 312); \ |
---|
1290 | 1592 | 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); |
---|
1291 | 1609 | |
---|
1292 | 1610 | #define DO_TESTCASE_6x6(desc, name) \ |
---|
1293 | 1611 | DO_TESTCASE_6I(desc, name, 123); \ |
---|
.. | .. |
---|
1475 | 1793 | |
---|
1476 | 1794 | mutex_lock(&o2.base); |
---|
1477 | 1795 | o2.ctx = &t2; |
---|
1478 | | - mutex_release(&o2.base.dep_map, 1, _THIS_IP_); |
---|
| 1796 | + mutex_release(&o2.base.dep_map, _THIS_IP_); |
---|
1479 | 1797 | |
---|
1480 | 1798 | WWAI(&t); |
---|
1481 | 1799 | t2 = t; |
---|
.. | .. |
---|
1500 | 1818 | int ret; |
---|
1501 | 1819 | |
---|
1502 | 1820 | mutex_lock(&o2.base); |
---|
1503 | | - mutex_release(&o2.base.dep_map, 1, _THIS_IP_); |
---|
| 1821 | + mutex_release(&o2.base.dep_map, _THIS_IP_); |
---|
1504 | 1822 | o2.ctx = &t2; |
---|
1505 | 1823 | |
---|
1506 | 1824 | WWAI(&t); |
---|
.. | .. |
---|
1527 | 1845 | |
---|
1528 | 1846 | mutex_lock(&o2.base); |
---|
1529 | 1847 | o2.ctx = &t2; |
---|
1530 | | - mutex_release(&o2.base.dep_map, 1, _THIS_IP_); |
---|
| 1848 | + mutex_release(&o2.base.dep_map, _THIS_IP_); |
---|
1531 | 1849 | |
---|
1532 | 1850 | WWAI(&t); |
---|
1533 | 1851 | t2 = t; |
---|
.. | .. |
---|
1551 | 1869 | int ret; |
---|
1552 | 1870 | |
---|
1553 | 1871 | mutex_lock(&o2.base); |
---|
1554 | | - mutex_release(&o2.base.dep_map, 1, _THIS_IP_); |
---|
| 1872 | + mutex_release(&o2.base.dep_map, _THIS_IP_); |
---|
1555 | 1873 | o2.ctx = &t2; |
---|
1556 | 1874 | |
---|
1557 | 1875 | WWAI(&t); |
---|
.. | .. |
---|
1576 | 1894 | int ret; |
---|
1577 | 1895 | |
---|
1578 | 1896 | mutex_lock(&o2.base); |
---|
1579 | | - mutex_release(&o2.base.dep_map, 1, _THIS_IP_); |
---|
| 1897 | + mutex_release(&o2.base.dep_map, _THIS_IP_); |
---|
1580 | 1898 | o2.ctx = &t2; |
---|
1581 | 1899 | |
---|
1582 | 1900 | WWAI(&t); |
---|
.. | .. |
---|
1597 | 1915 | int ret; |
---|
1598 | 1916 | |
---|
1599 | 1917 | mutex_lock(&o2.base); |
---|
1600 | | - mutex_release(&o2.base.dep_map, 1, _THIS_IP_); |
---|
| 1918 | + mutex_release(&o2.base.dep_map, _THIS_IP_); |
---|
1601 | 1919 | o2.ctx = &t2; |
---|
1602 | 1920 | |
---|
1603 | 1921 | WWAI(&t); |
---|
.. | .. |
---|
1618 | 1936 | int ret; |
---|
1619 | 1937 | |
---|
1620 | 1938 | mutex_lock(&o2.base); |
---|
1621 | | - mutex_release(&o2.base.dep_map, 1, _THIS_IP_); |
---|
| 1939 | + mutex_release(&o2.base.dep_map, _THIS_IP_); |
---|
1622 | 1940 | o2.ctx = &t2; |
---|
1623 | 1941 | |
---|
1624 | 1942 | mutex_lock(&o3.base); |
---|
1625 | | - mutex_release(&o3.base.dep_map, 1, _THIS_IP_); |
---|
| 1943 | + mutex_release(&o3.base.dep_map, _THIS_IP_); |
---|
1626 | 1944 | o3.ctx = &t2; |
---|
1627 | 1945 | |
---|
1628 | 1946 | WWAI(&t); |
---|
.. | .. |
---|
1644 | 1962 | int ret; |
---|
1645 | 1963 | |
---|
1646 | 1964 | mutex_lock(&o2.base); |
---|
1647 | | - mutex_release(&o2.base.dep_map, 1, _THIS_IP_); |
---|
| 1965 | + mutex_release(&o2.base.dep_map, _THIS_IP_); |
---|
1648 | 1966 | o2.ctx = &t2; |
---|
1649 | 1967 | |
---|
1650 | 1968 | mutex_lock(&o3.base); |
---|
1651 | | - mutex_release(&o3.base.dep_map, 1, _THIS_IP_); |
---|
| 1969 | + mutex_release(&o3.base.dep_map, _THIS_IP_); |
---|
1652 | 1970 | o3.ctx = &t2; |
---|
1653 | 1971 | |
---|
1654 | 1972 | WWAI(&t); |
---|
.. | .. |
---|
1669 | 1987 | int ret; |
---|
1670 | 1988 | |
---|
1671 | 1989 | mutex_lock(&o2.base); |
---|
1672 | | - mutex_release(&o2.base.dep_map, 1, _THIS_IP_); |
---|
| 1990 | + mutex_release(&o2.base.dep_map, _THIS_IP_); |
---|
1673 | 1991 | o2.ctx = &t2; |
---|
1674 | 1992 | |
---|
1675 | 1993 | WWAI(&t); |
---|
.. | .. |
---|
1694 | 2012 | int ret; |
---|
1695 | 2013 | |
---|
1696 | 2014 | mutex_lock(&o2.base); |
---|
1697 | | - mutex_release(&o2.base.dep_map, 1, _THIS_IP_); |
---|
| 2015 | + mutex_release(&o2.base.dep_map, _THIS_IP_); |
---|
1698 | 2016 | o2.ctx = &t2; |
---|
1699 | 2017 | |
---|
1700 | 2018 | WWAI(&t); |
---|
.. | .. |
---|
1966 | 2284 | pr_cont("\n"); |
---|
1967 | 2285 | } |
---|
1968 | 2286 | |
---|
| 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 | + |
---|
1969 | 2389 | void locking_selftest(void) |
---|
1970 | 2390 | { |
---|
1971 | 2391 | /* |
---|
.. | .. |
---|
1979 | 2399 | } |
---|
1980 | 2400 | |
---|
1981 | 2401 | /* |
---|
| 2402 | + * treats read_lock() as recursive read locks for testing purpose |
---|
| 2403 | + */ |
---|
| 2404 | + force_read_lock_recursive = 1; |
---|
| 2405 | + |
---|
| 2406 | + /* |
---|
1982 | 2407 | * Run the testsuite: |
---|
1983 | 2408 | */ |
---|
1984 | 2409 | printk("------------------------\n"); |
---|
.. | .. |
---|
1989 | 2414 | |
---|
1990 | 2415 | init_shared_classes(); |
---|
1991 | 2416 | debug_locks_silent = !debug_locks_verbose; |
---|
| 2417 | + lockdep_set_selftest_task(current); |
---|
1992 | 2418 | |
---|
1993 | 2419 | DO_TESTCASE_6R("A-A deadlock", AA); |
---|
1994 | 2420 | DO_TESTCASE_6R("A-B-B-A deadlock", ABBA); |
---|
.. | .. |
---|
2032 | 2458 | print_testname("mixed read-lock/lock-write ABBA"); |
---|
2033 | 2459 | pr_cont(" |"); |
---|
2034 | 2460 | 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 | | - |
---|
2043 | 2461 | pr_cont(" |"); |
---|
2044 | 2462 | dotest(rwsem_ABBA1, FAILURE, LOCKTYPE_RWSEM); |
---|
2045 | 2463 | |
---|
.. | .. |
---|
2055 | 2473 | pr_cont(" |"); |
---|
2056 | 2474 | dotest(rwsem_ABBA3, FAILURE, LOCKTYPE_RWSEM); |
---|
2057 | 2475 | |
---|
| 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 | + |
---|
2058 | 2485 | printk(" --------------------------------------------------------------------------\n"); |
---|
2059 | 2486 | |
---|
| 2487 | +#ifndef CONFIG_PREEMPT_RT |
---|
2060 | 2488 | /* |
---|
2061 | 2489 | * irq-context testcases: |
---|
2062 | 2490 | */ |
---|
.. | .. |
---|
2067 | 2495 | DO_TESTCASE_6x6("safe-A + unsafe-B #2", irqsafe4); |
---|
2068 | 2496 | DO_TESTCASE_6x6RW("irq lock-inversion", irq_inversion); |
---|
2069 | 2497 | |
---|
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); |
---|
2072 | 2501 | |
---|
| 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 |
---|
2073 | 2524 | 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(); |
---|
2074 | 2532 | |
---|
2075 | 2533 | if (unexpected_testcase_failures) { |
---|
2076 | 2534 | printk("-----------------------------------------------------------------\n"); |
---|
.. | .. |
---|
2097 | 2555 | printk("---------------------------------\n"); |
---|
2098 | 2556 | debug_locks = 1; |
---|
2099 | 2557 | } |
---|
| 2558 | + lockdep_set_selftest_task(NULL); |
---|
2100 | 2559 | debug_locks_silent = 0; |
---|
2101 | 2560 | } |
---|