aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-12-01 06:47:05 -0500
committerIngo Molnar <mingo@kernel.org>2017-01-14 05:37:14 -0500
commit0186a6cbdc6287fde65858e5d9c714dc167b8ace (patch)
tree7f9d7eac00704e67959e5786c7d2b94cecf739a6
parentaf2e859edd477fa1ea3d1d106f41a595cff3d162 (diff)
locking/ww_mutex: Add ww_mutex to locktorture test
Although ww_mutexes degenerate into mutexes, it would be useful to torture the deadlock handling between multiple ww_mutexes in addition to torturing the regular mutexes. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Maarten Lankhorst <dev@mblankhorst.nl> Cc: Nicolai Hähnle <nhaehnle@gmail.com> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/20161201114711.28697-3-chris@chris-wilson.co.uk Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--kernel/locking/locktorture.c73
-rw-r--r--tools/testing/selftests/rcutorture/configs/lock/CFLIST1
-rw-r--r--tools/testing/selftests/rcutorture/configs/lock/LOCK076
-rw-r--r--tools/testing/selftests/rcutorture/configs/lock/LOCK07.boot1
4 files changed, 81 insertions, 0 deletions
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
index f8c5af52a131..9bffedd82884 100644
--- a/kernel/locking/locktorture.c
+++ b/kernel/locking/locktorture.c
@@ -372,6 +372,78 @@ static struct lock_torture_ops mutex_lock_ops = {
372 .name = "mutex_lock" 372 .name = "mutex_lock"
373}; 373};
374 374
375#include <linux/ww_mutex.h>
376static DEFINE_WW_CLASS(torture_ww_class);
377static DEFINE_WW_MUTEX(torture_ww_mutex_0, &torture_ww_class);
378static DEFINE_WW_MUTEX(torture_ww_mutex_1, &torture_ww_class);
379static DEFINE_WW_MUTEX(torture_ww_mutex_2, &torture_ww_class);
380
381static int torture_ww_mutex_lock(void)
382__acquires(torture_ww_mutex_0)
383__acquires(torture_ww_mutex_1)
384__acquires(torture_ww_mutex_2)
385{
386 LIST_HEAD(list);
387 struct reorder_lock {
388 struct list_head link;
389 struct ww_mutex *lock;
390 } locks[3], *ll, *ln;
391 struct ww_acquire_ctx ctx;
392
393 locks[0].lock = &torture_ww_mutex_0;
394 list_add(&locks[0].link, &list);
395
396 locks[1].lock = &torture_ww_mutex_1;
397 list_add(&locks[1].link, &list);
398
399 locks[2].lock = &torture_ww_mutex_2;
400 list_add(&locks[2].link, &list);
401
402 ww_acquire_init(&ctx, &torture_ww_class);
403
404 list_for_each_entry(ll, &list, link) {
405 int err;
406
407 err = ww_mutex_lock(ll->lock, &ctx);
408 if (!err)
409 continue;
410
411 ln = ll;
412 list_for_each_entry_continue_reverse(ln, &list, link)
413 ww_mutex_unlock(ln->lock);
414
415 if (err != -EDEADLK)
416 return err;
417
418 ww_mutex_lock_slow(ll->lock, &ctx);
419 list_move(&ll->link, &list);
420 }
421
422 ww_acquire_fini(&ctx);
423 return 0;
424}
425
426static void torture_ww_mutex_unlock(void)
427__releases(torture_ww_mutex_0)
428__releases(torture_ww_mutex_1)
429__releases(torture_ww_mutex_2)
430{
431 ww_mutex_unlock(&torture_ww_mutex_0);
432 ww_mutex_unlock(&torture_ww_mutex_1);
433 ww_mutex_unlock(&torture_ww_mutex_2);
434}
435
436static struct lock_torture_ops ww_mutex_lock_ops = {
437 .writelock = torture_ww_mutex_lock,
438 .write_delay = torture_mutex_delay,
439 .task_boost = torture_boost_dummy,
440 .writeunlock = torture_ww_mutex_unlock,
441 .readlock = NULL,
442 .read_delay = NULL,
443 .readunlock = NULL,
444 .name = "ww_mutex_lock"
445};
446
375#ifdef CONFIG_RT_MUTEXES 447#ifdef CONFIG_RT_MUTEXES
376static DEFINE_RT_MUTEX(torture_rtmutex); 448static DEFINE_RT_MUTEX(torture_rtmutex);
377 449
@@ -793,6 +865,7 @@ static int __init lock_torture_init(void)
793 &spin_lock_ops, &spin_lock_irq_ops, 865 &spin_lock_ops, &spin_lock_irq_ops,
794 &rw_lock_ops, &rw_lock_irq_ops, 866 &rw_lock_ops, &rw_lock_irq_ops,
795 &mutex_lock_ops, 867 &mutex_lock_ops,
868 &ww_mutex_lock_ops,
796#ifdef CONFIG_RT_MUTEXES 869#ifdef CONFIG_RT_MUTEXES
797 &rtmutex_lock_ops, 870 &rtmutex_lock_ops,
798#endif 871#endif
diff --git a/tools/testing/selftests/rcutorture/configs/lock/CFLIST b/tools/testing/selftests/rcutorture/configs/lock/CFLIST
index b9611c523723..41bae5824339 100644
--- a/tools/testing/selftests/rcutorture/configs/lock/CFLIST
+++ b/tools/testing/selftests/rcutorture/configs/lock/CFLIST
@@ -4,3 +4,4 @@ LOCK03
4LOCK04 4LOCK04
5LOCK05 5LOCK05
6LOCK06 6LOCK06
7LOCK07
diff --git a/tools/testing/selftests/rcutorture/configs/lock/LOCK07 b/tools/testing/selftests/rcutorture/configs/lock/LOCK07
new file mode 100644
index 000000000000..1d1da1477fc3
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/configs/lock/LOCK07
@@ -0,0 +1,6 @@
1CONFIG_SMP=y
2CONFIG_NR_CPUS=4
3CONFIG_HOTPLUG_CPU=y
4CONFIG_PREEMPT_NONE=n
5CONFIG_PREEMPT_VOLUNTARY=n
6CONFIG_PREEMPT=y
diff --git a/tools/testing/selftests/rcutorture/configs/lock/LOCK07.boot b/tools/testing/selftests/rcutorture/configs/lock/LOCK07.boot
new file mode 100644
index 000000000000..97dadd1a9e45
--- /dev/null
+++ b/tools/testing/selftests/rcutorture/configs/lock/LOCK07.boot
@@ -0,0 +1 @@
locktorture.torture_type=ww_mutex_lock