diff options
Diffstat (limited to 'lib/locking-selftest.c')
-rw-r--r-- | lib/locking-selftest.c | 721 |
1 files changed, 703 insertions, 18 deletions
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index c3eb261a7df3..6dc09d8f4c24 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | #include <linux/rwsem.h> | 13 | #include <linux/rwsem.h> |
14 | #include <linux/mutex.h> | 14 | #include <linux/mutex.h> |
15 | #include <linux/ww_mutex.h> | ||
15 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
16 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
17 | #include <linux/lockdep.h> | 18 | #include <linux/lockdep.h> |
@@ -26,6 +27,8 @@ | |||
26 | */ | 27 | */ |
27 | static unsigned int debug_locks_verbose; | 28 | static unsigned int debug_locks_verbose; |
28 | 29 | ||
30 | static DEFINE_WW_CLASS(ww_lockdep); | ||
31 | |||
29 | static int __init setup_debug_locks_verbose(char *str) | 32 | static int __init setup_debug_locks_verbose(char *str) |
30 | { | 33 | { |
31 | get_option(&str, &debug_locks_verbose); | 34 | get_option(&str, &debug_locks_verbose); |
@@ -42,6 +45,10 @@ __setup("debug_locks_verbose=", setup_debug_locks_verbose); | |||
42 | #define LOCKTYPE_RWLOCK 0x2 | 45 | #define LOCKTYPE_RWLOCK 0x2 |
43 | #define LOCKTYPE_MUTEX 0x4 | 46 | #define LOCKTYPE_MUTEX 0x4 |
44 | #define LOCKTYPE_RWSEM 0x8 | 47 | #define LOCKTYPE_RWSEM 0x8 |
48 | #define LOCKTYPE_WW 0x10 | ||
49 | |||
50 | static struct ww_acquire_ctx t, t2; | ||
51 | static struct ww_mutex o, o2, o3; | ||
45 | 52 | ||
46 | /* | 53 | /* |
47 | * Normal standalone locks, for the circular and irq-context | 54 | * Normal standalone locks, for the circular and irq-context |
@@ -193,6 +200,20 @@ static void init_shared_classes(void) | |||
193 | #define RSU(x) up_read(&rwsem_##x) | 200 | #define RSU(x) up_read(&rwsem_##x) |
194 | #define RWSI(x) init_rwsem(&rwsem_##x) | 201 | #define RWSI(x) init_rwsem(&rwsem_##x) |
195 | 202 | ||
203 | #ifndef CONFIG_DEBUG_WW_MUTEX_SLOWPATH | ||
204 | #define WWAI(x) ww_acquire_init(x, &ww_lockdep) | ||
205 | #else | ||
206 | #define WWAI(x) do { ww_acquire_init(x, &ww_lockdep); (x)->deadlock_inject_countdown = ~0U; } while (0) | ||
207 | #endif | ||
208 | #define WWAD(x) ww_acquire_done(x) | ||
209 | #define WWAF(x) ww_acquire_fini(x) | ||
210 | |||
211 | #define WWL(x, c) ww_mutex_lock(x, c) | ||
212 | #define WWT(x) ww_mutex_trylock(x) | ||
213 | #define WWL1(x) ww_mutex_lock(x, NULL) | ||
214 | #define WWU(x) ww_mutex_unlock(x) | ||
215 | |||
216 | |||
196 | #define LOCK_UNLOCK_2(x,y) LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x) | 217 | #define LOCK_UNLOCK_2(x,y) LOCK(x); LOCK(y); UNLOCK(y); UNLOCK(x) |
197 | 218 | ||
198 | /* | 219 | /* |
@@ -894,11 +915,13 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft) | |||
894 | # define I_RWLOCK(x) lockdep_reset_lock(&rwlock_##x.dep_map) | 915 | # define I_RWLOCK(x) lockdep_reset_lock(&rwlock_##x.dep_map) |
895 | # define I_MUTEX(x) lockdep_reset_lock(&mutex_##x.dep_map) | 916 | # define I_MUTEX(x) lockdep_reset_lock(&mutex_##x.dep_map) |
896 | # define I_RWSEM(x) lockdep_reset_lock(&rwsem_##x.dep_map) | 917 | # define I_RWSEM(x) lockdep_reset_lock(&rwsem_##x.dep_map) |
918 | # define I_WW(x) lockdep_reset_lock(&x.dep_map) | ||
897 | #else | 919 | #else |
898 | # define I_SPINLOCK(x) | 920 | # define I_SPINLOCK(x) |
899 | # define I_RWLOCK(x) | 921 | # define I_RWLOCK(x) |
900 | # define I_MUTEX(x) | 922 | # define I_MUTEX(x) |
901 | # define I_RWSEM(x) | 923 | # define I_RWSEM(x) |
924 | # define I_WW(x) | ||
902 | #endif | 925 | #endif |
903 | 926 | ||
904 | #define I1(x) \ | 927 | #define I1(x) \ |
@@ -920,11 +943,20 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_recursion_soft) | |||
920 | static void reset_locks(void) | 943 | static void reset_locks(void) |
921 | { | 944 | { |
922 | local_irq_disable(); | 945 | local_irq_disable(); |
946 | lockdep_free_key_range(&ww_lockdep.acquire_key, 1); | ||
947 | lockdep_free_key_range(&ww_lockdep.mutex_key, 1); | ||
948 | |||
923 | I1(A); I1(B); I1(C); I1(D); | 949 | I1(A); I1(B); I1(C); I1(D); |
924 | I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2); | 950 | I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2); |
951 | I_WW(t); I_WW(t2); I_WW(o.base); I_WW(o2.base); I_WW(o3.base); | ||
925 | lockdep_reset(); | 952 | lockdep_reset(); |
926 | I2(A); I2(B); I2(C); I2(D); | 953 | I2(A); I2(B); I2(C); I2(D); |
927 | init_shared_classes(); | 954 | init_shared_classes(); |
955 | |||
956 | ww_mutex_init(&o, &ww_lockdep); ww_mutex_init(&o2, &ww_lockdep); ww_mutex_init(&o3, &ww_lockdep); | ||
957 | memset(&t, 0, sizeof(t)); memset(&t2, 0, sizeof(t2)); | ||
958 | memset(&ww_lockdep.acquire_key, 0, sizeof(ww_lockdep.acquire_key)); | ||
959 | memset(&ww_lockdep.mutex_key, 0, sizeof(ww_lockdep.mutex_key)); | ||
928 | local_irq_enable(); | 960 | local_irq_enable(); |
929 | } | 961 | } |
930 | 962 | ||
@@ -938,7 +970,6 @@ static int unexpected_testcase_failures; | |||
938 | static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) | 970 | static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) |
939 | { | 971 | { |
940 | unsigned long saved_preempt_count = preempt_count(); | 972 | unsigned long saved_preempt_count = preempt_count(); |
941 | int expected_failure = 0; | ||
942 | 973 | ||
943 | WARN_ON(irqs_disabled()); | 974 | WARN_ON(irqs_disabled()); |
944 | 975 | ||
@@ -947,25 +978,17 @@ static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) | |||
947 | * Filter out expected failures: | 978 | * Filter out expected failures: |
948 | */ | 979 | */ |
949 | #ifndef CONFIG_PROVE_LOCKING | 980 | #ifndef CONFIG_PROVE_LOCKING |
950 | if ((lockclass_mask & LOCKTYPE_SPIN) && debug_locks != expected) | 981 | if (expected == FAILURE && debug_locks) { |
951 | expected_failure = 1; | 982 | expected_testcase_failures++; |
952 | if ((lockclass_mask & LOCKTYPE_RWLOCK) && debug_locks != expected) | 983 | printk("failed|"); |
953 | expected_failure = 1; | 984 | } |
954 | if ((lockclass_mask & LOCKTYPE_MUTEX) && debug_locks != expected) | 985 | else |
955 | expected_failure = 1; | ||
956 | if ((lockclass_mask & LOCKTYPE_RWSEM) && debug_locks != expected) | ||
957 | expected_failure = 1; | ||
958 | #endif | 986 | #endif |
959 | if (debug_locks != expected) { | 987 | if (debug_locks != expected) { |
960 | if (expected_failure) { | 988 | unexpected_testcase_failures++; |
961 | expected_testcase_failures++; | 989 | printk("FAILED|"); |
962 | printk("failed|"); | 990 | |
963 | } else { | 991 | dump_stack(); |
964 | unexpected_testcase_failures++; | ||
965 | |||
966 | printk("FAILED|"); | ||
967 | dump_stack(); | ||
968 | } | ||
969 | } else { | 992 | } else { |
970 | testcase_successes++; | 993 | testcase_successes++; |
971 | printk(" ok |"); | 994 | printk(" ok |"); |
@@ -1108,6 +1131,666 @@ static inline void print_testname(const char *testname) | |||
1108 | DO_TESTCASE_6IRW(desc, name, 312); \ | 1131 | DO_TESTCASE_6IRW(desc, name, 312); \ |
1109 | DO_TESTCASE_6IRW(desc, name, 321); | 1132 | DO_TESTCASE_6IRW(desc, name, 321); |
1110 | 1133 | ||
1134 | static void ww_test_fail_acquire(void) | ||
1135 | { | ||
1136 | int ret; | ||
1137 | |||
1138 | WWAI(&t); | ||
1139 | t.stamp++; | ||
1140 | |||
1141 | ret = WWL(&o, &t); | ||
1142 | |||
1143 | if (WARN_ON(!o.ctx) || | ||
1144 | WARN_ON(ret)) | ||
1145 | return; | ||
1146 | |||
1147 | /* No lockdep test, pure API */ | ||
1148 | ret = WWL(&o, &t); | ||
1149 | WARN_ON(ret != -EALREADY); | ||
1150 | |||
1151 | ret = WWT(&o); | ||
1152 | WARN_ON(ret); | ||
1153 | |||
1154 | t2 = t; | ||
1155 | t2.stamp++; | ||
1156 | ret = WWL(&o, &t2); | ||
1157 | WARN_ON(ret != -EDEADLK); | ||
1158 | WWU(&o); | ||
1159 | |||
1160 | if (WWT(&o)) | ||
1161 | WWU(&o); | ||
1162 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
1163 | else | ||
1164 | DEBUG_LOCKS_WARN_ON(1); | ||
1165 | #endif | ||
1166 | } | ||
1167 | |||
1168 | static void ww_test_normal(void) | ||
1169 | { | ||
1170 | int ret; | ||
1171 | |||
1172 | WWAI(&t); | ||
1173 | |||
1174 | /* | ||
1175 | * None of the ww_mutex codepaths should be taken in the 'normal' | ||
1176 | * mutex calls. The easiest way to verify this is by using the | ||
1177 | * normal mutex calls, and making sure o.ctx is unmodified. | ||
1178 | */ | ||
1179 | |||
1180 | /* mutex_lock (and indirectly, mutex_lock_nested) */ | ||
1181 | o.ctx = (void *)~0UL; | ||
1182 | mutex_lock(&o.base); | ||
1183 | mutex_unlock(&o.base); | ||
1184 | WARN_ON(o.ctx != (void *)~0UL); | ||
1185 | |||
1186 | /* mutex_lock_interruptible (and *_nested) */ | ||
1187 | o.ctx = (void *)~0UL; | ||
1188 | ret = mutex_lock_interruptible(&o.base); | ||
1189 | if (!ret) | ||
1190 | mutex_unlock(&o.base); | ||
1191 | else | ||
1192 | WARN_ON(1); | ||
1193 | WARN_ON(o.ctx != (void *)~0UL); | ||
1194 | |||
1195 | /* mutex_lock_killable (and *_nested) */ | ||
1196 | o.ctx = (void *)~0UL; | ||
1197 | ret = mutex_lock_killable(&o.base); | ||
1198 | if (!ret) | ||
1199 | mutex_unlock(&o.base); | ||
1200 | else | ||
1201 | WARN_ON(1); | ||
1202 | WARN_ON(o.ctx != (void *)~0UL); | ||
1203 | |||
1204 | /* trylock, succeeding */ | ||
1205 | o.ctx = (void *)~0UL; | ||
1206 | ret = mutex_trylock(&o.base); | ||
1207 | WARN_ON(!ret); | ||
1208 | if (ret) | ||
1209 | mutex_unlock(&o.base); | ||
1210 | else | ||
1211 | WARN_ON(1); | ||
1212 | WARN_ON(o.ctx != (void *)~0UL); | ||
1213 | |||
1214 | /* trylock, failing */ | ||
1215 | o.ctx = (void *)~0UL; | ||
1216 | mutex_lock(&o.base); | ||
1217 | ret = mutex_trylock(&o.base); | ||
1218 | WARN_ON(ret); | ||
1219 | mutex_unlock(&o.base); | ||
1220 | WARN_ON(o.ctx != (void *)~0UL); | ||
1221 | |||
1222 | /* nest_lock */ | ||
1223 | o.ctx = (void *)~0UL; | ||
1224 | mutex_lock_nest_lock(&o.base, &t); | ||
1225 | mutex_unlock(&o.base); | ||
1226 | WARN_ON(o.ctx != (void *)~0UL); | ||
1227 | } | ||
1228 | |||
1229 | static void ww_test_two_contexts(void) | ||
1230 | { | ||
1231 | WWAI(&t); | ||
1232 | WWAI(&t2); | ||
1233 | } | ||
1234 | |||
1235 | static void ww_test_diff_class(void) | ||
1236 | { | ||
1237 | WWAI(&t); | ||
1238 | #ifdef CONFIG_DEBUG_MUTEXES | ||
1239 | t.ww_class = NULL; | ||
1240 | #endif | ||
1241 | WWL(&o, &t); | ||
1242 | } | ||
1243 | |||
1244 | static void ww_test_context_done_twice(void) | ||
1245 | { | ||
1246 | WWAI(&t); | ||
1247 | WWAD(&t); | ||
1248 | WWAD(&t); | ||
1249 | WWAF(&t); | ||
1250 | } | ||
1251 | |||
1252 | static void ww_test_context_unlock_twice(void) | ||
1253 | { | ||
1254 | WWAI(&t); | ||
1255 | WWAD(&t); | ||
1256 | WWAF(&t); | ||
1257 | WWAF(&t); | ||
1258 | } | ||
1259 | |||
1260 | static void ww_test_context_fini_early(void) | ||
1261 | { | ||
1262 | WWAI(&t); | ||
1263 | WWL(&o, &t); | ||
1264 | WWAD(&t); | ||
1265 | WWAF(&t); | ||
1266 | } | ||
1267 | |||
1268 | static void ww_test_context_lock_after_done(void) | ||
1269 | { | ||
1270 | WWAI(&t); | ||
1271 | WWAD(&t); | ||
1272 | WWL(&o, &t); | ||
1273 | } | ||
1274 | |||
1275 | static void ww_test_object_unlock_twice(void) | ||
1276 | { | ||
1277 | WWL1(&o); | ||
1278 | WWU(&o); | ||
1279 | WWU(&o); | ||
1280 | } | ||
1281 | |||
1282 | static void ww_test_object_lock_unbalanced(void) | ||
1283 | { | ||
1284 | WWAI(&t); | ||
1285 | WWL(&o, &t); | ||
1286 | t.acquired = 0; | ||
1287 | WWU(&o); | ||
1288 | WWAF(&t); | ||
1289 | } | ||
1290 | |||
1291 | static void ww_test_object_lock_stale_context(void) | ||
1292 | { | ||
1293 | WWAI(&t); | ||
1294 | o.ctx = &t2; | ||
1295 | WWL(&o, &t); | ||
1296 | } | ||
1297 | |||
1298 | static void ww_test_edeadlk_normal(void) | ||
1299 | { | ||
1300 | int ret; | ||
1301 | |||
1302 | mutex_lock(&o2.base); | ||
1303 | o2.ctx = &t2; | ||
1304 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1305 | |||
1306 | WWAI(&t); | ||
1307 | t2 = t; | ||
1308 | t2.stamp--; | ||
1309 | |||
1310 | ret = WWL(&o, &t); | ||
1311 | WARN_ON(ret); | ||
1312 | |||
1313 | ret = WWL(&o2, &t); | ||
1314 | WARN_ON(ret != -EDEADLK); | ||
1315 | |||
1316 | o2.ctx = NULL; | ||
1317 | mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); | ||
1318 | mutex_unlock(&o2.base); | ||
1319 | WWU(&o); | ||
1320 | |||
1321 | WWL(&o2, &t); | ||
1322 | } | ||
1323 | |||
1324 | static void ww_test_edeadlk_normal_slow(void) | ||
1325 | { | ||
1326 | int ret; | ||
1327 | |||
1328 | mutex_lock(&o2.base); | ||
1329 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1330 | o2.ctx = &t2; | ||
1331 | |||
1332 | WWAI(&t); | ||
1333 | t2 = t; | ||
1334 | t2.stamp--; | ||
1335 | |||
1336 | ret = WWL(&o, &t); | ||
1337 | WARN_ON(ret); | ||
1338 | |||
1339 | ret = WWL(&o2, &t); | ||
1340 | WARN_ON(ret != -EDEADLK); | ||
1341 | |||
1342 | o2.ctx = NULL; | ||
1343 | mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); | ||
1344 | mutex_unlock(&o2.base); | ||
1345 | WWU(&o); | ||
1346 | |||
1347 | ww_mutex_lock_slow(&o2, &t); | ||
1348 | } | ||
1349 | |||
1350 | static void ww_test_edeadlk_no_unlock(void) | ||
1351 | { | ||
1352 | int ret; | ||
1353 | |||
1354 | mutex_lock(&o2.base); | ||
1355 | o2.ctx = &t2; | ||
1356 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1357 | |||
1358 | WWAI(&t); | ||
1359 | t2 = t; | ||
1360 | t2.stamp--; | ||
1361 | |||
1362 | ret = WWL(&o, &t); | ||
1363 | WARN_ON(ret); | ||
1364 | |||
1365 | ret = WWL(&o2, &t); | ||
1366 | WARN_ON(ret != -EDEADLK); | ||
1367 | |||
1368 | o2.ctx = NULL; | ||
1369 | mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); | ||
1370 | mutex_unlock(&o2.base); | ||
1371 | |||
1372 | WWL(&o2, &t); | ||
1373 | } | ||
1374 | |||
1375 | static void ww_test_edeadlk_no_unlock_slow(void) | ||
1376 | { | ||
1377 | int ret; | ||
1378 | |||
1379 | mutex_lock(&o2.base); | ||
1380 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1381 | o2.ctx = &t2; | ||
1382 | |||
1383 | WWAI(&t); | ||
1384 | t2 = t; | ||
1385 | t2.stamp--; | ||
1386 | |||
1387 | ret = WWL(&o, &t); | ||
1388 | WARN_ON(ret); | ||
1389 | |||
1390 | ret = WWL(&o2, &t); | ||
1391 | WARN_ON(ret != -EDEADLK); | ||
1392 | |||
1393 | o2.ctx = NULL; | ||
1394 | mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); | ||
1395 | mutex_unlock(&o2.base); | ||
1396 | |||
1397 | ww_mutex_lock_slow(&o2, &t); | ||
1398 | } | ||
1399 | |||
1400 | static void ww_test_edeadlk_acquire_more(void) | ||
1401 | { | ||
1402 | int ret; | ||
1403 | |||
1404 | mutex_lock(&o2.base); | ||
1405 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1406 | o2.ctx = &t2; | ||
1407 | |||
1408 | WWAI(&t); | ||
1409 | t2 = t; | ||
1410 | t2.stamp--; | ||
1411 | |||
1412 | ret = WWL(&o, &t); | ||
1413 | WARN_ON(ret); | ||
1414 | |||
1415 | ret = WWL(&o2, &t); | ||
1416 | WARN_ON(ret != -EDEADLK); | ||
1417 | |||
1418 | ret = WWL(&o3, &t); | ||
1419 | } | ||
1420 | |||
1421 | static void ww_test_edeadlk_acquire_more_slow(void) | ||
1422 | { | ||
1423 | int ret; | ||
1424 | |||
1425 | mutex_lock(&o2.base); | ||
1426 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1427 | o2.ctx = &t2; | ||
1428 | |||
1429 | WWAI(&t); | ||
1430 | t2 = t; | ||
1431 | t2.stamp--; | ||
1432 | |||
1433 | ret = WWL(&o, &t); | ||
1434 | WARN_ON(ret); | ||
1435 | |||
1436 | ret = WWL(&o2, &t); | ||
1437 | WARN_ON(ret != -EDEADLK); | ||
1438 | |||
1439 | ww_mutex_lock_slow(&o3, &t); | ||
1440 | } | ||
1441 | |||
1442 | static void ww_test_edeadlk_acquire_more_edeadlk(void) | ||
1443 | { | ||
1444 | int ret; | ||
1445 | |||
1446 | mutex_lock(&o2.base); | ||
1447 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1448 | o2.ctx = &t2; | ||
1449 | |||
1450 | mutex_lock(&o3.base); | ||
1451 | mutex_release(&o3.base.dep_map, 1, _THIS_IP_); | ||
1452 | o3.ctx = &t2; | ||
1453 | |||
1454 | WWAI(&t); | ||
1455 | t2 = t; | ||
1456 | t2.stamp--; | ||
1457 | |||
1458 | ret = WWL(&o, &t); | ||
1459 | WARN_ON(ret); | ||
1460 | |||
1461 | ret = WWL(&o2, &t); | ||
1462 | WARN_ON(ret != -EDEADLK); | ||
1463 | |||
1464 | ret = WWL(&o3, &t); | ||
1465 | WARN_ON(ret != -EDEADLK); | ||
1466 | } | ||
1467 | |||
1468 | static void ww_test_edeadlk_acquire_more_edeadlk_slow(void) | ||
1469 | { | ||
1470 | int ret; | ||
1471 | |||
1472 | mutex_lock(&o2.base); | ||
1473 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1474 | o2.ctx = &t2; | ||
1475 | |||
1476 | mutex_lock(&o3.base); | ||
1477 | mutex_release(&o3.base.dep_map, 1, _THIS_IP_); | ||
1478 | o3.ctx = &t2; | ||
1479 | |||
1480 | WWAI(&t); | ||
1481 | t2 = t; | ||
1482 | t2.stamp--; | ||
1483 | |||
1484 | ret = WWL(&o, &t); | ||
1485 | WARN_ON(ret); | ||
1486 | |||
1487 | ret = WWL(&o2, &t); | ||
1488 | WARN_ON(ret != -EDEADLK); | ||
1489 | |||
1490 | ww_mutex_lock_slow(&o3, &t); | ||
1491 | } | ||
1492 | |||
1493 | static void ww_test_edeadlk_acquire_wrong(void) | ||
1494 | { | ||
1495 | int ret; | ||
1496 | |||
1497 | mutex_lock(&o2.base); | ||
1498 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1499 | o2.ctx = &t2; | ||
1500 | |||
1501 | WWAI(&t); | ||
1502 | t2 = t; | ||
1503 | t2.stamp--; | ||
1504 | |||
1505 | ret = WWL(&o, &t); | ||
1506 | WARN_ON(ret); | ||
1507 | |||
1508 | ret = WWL(&o2, &t); | ||
1509 | WARN_ON(ret != -EDEADLK); | ||
1510 | if (!ret) | ||
1511 | WWU(&o2); | ||
1512 | |||
1513 | WWU(&o); | ||
1514 | |||
1515 | ret = WWL(&o3, &t); | ||
1516 | } | ||
1517 | |||
1518 | static void ww_test_edeadlk_acquire_wrong_slow(void) | ||
1519 | { | ||
1520 | int ret; | ||
1521 | |||
1522 | mutex_lock(&o2.base); | ||
1523 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1524 | o2.ctx = &t2; | ||
1525 | |||
1526 | WWAI(&t); | ||
1527 | t2 = t; | ||
1528 | t2.stamp--; | ||
1529 | |||
1530 | ret = WWL(&o, &t); | ||
1531 | WARN_ON(ret); | ||
1532 | |||
1533 | ret = WWL(&o2, &t); | ||
1534 | WARN_ON(ret != -EDEADLK); | ||
1535 | if (!ret) | ||
1536 | WWU(&o2); | ||
1537 | |||
1538 | WWU(&o); | ||
1539 | |||
1540 | ww_mutex_lock_slow(&o3, &t); | ||
1541 | } | ||
1542 | |||
1543 | static void ww_test_spin_nest_unlocked(void) | ||
1544 | { | ||
1545 | raw_spin_lock_nest_lock(&lock_A, &o.base); | ||
1546 | U(A); | ||
1547 | } | ||
1548 | |||
1549 | static void ww_test_unneeded_slow(void) | ||
1550 | { | ||
1551 | WWAI(&t); | ||
1552 | |||
1553 | ww_mutex_lock_slow(&o, &t); | ||
1554 | } | ||
1555 | |||
1556 | static void ww_test_context_block(void) | ||
1557 | { | ||
1558 | int ret; | ||
1559 | |||
1560 | WWAI(&t); | ||
1561 | |||
1562 | ret = WWL(&o, &t); | ||
1563 | WARN_ON(ret); | ||
1564 | WWL1(&o2); | ||
1565 | } | ||
1566 | |||
1567 | static void ww_test_context_try(void) | ||
1568 | { | ||
1569 | int ret; | ||
1570 | |||
1571 | WWAI(&t); | ||
1572 | |||
1573 | ret = WWL(&o, &t); | ||
1574 | WARN_ON(ret); | ||
1575 | |||
1576 | ret = WWT(&o2); | ||
1577 | WARN_ON(!ret); | ||
1578 | WWU(&o2); | ||
1579 | WWU(&o); | ||
1580 | } | ||
1581 | |||
1582 | static void ww_test_context_context(void) | ||
1583 | { | ||
1584 | int ret; | ||
1585 | |||
1586 | WWAI(&t); | ||
1587 | |||
1588 | ret = WWL(&o, &t); | ||
1589 | WARN_ON(ret); | ||
1590 | |||
1591 | ret = WWL(&o2, &t); | ||
1592 | WARN_ON(ret); | ||
1593 | |||
1594 | WWU(&o2); | ||
1595 | WWU(&o); | ||
1596 | } | ||
1597 | |||
1598 | static void ww_test_try_block(void) | ||
1599 | { | ||
1600 | bool ret; | ||
1601 | |||
1602 | ret = WWT(&o); | ||
1603 | WARN_ON(!ret); | ||
1604 | |||
1605 | WWL1(&o2); | ||
1606 | WWU(&o2); | ||
1607 | WWU(&o); | ||
1608 | } | ||
1609 | |||
1610 | static void ww_test_try_try(void) | ||
1611 | { | ||
1612 | bool ret; | ||
1613 | |||
1614 | ret = WWT(&o); | ||
1615 | WARN_ON(!ret); | ||
1616 | ret = WWT(&o2); | ||
1617 | WARN_ON(!ret); | ||
1618 | WWU(&o2); | ||
1619 | WWU(&o); | ||
1620 | } | ||
1621 | |||
1622 | static void ww_test_try_context(void) | ||
1623 | { | ||
1624 | int ret; | ||
1625 | |||
1626 | ret = WWT(&o); | ||
1627 | WARN_ON(!ret); | ||
1628 | |||
1629 | WWAI(&t); | ||
1630 | |||
1631 | ret = WWL(&o2, &t); | ||
1632 | WARN_ON(ret); | ||
1633 | } | ||
1634 | |||
1635 | static void ww_test_block_block(void) | ||
1636 | { | ||
1637 | WWL1(&o); | ||
1638 | WWL1(&o2); | ||
1639 | } | ||
1640 | |||
1641 | static void ww_test_block_try(void) | ||
1642 | { | ||
1643 | bool ret; | ||
1644 | |||
1645 | WWL1(&o); | ||
1646 | ret = WWT(&o2); | ||
1647 | WARN_ON(!ret); | ||
1648 | } | ||
1649 | |||
1650 | static void ww_test_block_context(void) | ||
1651 | { | ||
1652 | int ret; | ||
1653 | |||
1654 | WWL1(&o); | ||
1655 | WWAI(&t); | ||
1656 | |||
1657 | ret = WWL(&o2, &t); | ||
1658 | WARN_ON(ret); | ||
1659 | } | ||
1660 | |||
1661 | static void ww_test_spin_block(void) | ||
1662 | { | ||
1663 | L(A); | ||
1664 | U(A); | ||
1665 | |||
1666 | WWL1(&o); | ||
1667 | L(A); | ||
1668 | U(A); | ||
1669 | WWU(&o); | ||
1670 | |||
1671 | L(A); | ||
1672 | WWL1(&o); | ||
1673 | WWU(&o); | ||
1674 | U(A); | ||
1675 | } | ||
1676 | |||
1677 | static void ww_test_spin_try(void) | ||
1678 | { | ||
1679 | bool ret; | ||
1680 | |||
1681 | L(A); | ||
1682 | U(A); | ||
1683 | |||
1684 | ret = WWT(&o); | ||
1685 | WARN_ON(!ret); | ||
1686 | L(A); | ||
1687 | U(A); | ||
1688 | WWU(&o); | ||
1689 | |||
1690 | L(A); | ||
1691 | ret = WWT(&o); | ||
1692 | WARN_ON(!ret); | ||
1693 | WWU(&o); | ||
1694 | U(A); | ||
1695 | } | ||
1696 | |||
1697 | static void ww_test_spin_context(void) | ||
1698 | { | ||
1699 | int ret; | ||
1700 | |||
1701 | L(A); | ||
1702 | U(A); | ||
1703 | |||
1704 | WWAI(&t); | ||
1705 | |||
1706 | ret = WWL(&o, &t); | ||
1707 | WARN_ON(ret); | ||
1708 | L(A); | ||
1709 | U(A); | ||
1710 | WWU(&o); | ||
1711 | |||
1712 | L(A); | ||
1713 | ret = WWL(&o, &t); | ||
1714 | WARN_ON(ret); | ||
1715 | WWU(&o); | ||
1716 | U(A); | ||
1717 | } | ||
1718 | |||
1719 | static void ww_tests(void) | ||
1720 | { | ||
1721 | printk(" --------------------------------------------------------------------------\n"); | ||
1722 | printk(" | Wound/wait tests |\n"); | ||
1723 | printk(" ---------------------\n"); | ||
1724 | |||
1725 | print_testname("ww api failures"); | ||
1726 | dotest(ww_test_fail_acquire, SUCCESS, LOCKTYPE_WW); | ||
1727 | dotest(ww_test_normal, SUCCESS, LOCKTYPE_WW); | ||
1728 | dotest(ww_test_unneeded_slow, FAILURE, LOCKTYPE_WW); | ||
1729 | printk("\n"); | ||
1730 | |||
1731 | print_testname("ww contexts mixing"); | ||
1732 | dotest(ww_test_two_contexts, FAILURE, LOCKTYPE_WW); | ||
1733 | dotest(ww_test_diff_class, FAILURE, LOCKTYPE_WW); | ||
1734 | printk("\n"); | ||
1735 | |||
1736 | print_testname("finishing ww context"); | ||
1737 | dotest(ww_test_context_done_twice, FAILURE, LOCKTYPE_WW); | ||
1738 | dotest(ww_test_context_unlock_twice, FAILURE, LOCKTYPE_WW); | ||
1739 | dotest(ww_test_context_fini_early, FAILURE, LOCKTYPE_WW); | ||
1740 | dotest(ww_test_context_lock_after_done, FAILURE, LOCKTYPE_WW); | ||
1741 | printk("\n"); | ||
1742 | |||
1743 | print_testname("locking mismatches"); | ||
1744 | dotest(ww_test_object_unlock_twice, FAILURE, LOCKTYPE_WW); | ||
1745 | dotest(ww_test_object_lock_unbalanced, FAILURE, LOCKTYPE_WW); | ||
1746 | dotest(ww_test_object_lock_stale_context, FAILURE, LOCKTYPE_WW); | ||
1747 | printk("\n"); | ||
1748 | |||
1749 | print_testname("EDEADLK handling"); | ||
1750 | dotest(ww_test_edeadlk_normal, SUCCESS, LOCKTYPE_WW); | ||
1751 | dotest(ww_test_edeadlk_normal_slow, SUCCESS, LOCKTYPE_WW); | ||
1752 | dotest(ww_test_edeadlk_no_unlock, FAILURE, LOCKTYPE_WW); | ||
1753 | dotest(ww_test_edeadlk_no_unlock_slow, FAILURE, LOCKTYPE_WW); | ||
1754 | dotest(ww_test_edeadlk_acquire_more, FAILURE, LOCKTYPE_WW); | ||
1755 | dotest(ww_test_edeadlk_acquire_more_slow, FAILURE, LOCKTYPE_WW); | ||
1756 | dotest(ww_test_edeadlk_acquire_more_edeadlk, FAILURE, LOCKTYPE_WW); | ||
1757 | dotest(ww_test_edeadlk_acquire_more_edeadlk_slow, FAILURE, LOCKTYPE_WW); | ||
1758 | dotest(ww_test_edeadlk_acquire_wrong, FAILURE, LOCKTYPE_WW); | ||
1759 | dotest(ww_test_edeadlk_acquire_wrong_slow, FAILURE, LOCKTYPE_WW); | ||
1760 | printk("\n"); | ||
1761 | |||
1762 | print_testname("spinlock nest unlocked"); | ||
1763 | dotest(ww_test_spin_nest_unlocked, FAILURE, LOCKTYPE_WW); | ||
1764 | printk("\n"); | ||
1765 | |||
1766 | printk(" -----------------------------------------------------\n"); | ||
1767 | printk(" |block | try |context|\n"); | ||
1768 | printk(" -----------------------------------------------------\n"); | ||
1769 | |||
1770 | print_testname("context"); | ||
1771 | dotest(ww_test_context_block, FAILURE, LOCKTYPE_WW); | ||
1772 | dotest(ww_test_context_try, SUCCESS, LOCKTYPE_WW); | ||
1773 | dotest(ww_test_context_context, SUCCESS, LOCKTYPE_WW); | ||
1774 | printk("\n"); | ||
1775 | |||
1776 | print_testname("try"); | ||
1777 | dotest(ww_test_try_block, FAILURE, LOCKTYPE_WW); | ||
1778 | dotest(ww_test_try_try, SUCCESS, LOCKTYPE_WW); | ||
1779 | dotest(ww_test_try_context, FAILURE, LOCKTYPE_WW); | ||
1780 | printk("\n"); | ||
1781 | |||
1782 | print_testname("block"); | ||
1783 | dotest(ww_test_block_block, FAILURE, LOCKTYPE_WW); | ||
1784 | dotest(ww_test_block_try, SUCCESS, LOCKTYPE_WW); | ||
1785 | dotest(ww_test_block_context, FAILURE, LOCKTYPE_WW); | ||
1786 | printk("\n"); | ||
1787 | |||
1788 | print_testname("spinlock"); | ||
1789 | dotest(ww_test_spin_block, FAILURE, LOCKTYPE_WW); | ||
1790 | dotest(ww_test_spin_try, SUCCESS, LOCKTYPE_WW); | ||
1791 | dotest(ww_test_spin_context, FAILURE, LOCKTYPE_WW); | ||
1792 | printk("\n"); | ||
1793 | } | ||
1111 | 1794 | ||
1112 | void locking_selftest(void) | 1795 | void locking_selftest(void) |
1113 | { | 1796 | { |
@@ -1188,6 +1871,8 @@ void locking_selftest(void) | |||
1188 | DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion); | 1871 | DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion); |
1189 | // DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2); | 1872 | // DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2); |
1190 | 1873 | ||
1874 | ww_tests(); | ||
1875 | |||
1191 | if (unexpected_testcase_failures) { | 1876 | if (unexpected_testcase_failures) { |
1192 | printk("-----------------------------------------------------------------\n"); | 1877 | printk("-----------------------------------------------------------------\n"); |
1193 | debug_locks = 0; | 1878 | debug_locks = 0; |