diff options
author | Maarten Lankhorst <maarten.lankhorst@canonical.com> | 2013-06-20 07:31:42 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-06-26 06:10:58 -0400 |
commit | f3cf139efa4bc0fe4f032af6ca3e49e38a5d9ae5 (patch) | |
tree | 2c21ea868c522edd2642dac07718a94cf816b6c1 /lib | |
parent | 2fe3d4b149ccebbb384062fbbe6634439f2bf120 (diff) |
mutex: Add more w/w tests to test EDEADLK path handling
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: dri-devel@lists.freedesktop.org
Cc: linaro-mm-sig@lists.linaro.org
Cc: rostedt@goodmis.org
Cc: daniel@ffwll.ch
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20130620113141.4001.54331.stgit@patser
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/locking-selftest.c | 264 |
1 files changed, 261 insertions, 3 deletions
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index 37faefdbb678..d554f3fed846 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c | |||
@@ -47,7 +47,7 @@ __setup("debug_locks_verbose=", setup_debug_locks_verbose); | |||
47 | #define LOCKTYPE_WW 0x10 | 47 | #define LOCKTYPE_WW 0x10 |
48 | 48 | ||
49 | static struct ww_acquire_ctx t, t2; | 49 | static struct ww_acquire_ctx t, t2; |
50 | static struct ww_mutex o, o2; | 50 | static struct ww_mutex o, o2, o3; |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * Normal standalone locks, for the circular and irq-context | 53 | * Normal standalone locks, for the circular and irq-context |
@@ -947,12 +947,12 @@ static void reset_locks(void) | |||
947 | 947 | ||
948 | I1(A); I1(B); I1(C); I1(D); | 948 | I1(A); I1(B); I1(C); I1(D); |
949 | I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2); | 949 | I1(X1); I1(X2); I1(Y1); I1(Y2); I1(Z1); I1(Z2); |
950 | I_WW(t); I_WW(t2); I_WW(o.base); I_WW(o2.base); | 950 | I_WW(t); I_WW(t2); I_WW(o.base); I_WW(o2.base); I_WW(o3.base); |
951 | lockdep_reset(); | 951 | lockdep_reset(); |
952 | I2(A); I2(B); I2(C); I2(D); | 952 | I2(A); I2(B); I2(C); I2(D); |
953 | init_shared_classes(); | 953 | init_shared_classes(); |
954 | 954 | ||
955 | ww_mutex_init(&o, &ww_lockdep); ww_mutex_init(&o2, &ww_lockdep); | 955 | ww_mutex_init(&o, &ww_lockdep); ww_mutex_init(&o2, &ww_lockdep); ww_mutex_init(&o3, &ww_lockdep); |
956 | memset(&t, 0, sizeof(t)); memset(&t2, 0, sizeof(t2)); | 956 | memset(&t, 0, sizeof(t)); memset(&t2, 0, sizeof(t2)); |
957 | memset(&ww_lockdep.acquire_key, 0, sizeof(ww_lockdep.acquire_key)); | 957 | memset(&ww_lockdep.acquire_key, 0, sizeof(ww_lockdep.acquire_key)); |
958 | memset(&ww_lockdep.mutex_key, 0, sizeof(ww_lockdep.mutex_key)); | 958 | memset(&ww_lockdep.mutex_key, 0, sizeof(ww_lockdep.mutex_key)); |
@@ -1292,6 +1292,251 @@ static void ww_test_object_lock_stale_context(void) | |||
1292 | WWL(&o, &t); | 1292 | WWL(&o, &t); |
1293 | } | 1293 | } |
1294 | 1294 | ||
1295 | static void ww_test_edeadlk_normal(void) | ||
1296 | { | ||
1297 | int ret; | ||
1298 | |||
1299 | mutex_lock(&o2.base); | ||
1300 | o2.ctx = &t2; | ||
1301 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1302 | |||
1303 | WWAI(&t); | ||
1304 | t2 = t; | ||
1305 | t2.stamp--; | ||
1306 | |||
1307 | ret = WWL(&o, &t); | ||
1308 | WARN_ON(ret); | ||
1309 | |||
1310 | ret = WWL(&o2, &t); | ||
1311 | WARN_ON(ret != -EDEADLK); | ||
1312 | |||
1313 | o2.ctx = NULL; | ||
1314 | mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); | ||
1315 | mutex_unlock(&o2.base); | ||
1316 | WWU(&o); | ||
1317 | |||
1318 | WWL(&o2, &t); | ||
1319 | } | ||
1320 | |||
1321 | static void ww_test_edeadlk_normal_slow(void) | ||
1322 | { | ||
1323 | int ret; | ||
1324 | |||
1325 | mutex_lock(&o2.base); | ||
1326 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1327 | o2.ctx = &t2; | ||
1328 | |||
1329 | WWAI(&t); | ||
1330 | t2 = t; | ||
1331 | t2.stamp--; | ||
1332 | |||
1333 | ret = WWL(&o, &t); | ||
1334 | WARN_ON(ret); | ||
1335 | |||
1336 | ret = WWL(&o2, &t); | ||
1337 | WARN_ON(ret != -EDEADLK); | ||
1338 | |||
1339 | o2.ctx = NULL; | ||
1340 | mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); | ||
1341 | mutex_unlock(&o2.base); | ||
1342 | WWU(&o); | ||
1343 | |||
1344 | ww_mutex_lock_slow(&o2, &t); | ||
1345 | } | ||
1346 | |||
1347 | static void ww_test_edeadlk_no_unlock(void) | ||
1348 | { | ||
1349 | int ret; | ||
1350 | |||
1351 | mutex_lock(&o2.base); | ||
1352 | o2.ctx = &t2; | ||
1353 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1354 | |||
1355 | WWAI(&t); | ||
1356 | t2 = t; | ||
1357 | t2.stamp--; | ||
1358 | |||
1359 | ret = WWL(&o, &t); | ||
1360 | WARN_ON(ret); | ||
1361 | |||
1362 | ret = WWL(&o2, &t); | ||
1363 | WARN_ON(ret != -EDEADLK); | ||
1364 | |||
1365 | o2.ctx = NULL; | ||
1366 | mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); | ||
1367 | mutex_unlock(&o2.base); | ||
1368 | |||
1369 | WWL(&o2, &t); | ||
1370 | } | ||
1371 | |||
1372 | static void ww_test_edeadlk_no_unlock_slow(void) | ||
1373 | { | ||
1374 | int ret; | ||
1375 | |||
1376 | mutex_lock(&o2.base); | ||
1377 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1378 | o2.ctx = &t2; | ||
1379 | |||
1380 | WWAI(&t); | ||
1381 | t2 = t; | ||
1382 | t2.stamp--; | ||
1383 | |||
1384 | ret = WWL(&o, &t); | ||
1385 | WARN_ON(ret); | ||
1386 | |||
1387 | ret = WWL(&o2, &t); | ||
1388 | WARN_ON(ret != -EDEADLK); | ||
1389 | |||
1390 | o2.ctx = NULL; | ||
1391 | mutex_acquire(&o2.base.dep_map, 0, 1, _THIS_IP_); | ||
1392 | mutex_unlock(&o2.base); | ||
1393 | |||
1394 | ww_mutex_lock_slow(&o2, &t); | ||
1395 | } | ||
1396 | |||
1397 | static void ww_test_edeadlk_acquire_more(void) | ||
1398 | { | ||
1399 | int ret; | ||
1400 | |||
1401 | mutex_lock(&o2.base); | ||
1402 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1403 | o2.ctx = &t2; | ||
1404 | |||
1405 | WWAI(&t); | ||
1406 | t2 = t; | ||
1407 | t2.stamp--; | ||
1408 | |||
1409 | ret = WWL(&o, &t); | ||
1410 | WARN_ON(ret); | ||
1411 | |||
1412 | ret = WWL(&o2, &t); | ||
1413 | WARN_ON(ret != -EDEADLK); | ||
1414 | |||
1415 | ret = WWL(&o3, &t); | ||
1416 | } | ||
1417 | |||
1418 | static void ww_test_edeadlk_acquire_more_slow(void) | ||
1419 | { | ||
1420 | int ret; | ||
1421 | |||
1422 | mutex_lock(&o2.base); | ||
1423 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1424 | o2.ctx = &t2; | ||
1425 | |||
1426 | WWAI(&t); | ||
1427 | t2 = t; | ||
1428 | t2.stamp--; | ||
1429 | |||
1430 | ret = WWL(&o, &t); | ||
1431 | WARN_ON(ret); | ||
1432 | |||
1433 | ret = WWL(&o2, &t); | ||
1434 | WARN_ON(ret != -EDEADLK); | ||
1435 | |||
1436 | ww_mutex_lock_slow(&o3, &t); | ||
1437 | } | ||
1438 | |||
1439 | static void ww_test_edeadlk_acquire_more_edeadlk(void) | ||
1440 | { | ||
1441 | int ret; | ||
1442 | |||
1443 | mutex_lock(&o2.base); | ||
1444 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1445 | o2.ctx = &t2; | ||
1446 | |||
1447 | mutex_lock(&o3.base); | ||
1448 | mutex_release(&o3.base.dep_map, 1, _THIS_IP_); | ||
1449 | o3.ctx = &t2; | ||
1450 | |||
1451 | WWAI(&t); | ||
1452 | t2 = t; | ||
1453 | t2.stamp--; | ||
1454 | |||
1455 | ret = WWL(&o, &t); | ||
1456 | WARN_ON(ret); | ||
1457 | |||
1458 | ret = WWL(&o2, &t); | ||
1459 | WARN_ON(ret != -EDEADLK); | ||
1460 | |||
1461 | ret = WWL(&o3, &t); | ||
1462 | WARN_ON(ret != -EDEADLK); | ||
1463 | } | ||
1464 | |||
1465 | static void ww_test_edeadlk_acquire_more_edeadlk_slow(void) | ||
1466 | { | ||
1467 | int ret; | ||
1468 | |||
1469 | mutex_lock(&o2.base); | ||
1470 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1471 | o2.ctx = &t2; | ||
1472 | |||
1473 | mutex_lock(&o3.base); | ||
1474 | mutex_release(&o3.base.dep_map, 1, _THIS_IP_); | ||
1475 | o3.ctx = &t2; | ||
1476 | |||
1477 | WWAI(&t); | ||
1478 | t2 = t; | ||
1479 | t2.stamp--; | ||
1480 | |||
1481 | ret = WWL(&o, &t); | ||
1482 | WARN_ON(ret); | ||
1483 | |||
1484 | ret = WWL(&o2, &t); | ||
1485 | WARN_ON(ret != -EDEADLK); | ||
1486 | |||
1487 | ww_mutex_lock_slow(&o3, &t); | ||
1488 | } | ||
1489 | |||
1490 | static void ww_test_edeadlk_acquire_wrong(void) | ||
1491 | { | ||
1492 | int ret; | ||
1493 | |||
1494 | mutex_lock(&o2.base); | ||
1495 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1496 | o2.ctx = &t2; | ||
1497 | |||
1498 | WWAI(&t); | ||
1499 | t2 = t; | ||
1500 | t2.stamp--; | ||
1501 | |||
1502 | ret = WWL(&o, &t); | ||
1503 | WARN_ON(ret); | ||
1504 | |||
1505 | ret = WWL(&o2, &t); | ||
1506 | WARN_ON(ret != -EDEADLK); | ||
1507 | if (!ret) | ||
1508 | WWU(&o2); | ||
1509 | |||
1510 | WWU(&o); | ||
1511 | |||
1512 | ret = WWL(&o3, &t); | ||
1513 | } | ||
1514 | |||
1515 | static void ww_test_edeadlk_acquire_wrong_slow(void) | ||
1516 | { | ||
1517 | int ret; | ||
1518 | |||
1519 | mutex_lock(&o2.base); | ||
1520 | mutex_release(&o2.base.dep_map, 1, _THIS_IP_); | ||
1521 | o2.ctx = &t2; | ||
1522 | |||
1523 | WWAI(&t); | ||
1524 | t2 = t; | ||
1525 | t2.stamp--; | ||
1526 | |||
1527 | ret = WWL(&o, &t); | ||
1528 | WARN_ON(ret); | ||
1529 | |||
1530 | ret = WWL(&o2, &t); | ||
1531 | WARN_ON(ret != -EDEADLK); | ||
1532 | if (!ret) | ||
1533 | WWU(&o2); | ||
1534 | |||
1535 | WWU(&o); | ||
1536 | |||
1537 | ww_mutex_lock_slow(&o3, &t); | ||
1538 | } | ||
1539 | |||
1295 | static void ww_test_spin_nest_unlocked(void) | 1540 | static void ww_test_spin_nest_unlocked(void) |
1296 | { | 1541 | { |
1297 | raw_spin_lock_nest_lock(&lock_A, &o.base); | 1542 | raw_spin_lock_nest_lock(&lock_A, &o.base); |
@@ -1498,6 +1743,19 @@ static void ww_tests(void) | |||
1498 | dotest(ww_test_object_lock_stale_context, FAILURE, LOCKTYPE_WW); | 1743 | dotest(ww_test_object_lock_stale_context, FAILURE, LOCKTYPE_WW); |
1499 | printk("\n"); | 1744 | printk("\n"); |
1500 | 1745 | ||
1746 | print_testname("EDEADLK handling"); | ||
1747 | dotest(ww_test_edeadlk_normal, SUCCESS, LOCKTYPE_WW); | ||
1748 | dotest(ww_test_edeadlk_normal_slow, SUCCESS, LOCKTYPE_WW); | ||
1749 | dotest(ww_test_edeadlk_no_unlock, FAILURE, LOCKTYPE_WW); | ||
1750 | dotest(ww_test_edeadlk_no_unlock_slow, FAILURE, LOCKTYPE_WW); | ||
1751 | dotest(ww_test_edeadlk_acquire_more, FAILURE, LOCKTYPE_WW); | ||
1752 | dotest(ww_test_edeadlk_acquire_more_slow, FAILURE, LOCKTYPE_WW); | ||
1753 | dotest(ww_test_edeadlk_acquire_more_edeadlk, FAILURE, LOCKTYPE_WW); | ||
1754 | dotest(ww_test_edeadlk_acquire_more_edeadlk_slow, FAILURE, LOCKTYPE_WW); | ||
1755 | dotest(ww_test_edeadlk_acquire_wrong, FAILURE, LOCKTYPE_WW); | ||
1756 | dotest(ww_test_edeadlk_acquire_wrong_slow, FAILURE, LOCKTYPE_WW); | ||
1757 | printk("\n"); | ||
1758 | |||
1501 | print_testname("spinlock nest unlocked"); | 1759 | print_testname("spinlock nest unlocked"); |
1502 | dotest(ww_test_spin_nest_unlocked, FAILURE, LOCKTYPE_WW); | 1760 | dotest(ww_test_spin_nest_unlocked, FAILURE, LOCKTYPE_WW); |
1503 | printk("\n"); | 1761 | printk("\n"); |