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>
This commit is contained in:
Родитель
af2e859edd
Коммит
0186a6cbdc
|
@ -372,6 +372,78 @@ static struct lock_torture_ops mutex_lock_ops = {
|
||||||
.name = "mutex_lock"
|
.name = "mutex_lock"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include <linux/ww_mutex.h>
|
||||||
|
static DEFINE_WW_CLASS(torture_ww_class);
|
||||||
|
static DEFINE_WW_MUTEX(torture_ww_mutex_0, &torture_ww_class);
|
||||||
|
static DEFINE_WW_MUTEX(torture_ww_mutex_1, &torture_ww_class);
|
||||||
|
static DEFINE_WW_MUTEX(torture_ww_mutex_2, &torture_ww_class);
|
||||||
|
|
||||||
|
static int torture_ww_mutex_lock(void)
|
||||||
|
__acquires(torture_ww_mutex_0)
|
||||||
|
__acquires(torture_ww_mutex_1)
|
||||||
|
__acquires(torture_ww_mutex_2)
|
||||||
|
{
|
||||||
|
LIST_HEAD(list);
|
||||||
|
struct reorder_lock {
|
||||||
|
struct list_head link;
|
||||||
|
struct ww_mutex *lock;
|
||||||
|
} locks[3], *ll, *ln;
|
||||||
|
struct ww_acquire_ctx ctx;
|
||||||
|
|
||||||
|
locks[0].lock = &torture_ww_mutex_0;
|
||||||
|
list_add(&locks[0].link, &list);
|
||||||
|
|
||||||
|
locks[1].lock = &torture_ww_mutex_1;
|
||||||
|
list_add(&locks[1].link, &list);
|
||||||
|
|
||||||
|
locks[2].lock = &torture_ww_mutex_2;
|
||||||
|
list_add(&locks[2].link, &list);
|
||||||
|
|
||||||
|
ww_acquire_init(&ctx, &torture_ww_class);
|
||||||
|
|
||||||
|
list_for_each_entry(ll, &list, link) {
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = ww_mutex_lock(ll->lock, &ctx);
|
||||||
|
if (!err)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ln = ll;
|
||||||
|
list_for_each_entry_continue_reverse(ln, &list, link)
|
||||||
|
ww_mutex_unlock(ln->lock);
|
||||||
|
|
||||||
|
if (err != -EDEADLK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
ww_mutex_lock_slow(ll->lock, &ctx);
|
||||||
|
list_move(&ll->link, &list);
|
||||||
|
}
|
||||||
|
|
||||||
|
ww_acquire_fini(&ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_ww_mutex_unlock(void)
|
||||||
|
__releases(torture_ww_mutex_0)
|
||||||
|
__releases(torture_ww_mutex_1)
|
||||||
|
__releases(torture_ww_mutex_2)
|
||||||
|
{
|
||||||
|
ww_mutex_unlock(&torture_ww_mutex_0);
|
||||||
|
ww_mutex_unlock(&torture_ww_mutex_1);
|
||||||
|
ww_mutex_unlock(&torture_ww_mutex_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct lock_torture_ops ww_mutex_lock_ops = {
|
||||||
|
.writelock = torture_ww_mutex_lock,
|
||||||
|
.write_delay = torture_mutex_delay,
|
||||||
|
.task_boost = torture_boost_dummy,
|
||||||
|
.writeunlock = torture_ww_mutex_unlock,
|
||||||
|
.readlock = NULL,
|
||||||
|
.read_delay = NULL,
|
||||||
|
.readunlock = NULL,
|
||||||
|
.name = "ww_mutex_lock"
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_RT_MUTEXES
|
#ifdef CONFIG_RT_MUTEXES
|
||||||
static DEFINE_RT_MUTEX(torture_rtmutex);
|
static DEFINE_RT_MUTEX(torture_rtmutex);
|
||||||
|
|
||||||
|
@ -793,6 +865,7 @@ static int __init lock_torture_init(void)
|
||||||
&spin_lock_ops, &spin_lock_irq_ops,
|
&spin_lock_ops, &spin_lock_irq_ops,
|
||||||
&rw_lock_ops, &rw_lock_irq_ops,
|
&rw_lock_ops, &rw_lock_irq_ops,
|
||||||
&mutex_lock_ops,
|
&mutex_lock_ops,
|
||||||
|
&ww_mutex_lock_ops,
|
||||||
#ifdef CONFIG_RT_MUTEXES
|
#ifdef CONFIG_RT_MUTEXES
|
||||||
&rtmutex_lock_ops,
|
&rtmutex_lock_ops,
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,3 +4,4 @@ LOCK03
|
||||||
LOCK04
|
LOCK04
|
||||||
LOCK05
|
LOCK05
|
||||||
LOCK06
|
LOCK06
|
||||||
|
LOCK07
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
CONFIG_SMP=y
|
||||||
|
CONFIG_NR_CPUS=4
|
||||||
|
CONFIG_HOTPLUG_CPU=y
|
||||||
|
CONFIG_PREEMPT_NONE=n
|
||||||
|
CONFIG_PREEMPT_VOLUNTARY=n
|
||||||
|
CONFIG_PREEMPT=y
|
|
@ -0,0 +1 @@
|
||||||
|
locktorture.torture_type=ww_mutex_lock
|
Загрузка…
Ссылка в новой задаче