* [PATCH v3 1/3] lockdep: add lockdep_assert_not_held()
2021-02-27 0:06 [PATCH v3 0/3] Add lockdep_assert_not_held() Shuah Khan
@ 2021-02-27 0:06 ` Shuah Khan
2021-02-27 0:06 ` [PATCH v3 2/3] lockdep: add lockdep lock state defines Shuah Khan
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Shuah Khan @ 2021-02-27 0:06 UTC (permalink / raw)
To: peterz, mingo, will, kvalo, davem, kuba
Cc: Shuah Khan, ath10k, linux-wireless, netdev, linux-kernel
Some kernel functions must be called without holding a specific lock.
Add lockdep_assert_not_held() to be used in these functions to detect
incorrect calls while holding a lock.
lockdep_assert_not_held() provides the opposite functionality of
lockdep_assert_held() which is used to assert calls that require
holding a specific lock.
Incorporates suggestions from Peter Zijlstra to avoid misfires when
lockdep_off() is employed.
The need for lockdep_assert_not_held() came up in a discussion on
ath10k patch. ath10k_drain_tx() and i915_vma_pin_ww() are examples
of functions that can use lockdep_assert_not_held().
Link: https://lore.kernel.org/lkml/37a29c383bff2fb1605241ee6c7c9be3784fb3c6.1613171185.git.skhan@linuxfoundation.org/
Link: https://lore.kernel.org/linux-wireless/871rdmu9z9.fsf@codeaurora.org/
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
---
include/linux/lockdep.h | 11 ++++++++---
kernel/locking/lockdep.c | 6 +++++-
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index 7b7ebf2e28ec..dbd9ea846b36 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -301,8 +301,12 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)
-#define lockdep_assert_held(l) do { \
- WARN_ON(debug_locks && !lockdep_is_held(l)); \
+#define lockdep_assert_held(l) do { \
+ WARN_ON(debug_locks && lockdep_is_held(l) == 0); \
+ } while (0)
+
+#define lockdep_assert_not_held(l) do { \
+ WARN_ON(debug_locks && lockdep_is_held(l) == 1); \
} while (0)
#define lockdep_assert_held_write(l) do { \
@@ -393,7 +397,8 @@ extern int lockdep_is_held(const void *);
#define lockdep_is_held_type(l, r) (1)
#define lockdep_assert_held(l) do { (void)(l); } while (0)
-#define lockdep_assert_held_write(l) do { (void)(l); } while (0)
+#define lockdep_assert_not_held(l) do { (void)(l); } while (0)
+#define lockdep_assert_held_write(l) do { (void)(l); } while (0)
#define lockdep_assert_held_read(l) do { (void)(l); } while (0)
#define lockdep_assert_held_once(l) do { (void)(l); } while (0)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index c6d0c1dc6253..818d0ceed3eb 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -5539,8 +5539,12 @@ noinstr int lock_is_held_type(const struct lockdep_map *lock, int read)
unsigned long flags;
int ret = 0;
+ /*
+ * avoid false negative lockdep_assert_held() and
+ * lockdep_assert_not_held()
+ */
if (unlikely(!lockdep_enabled()))
- return 1; /* avoid false negative lockdep_assert_held() */
+ return -1;
raw_local_irq_save(flags);
check_flags(flags);
--
2.27.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 2/3] lockdep: add lockdep lock state defines
2021-02-27 0:06 [PATCH v3 0/3] Add lockdep_assert_not_held() Shuah Khan
2021-02-27 0:06 ` [PATCH v3 1/3] lockdep: add lockdep_assert_not_held() Shuah Khan
@ 2021-02-27 0:06 ` Shuah Khan
2021-02-27 0:07 ` [PATCH v3 3/3] ath10k: detect conf_mutex held ath10k_drain_tx() calls Shuah Khan
2021-03-01 8:38 ` [PATCH v3 0/3] Add lockdep_assert_not_held() Peter Zijlstra
3 siblings, 0 replies; 9+ messages in thread
From: Shuah Khan @ 2021-02-27 0:06 UTC (permalink / raw)
To: peterz, mingo, will, kvalo, davem, kuba
Cc: Shuah Khan, ath10k, linux-wireless, netdev, linux-kernel
Adds defines for lock state returns from lock_is_held_type() based on
Johannes Berg's suggestions as it make it easier to read and maintain
the lock states. These are defines and a enum to avoid changes to
lock_is_held_type() and lockdep_is_held() return types.
Updates to lock_is_held_type() and __lock_is_held() to use the new
defines.
Link: https://lore.kernel.org/lkml/37a29c383bff2fb1605241ee6c7c9be3784fb3c6.1613171185.git.skhan@linuxfoundation.org/
Link: https://lore.kernel.org/linux-wireless/871rdmu9z9.fsf@codeaurora.org/
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
---
include/linux/lockdep.h | 11 +++++++++--
kernel/locking/lockdep.c | 11 ++++++-----
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index dbd9ea846b36..17805aac0e85 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -268,6 +268,11 @@ extern void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
extern void lock_release(struct lockdep_map *lock, unsigned long ip);
+/* lock_is_held_type() returns */
+#define LOCK_STATE_UNKNOWN -1
+#define LOCK_STATE_NOT_HELD 0
+#define LOCK_STATE_HELD 1
+
/*
* Same "read" as for lock_acquire(), except -1 means any.
*/
@@ -302,11 +307,13 @@ extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie);
#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)
#define lockdep_assert_held(l) do { \
- WARN_ON(debug_locks && lockdep_is_held(l) == 0); \
+ WARN_ON(debug_locks && \
+ lockdep_is_held(l) == LOCK_STATE_NOT_HELD); \
} while (0)
#define lockdep_assert_not_held(l) do { \
- WARN_ON(debug_locks && lockdep_is_held(l) == 1); \
+ WARN_ON(debug_locks && \
+ lockdep_is_held(l) == LOCK_STATE_HELD); \
} while (0)
#define lockdep_assert_held_write(l) do { \
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 818d0ceed3eb..f5a8200f24f1 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -54,6 +54,7 @@
#include <linux/nmi.h>
#include <linux/rcupdate.h>
#include <linux/kprobes.h>
+#include <linux/lockdep.h>
#include <asm/sections.h>
@@ -5252,13 +5253,13 @@ int __lock_is_held(const struct lockdep_map *lock, int read)
if (match_held_lock(hlock, lock)) {
if (read == -1 || hlock->read == read)
- return 1;
+ return LOCK_STATE_HELD;
- return 0;
+ return LOCK_STATE_NOT_HELD;
}
}
- return 0;
+ return LOCK_STATE_NOT_HELD;
}
static struct pin_cookie __lock_pin_lock(struct lockdep_map *lock)
@@ -5537,14 +5538,14 @@ EXPORT_SYMBOL_GPL(lock_release);
noinstr int lock_is_held_type(const struct lockdep_map *lock, int read)
{
unsigned long flags;
- int ret = 0;
+ int ret = LOCK_STATE_NOT_HELD;
/*
* avoid false negative lockdep_assert_held() and
* lockdep_assert_not_held()
*/
if (unlikely(!lockdep_enabled()))
- return -1;
+ return LOCK_STATE_UNKNOWN;
raw_local_irq_save(flags);
check_flags(flags);
--
2.27.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3 3/3] ath10k: detect conf_mutex held ath10k_drain_tx() calls
2021-02-27 0:06 [PATCH v3 0/3] Add lockdep_assert_not_held() Shuah Khan
2021-02-27 0:06 ` [PATCH v3 1/3] lockdep: add lockdep_assert_not_held() Shuah Khan
2021-02-27 0:06 ` [PATCH v3 2/3] lockdep: add lockdep lock state defines Shuah Khan
@ 2021-02-27 0:07 ` Shuah Khan
2021-03-01 8:38 ` [PATCH v3 0/3] Add lockdep_assert_not_held() Peter Zijlstra
3 siblings, 0 replies; 9+ messages in thread
From: Shuah Khan @ 2021-02-27 0:07 UTC (permalink / raw)
To: peterz, mingo, will, kvalo, davem, kuba
Cc: Shuah Khan, ath10k, linux-wireless, netdev, linux-kernel
ath10k_drain_tx() must not be called with conf_mutex held as workers can
use that also. Add call to lockdep_assert_not_held() on conf_mutex to
detect if conf_mutex is held by the caller.
The idea for this patch stemmed from coming across the comment block
above the ath10k_drain_tx() while reviewing the conf_mutex holds during
to debug the conf_mutex lock assert in ath10k_debug_fw_stats_request().
Adding detection to assert on conf_mutex hold will help detect incorrect
usages that could lead to locking problems when async worker routines try
to call this routine.
Link: https://lore.kernel.org/lkml/37a29c383bff2fb1605241ee6c7c9be3784fb3c6.1613171185.git.skhan@linuxfoundation.org/
Link: https://lore.kernel.org/linux-wireless/871rdmu9z9.fsf@codeaurora.org/
Acked-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
---
drivers/net/wireless/ath/ath10k/mac.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index bb6c5ee43ac0..5ce4f8d038b9 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4727,6 +4727,8 @@ static void ath10k_mac_op_wake_tx_queue(struct ieee80211_hw *hw,
/* Must not be called with conf_mutex held as workers can use that also. */
void ath10k_drain_tx(struct ath10k *ar)
{
+ lockdep_assert_not_held(&ar->conf_mutex);
+
/* make sure rcu-protected mac80211 tx path itself is drained */
synchronize_net();
--
2.27.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v3 0/3] Add lockdep_assert_not_held()
2021-02-27 0:06 [PATCH v3 0/3] Add lockdep_assert_not_held() Shuah Khan
` (2 preceding siblings ...)
2021-02-27 0:07 ` [PATCH v3 3/3] ath10k: detect conf_mutex held ath10k_drain_tx() calls Shuah Khan
@ 2021-03-01 8:38 ` Peter Zijlstra
2021-03-01 8:45 ` Kalle Valo
3 siblings, 1 reply; 9+ messages in thread
From: Peter Zijlstra @ 2021-03-01 8:38 UTC (permalink / raw)
To: Shuah Khan
Cc: mingo, will, kvalo, davem, kuba, ath10k, linux-wireless, netdev,
linux-kernel
On Fri, Feb 26, 2021 at 05:06:57PM -0700, Shuah Khan wrote:
> Shuah Khan (3):
> lockdep: add lockdep_assert_not_held()
> lockdep: add lockdep lock state defines
> ath10k: detect conf_mutex held ath10k_drain_tx() calls
Thanks!
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 0/3] Add lockdep_assert_not_held()
2021-03-01 8:38 ` [PATCH v3 0/3] Add lockdep_assert_not_held() Peter Zijlstra
@ 2021-03-01 8:45 ` Kalle Valo
2021-03-01 9:36 ` Peter Zijlstra
0 siblings, 1 reply; 9+ messages in thread
From: Kalle Valo @ 2021-03-01 8:45 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Shuah Khan, netdev, linux-wireless, linux-kernel, ath10k, mingo,
kuba, will, davem
Peter Zijlstra <peterz@infradead.org> writes:
> On Fri, Feb 26, 2021 at 05:06:57PM -0700, Shuah Khan wrote:
>> Shuah Khan (3):
>> lockdep: add lockdep_assert_not_held()
>> lockdep: add lockdep lock state defines
>> ath10k: detect conf_mutex held ath10k_drain_tx() calls
>
> Thanks!
Via which tree should these go?
--
https://patchwork.kernel.org/project/linux-wireless/list/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 0/3] Add lockdep_assert_not_held()
2021-03-01 8:45 ` Kalle Valo
@ 2021-03-01 9:36 ` Peter Zijlstra
2021-03-01 11:02 ` Kalle Valo
0 siblings, 1 reply; 9+ messages in thread
From: Peter Zijlstra @ 2021-03-01 9:36 UTC (permalink / raw)
To: Kalle Valo
Cc: Shuah Khan, netdev, linux-wireless, linux-kernel, ath10k, mingo,
kuba, will, davem
On Mon, Mar 01, 2021 at 10:45:32AM +0200, Kalle Valo wrote:
> Peter Zijlstra <peterz@infradead.org> writes:
>
> > On Fri, Feb 26, 2021 at 05:06:57PM -0700, Shuah Khan wrote:
> >> Shuah Khan (3):
> >> lockdep: add lockdep_assert_not_held()
> >> lockdep: add lockdep lock state defines
> >> ath10k: detect conf_mutex held ath10k_drain_tx() calls
> >
> > Thanks!
>
> Via which tree should these go?
I've just queued the lot for locking/core, which will show up in tip
when the robots don't hate on it.
Does that work for you?
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 0/3] Add lockdep_assert_not_held()
2021-03-01 9:36 ` Peter Zijlstra
@ 2021-03-01 11:02 ` Kalle Valo
2021-03-01 16:04 ` Shuah Khan
0 siblings, 1 reply; 9+ messages in thread
From: Kalle Valo @ 2021-03-01 11:02 UTC (permalink / raw)
To: Peter Zijlstra
Cc: netdev, linux-wireless, linux-kernel, ath10k, mingo, Shuah Khan,
kuba, will, davem
Peter Zijlstra <peterz@infradead.org> writes:
> On Mon, Mar 01, 2021 at 10:45:32AM +0200, Kalle Valo wrote:
>> Peter Zijlstra <peterz@infradead.org> writes:
>>
>> > On Fri, Feb 26, 2021 at 05:06:57PM -0700, Shuah Khan wrote:
>> >> Shuah Khan (3):
>> >> lockdep: add lockdep_assert_not_held()
>> >> lockdep: add lockdep lock state defines
>> >> ath10k: detect conf_mutex held ath10k_drain_tx() calls
>> >
>> > Thanks!
>>
>> Via which tree should these go?
>
> I've just queued the lot for locking/core, which will show up in tip
> when the robots don't hate on it.
>
> Does that work for you?
That's perfect, thanks! Just making sure that the patches don't get
lost.
--
https://patchwork.kernel.org/project/linux-wireless/list/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 0/3] Add lockdep_assert_not_held()
2021-03-01 11:02 ` Kalle Valo
@ 2021-03-01 16:04 ` Shuah Khan
0 siblings, 0 replies; 9+ messages in thread
From: Shuah Khan @ 2021-03-01 16:04 UTC (permalink / raw)
To: Kalle Valo, Peter Zijlstra
Cc: netdev, linux-wireless, linux-kernel, ath10k, mingo, kuba, will,
davem, Shuah Khan
On 3/1/21 4:02 AM, Kalle Valo wrote:
> Peter Zijlstra <peterz@infradead.org> writes:
>
>> On Mon, Mar 01, 2021 at 10:45:32AM +0200, Kalle Valo wrote:
>>> Peter Zijlstra <peterz@infradead.org> writes:
>>>
>>>> On Fri, Feb 26, 2021 at 05:06:57PM -0700, Shuah Khan wrote:
>>>>> Shuah Khan (3):
>>>>> lockdep: add lockdep_assert_not_held()
>>>>> lockdep: add lockdep lock state defines
>>>>> ath10k: detect conf_mutex held ath10k_drain_tx() calls
>>>>
>>>> Thanks!
>>>
>>> Via which tree should these go?
>>
>> I've just queued the lot for locking/core, which will show up in tip
>> when the robots don't hate on it.
>>
>> Does that work for you?
>
> That's perfect, thanks! Just making sure that the patches don't get
> lost.
>
Awesome. Thank you.
thanks,
-- Shuah
^ permalink raw reply [flat|nested] 9+ messages in thread