2019-05-19 15:51:39 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2016-12-01 11:47:06 +00:00
/*
* Module - based API test facility for ww_mutexes
*/
# include <linux/kernel.h>
# include <linux/completion.h>
2016-12-01 11:47:10 +00:00
# include <linux/delay.h>
2016-12-01 11:47:06 +00:00
# include <linux/kthread.h>
# include <linux/module.h>
2016-12-01 11:47:10 +00:00
# include <linux/random.h>
2016-12-01 11:47:09 +00:00
# include <linux/slab.h>
2016-12-01 11:47:06 +00:00
# include <linux/ww_mutex.h>
2018-06-15 10:17:38 +02:00
static DEFINE_WD_CLASS ( ww_class ) ;
2016-12-01 11:47:09 +00:00
struct workqueue_struct * wq ;
2016-12-01 11:47:06 +00:00
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
# ifdef CONFIG_DEBUG_WW_MUTEX_SLOWPATH
# define ww_acquire_init_noinject(a, b) do { \
ww_acquire_init ( ( a ) , ( b ) ) ; \
( a ) - > deadlock_inject_countdown = ~ 0U ; \
} while ( 0 )
# else
# define ww_acquire_init_noinject(a, b) ww_acquire_init((a), (b))
# endif
2016-12-01 11:47:06 +00:00
struct test_mutex {
struct work_struct work ;
struct ww_mutex mutex ;
struct completion ready , go , done ;
unsigned int flags ;
} ;
# define TEST_MTX_SPIN BIT(0)
# define TEST_MTX_TRY BIT(1)
# define TEST_MTX_CTX BIT(2)
# define __TEST_MTX_LAST BIT(3)
static void test_mutex_work ( struct work_struct * work )
{
struct test_mutex * mtx = container_of ( work , typeof ( * mtx ) , work ) ;
complete ( & mtx - > ready ) ;
wait_for_completion ( & mtx - > go ) ;
if ( mtx - > flags & TEST_MTX_TRY ) {
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
while ( ! ww_mutex_trylock ( & mtx - > mutex , NULL ) )
2017-02-28 09:40:11 +00:00
cond_resched ( ) ;
2016-12-01 11:47:06 +00:00
} else {
ww_mutex_lock ( & mtx - > mutex , NULL ) ;
}
complete ( & mtx - > done ) ;
ww_mutex_unlock ( & mtx - > mutex ) ;
}
static int __test_mutex ( unsigned int flags )
{
# define TIMEOUT (HZ / 16)
struct test_mutex mtx ;
struct ww_acquire_ctx ctx ;
int ret ;
ww_mutex_init ( & mtx . mutex , & ww_class ) ;
ww_acquire_init ( & ctx , & ww_class ) ;
INIT_WORK_ONSTACK ( & mtx . work , test_mutex_work ) ;
init_completion ( & mtx . ready ) ;
init_completion ( & mtx . go ) ;
init_completion ( & mtx . done ) ;
mtx . flags = flags ;
schedule_work ( & mtx . work ) ;
wait_for_completion ( & mtx . ready ) ;
ww_mutex_lock ( & mtx . mutex , ( flags & TEST_MTX_CTX ) ? & ctx : NULL ) ;
complete ( & mtx . go ) ;
if ( flags & TEST_MTX_SPIN ) {
unsigned long timeout = jiffies + TIMEOUT ;
ret = 0 ;
do {
if ( completion_done ( & mtx . done ) ) {
ret = - EINVAL ;
break ;
}
2017-02-28 09:40:11 +00:00
cond_resched ( ) ;
2016-12-01 11:47:06 +00:00
} while ( time_before ( jiffies , timeout ) ) ;
} else {
ret = wait_for_completion_timeout ( & mtx . done , TIMEOUT ) ;
}
ww_mutex_unlock ( & mtx . mutex ) ;
ww_acquire_fini ( & ctx ) ;
if ( ret ) {
pr_err ( " %s(flags=%x): mutual exclusion failure \n " ,
__func__ , flags ) ;
ret = - EINVAL ;
}
flush_work ( & mtx . work ) ;
destroy_work_on_stack ( & mtx . work ) ;
return ret ;
# undef TIMEOUT
}
static int test_mutex ( void )
{
int ret ;
int i ;
for ( i = 0 ; i < __TEST_MTX_LAST ; i + + ) {
ret = __test_mutex ( i ) ;
if ( ret )
return ret ;
}
return 0 ;
}
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
static int test_aa ( bool trylock )
2016-12-01 11:47:07 +00:00
{
struct ww_mutex mutex ;
struct ww_acquire_ctx ctx ;
int ret ;
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
const char * from = trylock ? " trylock " : " lock " ;
2016-12-01 11:47:07 +00:00
ww_mutex_init ( & mutex , & ww_class ) ;
ww_acquire_init ( & ctx , & ww_class ) ;
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
if ( ! trylock ) {
ret = ww_mutex_lock ( & mutex , & ctx ) ;
if ( ret ) {
pr_err ( " %s: initial lock failed! \n " , __func__ ) ;
goto out ;
}
} else {
2021-09-22 07:58:22 -07:00
ret = ! ww_mutex_trylock ( & mutex , & ctx ) ;
if ( ret ) {
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
pr_err ( " %s: initial trylock failed! \n " , __func__ ) ;
goto out ;
}
}
2016-12-01 11:47:07 +00:00
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
if ( ww_mutex_trylock ( & mutex , NULL ) ) {
pr_err ( " %s: trylocked itself without context from %s! \n " , __func__ , from ) ;
ww_mutex_unlock ( & mutex ) ;
ret = - EINVAL ;
goto out ;
}
if ( ww_mutex_trylock ( & mutex , & ctx ) ) {
pr_err ( " %s: trylocked itself with context from %s! \n " , __func__ , from ) ;
2016-12-01 11:47:07 +00:00
ww_mutex_unlock ( & mutex ) ;
ret = - EINVAL ;
goto out ;
}
ret = ww_mutex_lock ( & mutex , & ctx ) ;
if ( ret ! = - EALREADY ) {
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
pr_err ( " %s: missed deadlock for recursing, ret=%d from %s \n " ,
__func__ , ret , from ) ;
2016-12-01 11:47:07 +00:00
if ( ! ret )
ww_mutex_unlock ( & mutex ) ;
ret = - EINVAL ;
goto out ;
}
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
ww_mutex_unlock ( & mutex ) ;
2016-12-01 11:47:07 +00:00
ret = 0 ;
out :
ww_acquire_fini ( & ctx ) ;
return ret ;
}
2016-12-01 11:47:08 +00:00
struct test_abba {
struct work_struct work ;
struct ww_mutex a_mutex ;
struct ww_mutex b_mutex ;
struct completion a_ready ;
struct completion b_ready ;
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
bool resolve , trylock ;
2016-12-01 11:47:08 +00:00
int result ;
} ;
static void test_abba_work ( struct work_struct * work )
{
struct test_abba * abba = container_of ( work , typeof ( * abba ) , work ) ;
struct ww_acquire_ctx ctx ;
int err ;
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
ww_acquire_init_noinject ( & ctx , & ww_class ) ;
if ( ! abba - > trylock )
ww_mutex_lock ( & abba - > b_mutex , & ctx ) ;
else
WARN_ON ( ! ww_mutex_trylock ( & abba - > b_mutex , & ctx ) ) ;
WARN_ON ( READ_ONCE ( abba - > b_mutex . ctx ) ! = & ctx ) ;
2016-12-01 11:47:08 +00:00
complete ( & abba - > b_ready ) ;
wait_for_completion ( & abba - > a_ready ) ;
err = ww_mutex_lock ( & abba - > a_mutex , & ctx ) ;
if ( abba - > resolve & & err = = - EDEADLK ) {
ww_mutex_unlock ( & abba - > b_mutex ) ;
ww_mutex_lock_slow ( & abba - > a_mutex , & ctx ) ;
err = ww_mutex_lock ( & abba - > b_mutex , & ctx ) ;
}
if ( ! err )
ww_mutex_unlock ( & abba - > a_mutex ) ;
ww_mutex_unlock ( & abba - > b_mutex ) ;
ww_acquire_fini ( & ctx ) ;
abba - > result = err ;
}
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
static int test_abba ( bool trylock , bool resolve )
2016-12-01 11:47:08 +00:00
{
struct test_abba abba ;
struct ww_acquire_ctx ctx ;
int err , ret ;
ww_mutex_init ( & abba . a_mutex , & ww_class ) ;
ww_mutex_init ( & abba . b_mutex , & ww_class ) ;
INIT_WORK_ONSTACK ( & abba . work , test_abba_work ) ;
init_completion ( & abba . a_ready ) ;
init_completion ( & abba . b_ready ) ;
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
abba . trylock = trylock ;
2016-12-01 11:47:08 +00:00
abba . resolve = resolve ;
schedule_work ( & abba . work ) ;
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
ww_acquire_init_noinject ( & ctx , & ww_class ) ;
if ( ! trylock )
ww_mutex_lock ( & abba . a_mutex , & ctx ) ;
else
WARN_ON ( ! ww_mutex_trylock ( & abba . a_mutex , & ctx ) ) ;
WARN_ON ( READ_ONCE ( abba . a_mutex . ctx ) ! = & ctx ) ;
2016-12-01 11:47:08 +00:00
complete ( & abba . a_ready ) ;
wait_for_completion ( & abba . b_ready ) ;
err = ww_mutex_lock ( & abba . b_mutex , & ctx ) ;
if ( resolve & & err = = - EDEADLK ) {
ww_mutex_unlock ( & abba . a_mutex ) ;
ww_mutex_lock_slow ( & abba . b_mutex , & ctx ) ;
err = ww_mutex_lock ( & abba . a_mutex , & ctx ) ;
}
if ( ! err )
ww_mutex_unlock ( & abba . b_mutex ) ;
ww_mutex_unlock ( & abba . a_mutex ) ;
ww_acquire_fini ( & ctx ) ;
flush_work ( & abba . work ) ;
destroy_work_on_stack ( & abba . work ) ;
ret = 0 ;
if ( resolve ) {
if ( err | | abba . result ) {
pr_err ( " %s: failed to resolve ABBA deadlock, A err=%d, B err=%d \n " ,
__func__ , err , abba . result ) ;
ret = - EINVAL ;
}
} else {
if ( err ! = - EDEADLK & & abba . result ! = - EDEADLK ) {
pr_err ( " %s: missed ABBA deadlock, A err=%d, B err=%d \n " ,
__func__ , err , abba . result ) ;
ret = - EINVAL ;
}
}
return ret ;
}
2016-12-01 11:47:09 +00:00
struct test_cycle {
struct work_struct work ;
struct ww_mutex a_mutex ;
struct ww_mutex * b_mutex ;
struct completion * a_signal ;
struct completion b_signal ;
int result ;
} ;
static void test_cycle_work ( struct work_struct * work )
{
struct test_cycle * cycle = container_of ( work , typeof ( * cycle ) , work ) ;
struct ww_acquire_ctx ctx ;
2018-10-02 14:48:49 -07:00
int err , erra = 0 ;
2016-12-01 11:47:09 +00:00
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
ww_acquire_init_noinject ( & ctx , & ww_class ) ;
2016-12-01 11:47:09 +00:00
ww_mutex_lock ( & cycle - > a_mutex , & ctx ) ;
complete ( cycle - > a_signal ) ;
wait_for_completion ( & cycle - > b_signal ) ;
err = ww_mutex_lock ( cycle - > b_mutex , & ctx ) ;
if ( err = = - EDEADLK ) {
2018-10-02 14:48:49 -07:00
err = 0 ;
2016-12-01 11:47:09 +00:00
ww_mutex_unlock ( & cycle - > a_mutex ) ;
ww_mutex_lock_slow ( cycle - > b_mutex , & ctx ) ;
2018-10-02 14:48:49 -07:00
erra = ww_mutex_lock ( & cycle - > a_mutex , & ctx ) ;
2016-12-01 11:47:09 +00:00
}
if ( ! err )
ww_mutex_unlock ( cycle - > b_mutex ) ;
2018-10-02 14:48:49 -07:00
if ( ! erra )
ww_mutex_unlock ( & cycle - > a_mutex ) ;
2016-12-01 11:47:09 +00:00
ww_acquire_fini ( & ctx ) ;
2018-10-02 14:48:49 -07:00
cycle - > result = err ? : erra ;
2016-12-01 11:47:09 +00:00
}
static int __test_cycle ( unsigned int nthreads )
{
struct test_cycle * cycles ;
unsigned int n , last = nthreads - 1 ;
int ret ;
cycles = kmalloc_array ( nthreads , sizeof ( * cycles ) , GFP_KERNEL ) ;
if ( ! cycles )
return - ENOMEM ;
for ( n = 0 ; n < nthreads ; n + + ) {
struct test_cycle * cycle = & cycles [ n ] ;
ww_mutex_init ( & cycle - > a_mutex , & ww_class ) ;
if ( n = = last )
cycle - > b_mutex = & cycles [ 0 ] . a_mutex ;
else
cycle - > b_mutex = & cycles [ n + 1 ] . a_mutex ;
if ( n = = 0 )
cycle - > a_signal = & cycles [ last ] . b_signal ;
else
cycle - > a_signal = & cycles [ n - 1 ] . b_signal ;
init_completion ( & cycle - > b_signal ) ;
INIT_WORK ( & cycle - > work , test_cycle_work ) ;
cycle - > result = 0 ;
}
for ( n = 0 ; n < nthreads ; n + + )
queue_work ( wq , & cycles [ n ] . work ) ;
flush_workqueue ( wq ) ;
ret = 0 ;
for ( n = 0 ; n < nthreads ; n + + ) {
struct test_cycle * cycle = & cycles [ n ] ;
if ( ! cycle - > result )
continue ;
2018-08-24 12:22:35 +01:00
pr_err ( " cyclic deadlock not resolved, ret[%d/%d] = %d \n " ,
2016-12-01 11:47:09 +00:00
n , nthreads , cycle - > result ) ;
ret = - EINVAL ;
break ;
}
for ( n = 0 ; n < nthreads ; n + + )
ww_mutex_destroy ( & cycles [ n ] . a_mutex ) ;
kfree ( cycles ) ;
return ret ;
}
static int test_cycle ( unsigned int ncpus )
{
unsigned int n ;
int ret ;
for ( n = 2 ; n < = ncpus + 1 ; n + + ) {
ret = __test_cycle ( n ) ;
if ( ret )
return ret ;
}
return 0 ;
}
2016-12-01 11:47:10 +00:00
struct stress {
struct work_struct work ;
struct ww_mutex * locks ;
2017-03-10 10:57:33 +00:00
unsigned long timeout ;
2016-12-01 11:47:10 +00:00
int nlocks ;
} ;
static int * get_random_order ( int count )
{
int * order ;
int n , r , tmp ;
2017-09-13 16:28:29 -07:00
order = kmalloc_array ( count , sizeof ( * order ) , GFP_KERNEL ) ;
2016-12-01 11:47:10 +00:00
if ( ! order )
return order ;
for ( n = 0 ; n < count ; n + + )
order [ n ] = n ;
for ( n = count - 1 ; n > 1 ; n - - ) {
2022-10-05 16:43:38 +02:00
r = prandom_u32_max ( n + 1 ) ;
2016-12-01 11:47:10 +00:00
if ( r ! = n ) {
tmp = order [ n ] ;
order [ n ] = order [ r ] ;
order [ r ] = tmp ;
}
}
return order ;
}
static void dummy_load ( struct stress * stress )
{
usleep_range ( 1000 , 2000 ) ;
}
static void stress_inorder_work ( struct work_struct * work )
{
struct stress * stress = container_of ( work , typeof ( * stress ) , work ) ;
const int nlocks = stress - > nlocks ;
struct ww_mutex * locks = stress - > locks ;
struct ww_acquire_ctx ctx ;
int * order ;
order = get_random_order ( nlocks ) ;
if ( ! order )
return ;
do {
int contended = - 1 ;
int n , err ;
2017-03-03 13:57:56 +01:00
ww_acquire_init ( & ctx , & ww_class ) ;
2016-12-01 11:47:10 +00:00
retry :
err = 0 ;
for ( n = 0 ; n < nlocks ; n + + ) {
if ( n = = contended )
continue ;
err = ww_mutex_lock ( & locks [ order [ n ] ] , & ctx ) ;
if ( err < 0 )
break ;
}
if ( ! err )
dummy_load ( stress ) ;
if ( contended > n )
ww_mutex_unlock ( & locks [ order [ contended ] ] ) ;
contended = n ;
while ( n - - )
ww_mutex_unlock ( & locks [ order [ n ] ] ) ;
if ( err = = - EDEADLK ) {
ww_mutex_lock_slow ( & locks [ order [ contended ] ] , & ctx ) ;
goto retry ;
}
if ( err ) {
pr_err_once ( " stress (%s) failed with %d \n " ,
__func__ , err ) ;
break ;
}
2017-03-03 13:57:56 +01:00
ww_acquire_fini ( & ctx ) ;
2017-03-10 10:57:33 +00:00
} while ( ! time_after ( jiffies , stress - > timeout ) ) ;
2016-12-01 11:47:10 +00:00
kfree ( order ) ;
kfree ( stress ) ;
}
struct reorder_lock {
struct list_head link ;
struct ww_mutex * lock ;
} ;
static void stress_reorder_work ( struct work_struct * work )
{
struct stress * stress = container_of ( work , typeof ( * stress ) , work ) ;
LIST_HEAD ( locks ) ;
struct ww_acquire_ctx ctx ;
struct reorder_lock * ll , * ln ;
int * order ;
int n , err ;
order = get_random_order ( stress - > nlocks ) ;
if ( ! order )
return ;
for ( n = 0 ; n < stress - > nlocks ; n + + ) {
ll = kmalloc ( sizeof ( * ll ) , GFP_KERNEL ) ;
if ( ! ll )
goto out ;
ll - > lock = & stress - > locks [ order [ n ] ] ;
list_add ( & ll - > link , & locks ) ;
}
kfree ( order ) ;
order = NULL ;
do {
2017-03-03 13:57:56 +01:00
ww_acquire_init ( & ctx , & ww_class ) ;
2016-12-01 11:47:10 +00:00
list_for_each_entry ( ll , & locks , link ) {
err = ww_mutex_lock ( ll - > lock , & ctx ) ;
if ( ! err )
continue ;
ln = ll ;
list_for_each_entry_continue_reverse ( ln , & locks , link )
ww_mutex_unlock ( ln - > lock ) ;
if ( err ! = - EDEADLK ) {
pr_err_once ( " stress (%s) failed with %d \n " ,
__func__ , err ) ;
break ;
}
ww_mutex_lock_slow ( ll - > lock , & ctx ) ;
list_move ( & ll - > link , & locks ) ; /* restarts iteration */
}
dummy_load ( stress ) ;
list_for_each_entry ( ll , & locks , link )
ww_mutex_unlock ( ll - > lock ) ;
2017-03-03 13:57:56 +01:00
ww_acquire_fini ( & ctx ) ;
2017-03-10 10:57:33 +00:00
} while ( ! time_after ( jiffies , stress - > timeout ) ) ;
2016-12-01 11:47:10 +00:00
out :
list_for_each_entry_safe ( ll , ln , & locks , link )
kfree ( ll ) ;
kfree ( order ) ;
kfree ( stress ) ;
}
static void stress_one_work ( struct work_struct * work )
{
struct stress * stress = container_of ( work , typeof ( * stress ) , work ) ;
const int nlocks = stress - > nlocks ;
2022-10-05 16:43:38 +02:00
struct ww_mutex * lock = stress - > locks + prandom_u32_max ( nlocks ) ;
2016-12-01 11:47:10 +00:00
int err ;
do {
err = ww_mutex_lock ( lock , NULL ) ;
if ( ! err ) {
dummy_load ( stress ) ;
ww_mutex_unlock ( lock ) ;
} else {
pr_err_once ( " stress (%s) failed with %d \n " ,
__func__ , err ) ;
break ;
}
2017-03-10 10:57:33 +00:00
} while ( ! time_after ( jiffies , stress - > timeout ) ) ;
2016-12-01 11:47:10 +00:00
kfree ( stress ) ;
}
# define STRESS_INORDER BIT(0)
# define STRESS_REORDER BIT(1)
# define STRESS_ONE BIT(2)
# define STRESS_ALL (STRESS_INORDER | STRESS_REORDER | STRESS_ONE)
2017-03-10 10:57:33 +00:00
static int stress ( int nlocks , int nthreads , unsigned int flags )
2016-12-01 11:47:10 +00:00
{
struct ww_mutex * locks ;
int n ;
locks = kmalloc_array ( nlocks , sizeof ( * locks ) , GFP_KERNEL ) ;
if ( ! locks )
return - ENOMEM ;
for ( n = 0 ; n < nlocks ; n + + )
ww_mutex_init ( & locks [ n ] , & ww_class ) ;
for ( n = 0 ; nthreads ; n + + ) {
struct stress * stress ;
void ( * fn ) ( struct work_struct * work ) ;
fn = NULL ;
switch ( n & 3 ) {
case 0 :
if ( flags & STRESS_INORDER )
fn = stress_inorder_work ;
break ;
case 1 :
if ( flags & STRESS_REORDER )
fn = stress_reorder_work ;
break ;
case 2 :
if ( flags & STRESS_ONE )
fn = stress_one_work ;
break ;
}
if ( ! fn )
continue ;
stress = kmalloc ( sizeof ( * stress ) , GFP_KERNEL ) ;
if ( ! stress )
break ;
INIT_WORK ( & stress - > work , fn ) ;
stress - > locks = locks ;
stress - > nlocks = nlocks ;
2017-03-10 10:57:33 +00:00
stress - > timeout = jiffies + 2 * HZ ;
2016-12-01 11:47:10 +00:00
queue_work ( wq , & stress - > work ) ;
nthreads - - ;
}
flush_workqueue ( wq ) ;
for ( n = 0 ; n < nlocks ; n + + )
ww_mutex_destroy ( & locks [ n ] ) ;
kfree ( locks ) ;
return 0 ;
}
2016-12-01 11:47:06 +00:00
static int __init test_ww_mutex_init ( void )
{
2016-12-01 11:47:09 +00:00
int ncpus = num_online_cpus ( ) ;
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
int ret , i ;
printk ( KERN_INFO " Beginning ww mutex selftests \n " ) ;
2016-12-01 11:47:06 +00:00
2016-12-01 11:47:09 +00:00
wq = alloc_workqueue ( " test-ww_mutex " , WQ_UNBOUND , 0 ) ;
if ( ! wq )
return - ENOMEM ;
2016-12-01 11:47:06 +00:00
ret = test_mutex ( ) ;
if ( ret )
return ret ;
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
ret = test_aa ( false ) ;
2016-12-01 11:47:07 +00:00
if ( ret )
return ret ;
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
ret = test_aa ( true ) ;
2016-12-01 11:47:08 +00:00
if ( ret )
return ret ;
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
for ( i = 0 ; i < 4 ; i + + ) {
ret = test_abba ( i & 1 , i & 2 ) ;
if ( ret )
return ret ;
}
2016-12-01 11:47:08 +00:00
2016-12-01 11:47:09 +00:00
ret = test_cycle ( ncpus ) ;
if ( ret )
return ret ;
2017-03-10 10:57:33 +00:00
ret = stress ( 16 , 2 * ncpus , STRESS_INORDER ) ;
2016-12-01 11:47:10 +00:00
if ( ret )
return ret ;
2017-03-10 10:57:33 +00:00
ret = stress ( 16 , 2 * ncpus , STRESS_REORDER ) ;
2016-12-01 11:47:10 +00:00
if ( ret )
return ret ;
2017-03-10 10:57:33 +00:00
ret = stress ( 4095 , hweight32 ( STRESS_ALL ) * ncpus , STRESS_ALL ) ;
2016-12-01 11:47:10 +00:00
if ( ret )
return ret ;
kernel/locking: Add context to ww_mutex_trylock()
i915 will soon gain an eviction path that trylock a whole lot of locks
for eviction, getting dmesg failures like below:
BUG: MAX_LOCK_DEPTH too low!
turning off the locking correctness validator.
depth: 48 max: 48!
48 locks held by i915_selftest/5776:
#0: ffff888101a79240 (&dev->mutex){....}-{3:3}, at: __driver_attach+0x88/0x160
#1: ffffc900009778c0 (reservation_ww_class_acquire){+.+.}-{0:0}, at: i915_vma_pin.constprop.63+0x39/0x1b0 [i915]
#2: ffff88800cf74de8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_vma_pin.constprop.63+0x5f/0x1b0 [i915]
#3: ffff88810c7f9e38 (&vm->mutex/1){+.+.}-{3:3}, at: i915_vma_pin_ww+0x1c4/0x9d0 [i915]
#4: ffff88810bad5768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#5: ffff88810bad60e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
...
#46: ffff88811964d768 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
#47: ffff88811964e0e8 (reservation_ww_class_mutex){+.+.}-{3:3}, at: i915_gem_evict_something+0x110/0x860 [i915]
INFO: lockdep is turned off.
Fixing eviction to nest into ww_class_acquire is a high priority, but
it requires a rework of the entire driver, which can only be done one
step at a time.
As an intermediate solution, add an acquire context to
ww_mutex_trylock, which allows us to do proper nesting annotations on
the trylocks, making the above lockdep splat disappear.
This is also useful in regulator_lock_nested, which may avoid dropping
regulator_nesting_mutex in the uncontended path, so use it there.
TTM may be another user for this, where we could lock a buffer in a
fastpath with list locks held, without dropping all locks we hold.
[peterz: rework actual ww_mutex_trylock() implementations]
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/YUBGPdDDjKlxAuXJ@hirez.programming.kicks-ass.net
2021-09-09 11:32:18 +02:00
printk ( KERN_INFO " All ww mutex selftests passed \n " ) ;
2016-12-01 11:47:06 +00:00
return 0 ;
}
static void __exit test_ww_mutex_exit ( void )
{
2016-12-01 11:47:09 +00:00
destroy_workqueue ( wq ) ;
2016-12-01 11:47:06 +00:00
}
module_init ( test_ww_mutex_init ) ;
module_exit ( test_ww_mutex_exit ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Intel Corporation " ) ;