aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>2013-06-20 07:31:42 -0400
committerIngo Molnar <mingo@kernel.org>2013-06-26 06:10:58 -0400
commitf3cf139efa4bc0fe4f032af6ca3e49e38a5d9ae5 (patch)
tree2c21ea868c522edd2642dac07718a94cf816b6c1 /lib
parent2fe3d4b149ccebbb384062fbbe6634439f2bf120 (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.c264
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
49static struct ww_acquire_ctx t, t2; 49static struct ww_acquire_ctx t, t2;
50static struct ww_mutex o, o2; 50static 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
1295static 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
1321static 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
1347static 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
1372static 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
1397static 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
1418static 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
1439static 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
1465static 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
1490static 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
1515static 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
1295static void ww_test_spin_nest_unlocked(void) 1540static 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");