aboutsummaryrefslogtreecommitdiffstats
path: root/lib/locking-selftest.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/locking-selftest.c')
-rw-r--r--lib/locking-selftest.c721
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 */
27static unsigned int debug_locks_verbose; 28static unsigned int debug_locks_verbose;
28 29
30static DEFINE_WW_CLASS(ww_lockdep);
31
29static int __init setup_debug_locks_verbose(char *str) 32static 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
50static struct ww_acquire_ctx t, t2;
51static 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)
920static void reset_locks(void) 943static 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;
938static void dotest(void (*testcase_fn)(void), int expected, int lockclass_mask) 970static 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
1134static 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
1168static 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
1229static void ww_test_two_contexts(void)
1230{
1231 WWAI(&t);
1232 WWAI(&t2);
1233}
1234
1235static 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
1244static void ww_test_context_done_twice(void)
1245{
1246 WWAI(&t);
1247 WWAD(&t);
1248 WWAD(&t);
1249 WWAF(&t);
1250}
1251
1252static void ww_test_context_unlock_twice(void)
1253{
1254 WWAI(&t);
1255 WWAD(&t);
1256 WWAF(&t);
1257 WWAF(&t);
1258}
1259
1260static void ww_test_context_fini_early(void)
1261{
1262 WWAI(&t);
1263 WWL(&o, &t);
1264 WWAD(&t);
1265 WWAF(&t);
1266}
1267
1268static void ww_test_context_lock_after_done(void)
1269{
1270 WWAI(&t);
1271 WWAD(&t);
1272 WWL(&o, &t);
1273}
1274
1275static void ww_test_object_unlock_twice(void)
1276{
1277 WWL1(&o);
1278 WWU(&o);
1279 WWU(&o);
1280}
1281
1282static 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
1291static void ww_test_object_lock_stale_context(void)
1292{
1293 WWAI(&t);
1294 o.ctx = &t2;
1295 WWL(&o, &t);
1296}
1297
1298static 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
1324static 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
1350static 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
1375static 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
1400static 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
1421static 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
1442static 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
1468static 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
1493static 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
1518static 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
1543static void ww_test_spin_nest_unlocked(void)
1544{
1545 raw_spin_lock_nest_lock(&lock_A, &o.base);
1546 U(A);
1547}
1548
1549static void ww_test_unneeded_slow(void)
1550{
1551 WWAI(&t);
1552
1553 ww_mutex_lock_slow(&o, &t);
1554}
1555
1556static 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
1567static 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
1582static 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
1598static 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
1610static 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
1622static 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
1635static void ww_test_block_block(void)
1636{
1637 WWL1(&o);
1638 WWL1(&o2);
1639}
1640
1641static void ww_test_block_try(void)
1642{
1643 bool ret;
1644
1645 WWL1(&o);
1646 ret = WWT(&o2);
1647 WARN_ON(!ret);
1648}
1649
1650static 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
1661static 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
1677static 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
1697static 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
1719static 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
1112void locking_selftest(void) 1795void 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;