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"); |
