spin_lock_*(): Always evaluate second argument
PATCH RESEND 1/1 spin_lock_*(): Always evaluate second argument
Evaluating a macro argument only if certain configuration options have been selected is confusing and error-prone. Hence always evaluate the second argument of spin_lock_nested() and spin_lock_nest_lock().
An intentional side effect of this patch is that it avoids that the following warning is reported for netif_addr_lock_nested() when building with CONFIG_DEBUG_LOCK_ALLOC=n and with W=1:
include/linux/netdevice.h: In function 'netif_addr_lock_nested':include/linux/netdevice.h:2865:6: warning: variable 'subclass' set but not used [-Wunused-but-set-variable]
int subclass = SINGLE_DEPTH_NESTING;
^--- include/linux/spinlock.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
include/linux/spinlock.h +4 -2
@@ -197,8 +197,10 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)_raw_spin_lock_nest_lock (lock, &(nest_lock)->dep_map); \ } while (0) #else -# define raw_spin_lock_nested (lock, subclass) _raw_spin_lock(lock) -# define raw_spin_lock_nest_lock (lock, nest_lock) _raw_spin_lock(lock) +# define raw_spin_lock_nested (lock, subclass) \ + ((void)(subclass), _raw_spin_lock(lock)) +# define raw_spin_lock_nest_lock (lock, nest_lock) \ + ((void)(nest_lock), _raw_spin_lock(lock))#endif #if defined(CONFIG_SMP ) || defined(CONFIG_DEBUG_SPINLOCK )
Signature · 1 line
1.8.4.5
Quoted 15 lines · On Tue, 22 Jul 2014 09:17:45 +0200 Bart Van Assche <[email protected]> wrote:
Evaluating a macro argument only if certain configuration options have been selected is confusing and error-prone. Hence always evaluate the second argument of
spin_lock_nested()andspin_lock_nest_lock().An intentional side effect of this patch is that it avoids that the following warning is reported for
netif_addr_lock_nested()when building withCONFIG_DEBUG_LOCK_ALLOC=nand with W=1:...
include/linux/spinlock.h +0
-0@@ -197,8 +197,10 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)_raw_spin_lock_nest_lock (lock, &(nest_lock)->dep_map); \
include/linux/spinlock.h static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) · line 205
Quoted 10 lines
include/linux/spinlock.h +4
-2} while (0)#else -# define raw_spin_lock_nested (lock, subclass) _raw_spin_lock(lock) -# define raw_spin_lock_nest_lock (lock, nest_lock) _raw_spin_lock(lock) +# define raw_spin_lock_nested (lock, subclass) \ + ((void)(subclass), _raw_spin_lock(lock)) +# define raw_spin_lock_nest_lock (lock, nest_lock) \ + ((void)(nest_lock), _raw_spin_lock(lock))#endif
Did you try converting these to static inline functions? That should squish the warning and makes the code nicer instead of nastier...
Quoted 20 lines · Andrew Morton
Quoted 20 lines
Evaluating a macro argument only if certain configuration options have been selected is confusing and error-prone. Hence always evaluate the second argument of
spin_lock_nested()andspin_lock_nest_lock().An intentional side effect of this patch is that it avoids that the following warning is reported for
netif_addr_lock_nested()when building withCONFIG_DEBUG_LOCK_ALLOC=nand with W=1:...
include/linux/spinlock.h +1
-2@@ -197,8 +197,10 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)_raw_spin_lock_nest_lock (lock, &(nest_lock)->dep_map); \ } while (0) #else -# define raw_spin_lock_nested (lock, subclass) _raw_spin_lock(lock) -# define raw_spin_lock_nest_lock (lock, nest_lock) _raw_spin_lock(lock) +# define raw_spin_lock_nested (lock, subclass) \
Quoted 9 lines
include/linux/spinlock.h static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) · line 205
Quoted 5 lines
include/linux/spinlock.h +3
-0+ ((void)(subclass), _raw_spin_lock(lock)) +# define raw_spin_lock_nest_lock (lock, nest_lock) \ + ((void)(nest_lock), _raw_spin_lock(lock))#endif Did you try converting these to static inline functions? That should squish the warning and makes the code nicer instead of nastier...
Not sure how that would be done since _raw_spin_lock isn't declared in this scope.
Taking a second look, however, I think the patch doesn't need to modify raw_spin_lock_nest_lock() for the problem being reported and evaluating the parameter of type struct lockdep_map * probably is meaningless.
Bart, is it possible to just get away with the raw_spin_lock_nested() change?
Quoted 33 lines · David Rientjes
Quoted 20 lines · Andrew Morton
Quoted 20 lines
Evaluating a macro argument only if certain configuration options have been selected is confusing and error-prone. Hence always evaluate the second argument of
spin_lock_nested()andspin_lock_nest_lock().An intentional side effect of this patch is that it avoids that the following warning is reported for
netif_addr_lock_nested()when building withCONFIG_DEBUG_LOCK_ALLOC=nand with W=1:...
include/linux/spinlock.h +1
-2@@ -197,8 +197,10 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)_raw_spin_lock_nest_lock (lock, &(nest_lock)->dep_map); \ } while (0) #else -# define raw_spin_lock_nested (lock, subclass) _raw_spin_lock(lock) -# define raw_spin_lock_nest_lock (lock, nest_lock) _raw_spin_lock(lock) +# define raw_spin_lock_nested (lock, subclass) \Quoted 8 lines
include/linux/spinlock.h static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) · line 205
Quoted 5 lines
include/linux/spinlock.h +3
-0+ ((void)(subclass), _raw_spin_lock(lock)) +# define raw_spin_lock_nest_lock (lock, nest_lock) \ + ((void)(nest_lock), _raw_spin_lock(lock))#endif Did you try converting these to static inline functions? That should squish the warning and makes the code nicer instead of nastier...
Not sure how that would be done since
_raw_spin_lockisn't declared in this scope.
Quoted 6 lines
Taking a second look, however, I think the patch doesn't need to modify
raw_spin_lock_nest_lock()for the problem being reported and evaluating the parameter of type structlockdep_map* probably is meaningless.Bart, is it possible to just get away with the
raw_spin_lock_nested()change?
Probably ... I will post an updated version of this patch.
Bart.
PATCH v2 1/1 spin_lock_nested(): Always evaluate second argument
Evaluating a macro argument only if certain configuration options have been selected is confusing and error-prone. Hence always evaluate the second argument of spin_lock_nested().
An intentional side effect of this patch is that it avoids that the following warning is reported for netif_addr_lock_nested() when building with CONFIG_DEBUG_LOCK_ALLOC=n and with W=1:
include/linux/netdevice.h: In function 'netif_addr_lock_nested':include/linux/netdevice.h:2865:6: warning: variable 'subclass' set but not used [-Wunused-but-set-variable]
int subclass = SINGLE_DEPTH_NESTING;
^--- include/linux/spinlock.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
include/linux/spinlock.h +2 -1
@@ -197,7 +197,8 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)_raw_spin_lock_nest_lock (lock, &(nest_lock)->dep_map); \ } while (0) #else -# define raw_spin_lock_nested (lock, subclass) _raw_spin_lock(lock) +# define raw_spin_lock_nested (lock, subclass) \ + ((void)(subclass), _raw_spin_lock(lock))# define raw_spin_lock_nest_lock (lock, nest_lock) _raw_spin_lock(lock)#endif
Signature · 1 line
1.8.4.5
Re: [PATCH v2] spin_lock_nested(): Always evaluate second argument
Quoted 5 lines · Bart Van Assche
include/linux/spinlock.h +0
-0
include/linux/spinlock.h static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) · line 204
Quoted 9 lines
include/linux/spinlock.h +2
-1@@ -197,7 +197,8 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)_raw_spin_lock_nest_lock (lock, &(nest_lock)->dep_map); \ } while (0) #else -# define raw_spin_lock_nested (lock, subclass) _raw_spin_lock(lock) +# define raw_spin_lock_nested (lock, subclass) \ + ((void)(subclass), _raw_spin_lock(lock))# define raw_spin_lock_nest_lock (lock, nest_lock) _raw_spin_lock(lock)#endif
I think it would be nice to comment why we're evaluating the subclass when CONFIG_DEBUG_LOCK_ALLOC=n so that nobody comes along and unknowingly changes it back.
Thanks for posting the updated version and keeping at it!
Re: [PATCH v2] spin_lock_nested(): Always evaluate second argument
Quoted 20 lines · David Rientjes
Quoted 5 lines · Bart Van Assche
include/linux/spinlock.h +0
-0include/linux/spinlock.h static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) · line 204
Quoted 9 lines
include/linux/spinlock.h +2
-1@@ -197,7 +197,8 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)_raw_spin_lock_nest_lock (lock, &(nest_lock)->dep_map); \ } while (0) #else -# define raw_spin_lock_nested (lock, subclass) _raw_spin_lock(lock) +# define raw_spin_lock_nested (lock, subclass) \ + ((void)(subclass), _raw_spin_lock(lock))# define raw_spin_lock_nest_lock (lock, nest_lock) _raw_spin_lock(lock)#endif I think it would be nice to comment why we're evaluating the subclass when
CONFIG_DEBUG_LOCK_ALLOC=nso that nobody comes along and unknowingly changes it back.
Quoted 1 line
Thanks for posting the updated version and keeping at it!
This morning I received an e-mail from Wu Fengguang reporting that this patch breaks the build for CONFIG_SMP=n. I will post a third version.
Bart.
PATCH v3 1/1 spin_lock_nested(): Always evaluate second argument
Evaluating a macro argument only if certain configuration options have been selected is confusing and error-prone. Hence always evaluate the second argument of spin_lock_nested().
An intentional side effect of this patch is that it avoids that the following warning is reported for netif_addr_lock_nested() when building with CONFIG_DEBUG_LOCK_ALLOC=n and with W=1:
include/linux/netdevice.h: In function 'netif_addr_lock_nested':include/linux/netdevice.h:2865:6: warning: variable 'subclass' set but not used [-Wunused-but-set-variable]
int subclass = SINGLE_DEPTH_NESTING;
^--- include/linux/spinlock.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
include/linux/spinlock.h +7 -1
@@ -197,7 +197,13 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)_raw_spin_lock_nest_lock (lock, &(nest_lock)->dep_map); \ } while (0)#else -# define raw_spin_lock_nested (lock, subclass) _raw_spin_lock(lock) +/* +* Always evaluate the 'subclass' argument to avoid that the compiler +* warns about set-but-not-used variables when building with +* CONFIG_DEBUG_LOCK_ALLOC=n and with W=1. +*/ +# define raw_spin_lock_nested (lock, subclass) \ + _raw_spin_lock(((void)(subclass), (lock)))# define raw_spin_lock_nest_lock (lock, nest_lock) _raw_spin_lock(lock)#endif
Signature · 1 line
1.8.4.5
Re: [PATCH v3] spin_lock_nested(): Always evaluate second argument
Quoted 5 lines · Bart Van Assche
include/linux/spinlock.h +0
-0
include/linux/spinlock.h static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) · line 204
Quoted 9 lines
include/linux/spinlock.h +5
-1@@ -197,7 +197,13 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)_raw_spin_lock_nest_lock (lock, &(nest_lock)->dep_map); \ } while (0)#else -# define raw_spin_lock_nested (lock, subclass) _raw_spin_lock(lock) +/* +* Always evaluate the 'subclass' argument to avoid that the compiler +* warns about set-but-not-used variables when building with +* CONFIG_DEBUG_LOCK_ALLOC=n and with W=1. +*/
I was hoping there was going to be a more important reason for this change than to avoid compiler warnings, such as an example where someone is doing spin_lock_nested(lock, subclass) and the expression for "subclass" requires evaluation in all configs.
Quoted 5 lines
include/linux/spinlock.h +2
-0+# define raw_spin_lock_nested (lock, subclass) \ + _raw_spin_lock(((void)(subclass), (lock)))# define raw_spin_lock_nest_lock (lock, nest_lock) _raw_spin_lock(lock)#endif
Peter Zijlstra
maintainerRe: [PATCH v3] spin_lock_nested(): Always evaluate second argument
Quoted 13 lines · David Rientjes
Quoted 11 lines · Bart Van Assche
include/linux/spinlock.h +2
-1@@ -197,7 +197,13 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)_raw_spin_lock_nest_lock (lock, &(nest_lock)->dep_map); \ } while (0)#else -# define raw_spin_lock_nested (lock, subclass) _raw_spin_lock(lock) +/* +* Always evaluate the 'subclass' argument to avoid that the compiler
Quoted 8 lines
include/linux/spinlock.h static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) · line 204
Quoted 3 lines
include/linux/spinlock.h +3
-0+* warns about set-but-not-used variables when building with +* CONFIG_DEBUG_LOCK_ALLOC=n and with W=1. +*/ I was hoping there was going to be a more important reason for this change than to avoid compiler warnings, such as an example where someone is doing
spin_lock_nested(lock, subclass)and the expression for "subclass" requires evaluation in all configs.
That would stink, having that argument have side effects. I'd call that a plain old bug that needs fixing.
tip-bot for Bart Van Assche
merge bot[tip:locking/core] locking/spinlocks: Always evaluate the second argument of spin_lock_nested()
In reply to Bart Van Asschelocking/spinlocks: Always evaluate the second argument of spin_lock_nested()
Commit-ID: 4999201a59ef555f9105d2bb2459ed895627f7aa Gitweb: http://git.kernel.org/tip/4999201a59ef555f9105d2bb2459ed895627f7aa Author: Bart Van Assche <[email protected]> AuthorDate: Fri, 8 Aug 2014 12:35:36 +0200 Committer: Ingo Molnar <[email protected]> CommitDate: Wed, 13 Aug 2014 10:32:38 +0200
locking/spinlocks: Always evaluate the second argument of spin_lock_nested()
Evaluating a macro argument only if certain configuration options have been selected is confusing and error-prone. Hence always evaluate the second argument of spin_lock_nested().
An intentional side effect of this patch is that it avoids that the following warning is reported for netif_addr_lock_nested() when building with CONFIG_DEBUG_LOCK_ALLOC=n and with W=1:
include/linux/netdevice.h: In function 'netif_addr_lock_nested':
include/linux/netdevice.h:2865:6: warning: variable 'subclass' set but not used [-Wunused-but-set-variable]
int subclass = SINGLE_DEPTH_NESTING;
^--- include/linux/spinlock.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
include/linux/spinlock.h +7 -1
@@ -197,7 +197,13 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock)_raw_spin_lock_nest_lock (lock, &(nest_lock)->dep_map); \ } while (0)#else -# define raw_spin_lock_nested (lock, subclass) _raw_spin_lock(lock) +/* +* Always evaluate the 'subclass' argument to avoid that the compiler +* warns about set-but-not-used variables when building with +* CONFIG_DEBUG_LOCK_ALLOC=n and with W=1. +*/ +# define raw_spin_lock_nested (lock, subclass) \ + _raw_spin_lock(((void)(subclass), (lock)))# define raw_spin_lock_nest_lock (lock, nest_lock) _raw_spin_lock(lock)#endif