[PATCH v3] locking/local_lock: s/l/__l/ and s/tl/__tl/ to reduce risk of shadowing

Sebastian Andrzej Siewior posted 1 patch 2 months, 1 week ago
include/linux/local_lock_internal.h | 62 ++++++++++++++---------------
1 file changed, 31 insertions(+), 31 deletions(-)
[PATCH v3] locking/local_lock: s/l/__l/ and s/tl/__tl/ to reduce risk of shadowing
Posted by Sebastian Andrzej Siewior 2 months, 1 week ago
From: Vincent Mailhol <mailhol@kernel.org>

The Linux kernel coding style advises to avoid common variable
names in function-like macros to reduce the risk of collisions.

Throughout local_lock_internal.h, several macros use the rather common
variable names 'l' and 'tl'. This already resulted in an actual
collision: the __local_lock_acquire() function like macro is currently
shadowing the parameter 'l' of the:

  class_##_name##_t class_##_name##_constructor(_type *l)

function factory from linux/cleanup.h.

Rename the variable 'l' to '__l' and the variable 'tl' to '__tl'
throughout the file to fix the current name collision and to prevent
future ones.

[ bigeasy: Rebase, update all l and tl instances in macros ]

Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---

Looks harmless enough to make everyone happy.

v2…v3: 
  - Rebase

v1…v2: https://lore.kernel.org/all/20250925-local_lock_internal_fix_shadow-v2-1-d3b85ee775a4@kernel.org/

  - __lock conflicted with an existing definition in lockdep.c. Use
    instead __l (and also, to keep things consistent, use __tl instead
    of tl for the trylock).

  - Apply the renaming to the entire file and not just to
    __local_lock_acquire().

  - Rewrite the patch description accordingly.

v1: https://lore.kernel.org/r/20250923-local_lock_internal_fix_shadow-v1-1-14e313c88a46@kernel.org

 include/linux/local_lock_internal.h | 62 ++++++++++++++---------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/include/linux/local_lock_internal.h b/include/linux/local_lock_internal.h
index a4dc479157b5c..8f82b4eb542f2 100644
--- a/include/linux/local_lock_internal.h
+++ b/include/linux/local_lock_internal.h
@@ -99,18 +99,18 @@ do {								\
 
 #define __local_lock_acquire(lock)					\
 	do {								\
-		local_trylock_t *tl;					\
-		local_lock_t *l;					\
+		local_trylock_t *__tl;					\
+		local_lock_t *__l;					\
 									\
-		l = (local_lock_t *)(lock);				\
-		tl = (local_trylock_t *)l;				\
+		__l = (local_lock_t *)(lock);				\
+		__tl = (local_trylock_t *)__l;				\
 		_Generic((lock),					\
 			local_trylock_t *: ({				\
-				lockdep_assert(tl->acquired == 0);	\
-				WRITE_ONCE(tl->acquired, 1);		\
+				lockdep_assert(__tl->acquired == 0);	\
+				WRITE_ONCE(__tl->acquired, 1);		\
 			}),						\
 			local_lock_t *: (void)0);			\
-		local_lock_acquire(l);					\
+		local_lock_acquire(__l);				\
 	} while (0)
 
 #define __local_lock(lock)					\
@@ -133,36 +133,36 @@ do {								\
 
 #define __local_trylock(lock)					\
 	({							\
-		local_trylock_t *tl;				\
+		local_trylock_t *__tl;				\
 								\
 		preempt_disable();				\
-		tl = (lock);					\
-		if (READ_ONCE(tl->acquired)) {			\
+		__tl = (lock);					\
+		if (READ_ONCE(__tl->acquired)) {		\
 			preempt_enable();			\
-			tl = NULL;				\
+			__tl = NULL;				\
 		} else {					\
-			WRITE_ONCE(tl->acquired, 1);		\
+			WRITE_ONCE(__tl->acquired, 1);		\
 			local_trylock_acquire(			\
-				(local_lock_t *)tl);		\
+				(local_lock_t *)__tl);		\
 		}						\
-		!!tl;						\
+		!!__tl;						\
 	})
 
 #define __local_trylock_irqsave(lock, flags)			\
 	({							\
-		local_trylock_t *tl;				\
+		local_trylock_t *__tl;				\
 								\
 		local_irq_save(flags);				\
-		tl = (lock);					\
-		if (READ_ONCE(tl->acquired)) {			\
+		__tl = (lock);					\
+		if (READ_ONCE(__tl->acquired)) {		\
 			local_irq_restore(flags);		\
-			tl = NULL;				\
+			__tl = NULL;				\
 		} else {					\
-			WRITE_ONCE(tl->acquired, 1);		\
+			WRITE_ONCE(__tl->acquired, 1);		\
 			local_trylock_acquire(			\
-				(local_lock_t *)tl);		\
+				(local_lock_t *)__tl);		\
 		}						\
-		!!tl;						\
+		!!__tl;						\
 	})
 
 /* preemption or migration must be disabled before calling __local_lock_is_locked */
@@ -170,16 +170,16 @@ do {								\
 
 #define __local_lock_release(lock)					\
 	do {								\
-		local_trylock_t *tl;					\
-		local_lock_t *l;					\
+		local_trylock_t *__tl;					\
+		local_lock_t *__l;					\
 									\
-		l = (local_lock_t *)(lock);				\
-		tl = (local_trylock_t *)l;				\
-		local_lock_release(l);					\
+		__l = (local_lock_t *)(lock);				\
+		__tl = (local_trylock_t *)__l;				\
+		local_lock_release(__l);				\
 		_Generic((lock),					\
 			local_trylock_t *: ({				\
-				lockdep_assert(tl->acquired == 1);	\
-				WRITE_ONCE(tl->acquired, 0);		\
+				lockdep_assert(__tl->acquired == 1);	\
+				WRITE_ONCE(__tl->acquired, 0);		\
 			}),						\
 			local_lock_t *: (void)0);			\
 	} while (0)
@@ -223,12 +223,12 @@ typedef spinlock_t local_trylock_t;
 #define INIT_LOCAL_LOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
 #define INIT_LOCAL_TRYLOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
 
-#define __local_lock_init(l)					\
+#define __local_lock_init(__l)					\
 	do {							\
-		local_spin_lock_init((l));			\
+		local_spin_lock_init((__l));			\
 	} while (0)
 
-#define __local_trylock_init(l)			__local_lock_init(l)
+#define __local_trylock_init(__l)			__local_lock_init(__l)
 
 #define __local_lock(__lock)					\
 	do {							\
-- 
2.51.0
Re: [PATCH v3] locking/local_lock: s/l/__l/ and s/tl/__tl/ to reduce risk of shadowing
Posted by Waiman Long 3 weeks, 1 day ago
On 10/9/25 6:39 AM, Sebastian Andrzej Siewior wrote:
> From: Vincent Mailhol <mailhol@kernel.org>
>
> The Linux kernel coding style advises to avoid common variable
> names in function-like macros to reduce the risk of collisions.
>
> Throughout local_lock_internal.h, several macros use the rather common
> variable names 'l' and 'tl'. This already resulted in an actual
> collision: the __local_lock_acquire() function like macro is currently
> shadowing the parameter 'l' of the:
>
>    class_##_name##_t class_##_name##_constructor(_type *l)
>
> function factory from linux/cleanup.h.
>
> Rename the variable 'l' to '__l' and the variable 'tl' to '__tl'
> throughout the file to fix the current name collision and to prevent
> future ones.
>
> [ bigeasy: Rebase, update all l and tl instances in macros ]
>
> Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> ---
>
> Looks harmless enough to make everyone happy.
>
> v2…v3:
>    - Rebase
>
> v1…v2: https://lore.kernel.org/all/20250925-local_lock_internal_fix_shadow-v2-1-d3b85ee775a4@kernel.org/
>
>    - __lock conflicted with an existing definition in lockdep.c. Use
>      instead __l (and also, to keep things consistent, use __tl instead
>      of tl for the trylock).
>
>    - Apply the renaming to the entire file and not just to
>      __local_lock_acquire().
>
>    - Rewrite the patch description accordingly.
>
> v1: https://lore.kernel.org/r/20250923-local_lock_internal_fix_shadow-v1-1-14e313c88a46@kernel.org
>
>   include/linux/local_lock_internal.h | 62 ++++++++++++++---------------
>   1 file changed, 31 insertions(+), 31 deletions(-)
>
> diff --git a/include/linux/local_lock_internal.h b/include/linux/local_lock_internal.h
> index a4dc479157b5c..8f82b4eb542f2 100644
> --- a/include/linux/local_lock_internal.h
> +++ b/include/linux/local_lock_internal.h
> @@ -99,18 +99,18 @@ do {								\
>   
>   #define __local_lock_acquire(lock)					\
>   	do {								\
> -		local_trylock_t *tl;					\
> -		local_lock_t *l;					\
> +		local_trylock_t *__tl;					\
> +		local_lock_t *__l;					\
>   									\
> -		l = (local_lock_t *)(lock);				\
> -		tl = (local_trylock_t *)l;				\
> +		__l = (local_lock_t *)(lock);				\
> +		__tl = (local_trylock_t *)__l;				\
>   		_Generic((lock),					\
>   			local_trylock_t *: ({				\
> -				lockdep_assert(tl->acquired == 0);	\
> -				WRITE_ONCE(tl->acquired, 1);		\
> +				lockdep_assert(__tl->acquired == 0);	\
> +				WRITE_ONCE(__tl->acquired, 1);		\
>   			}),						\
>   			local_lock_t *: (void)0);			\
> -		local_lock_acquire(l);					\
> +		local_lock_acquire(__l);				\
>   	} while (0)
>   
>   #define __local_lock(lock)					\
> @@ -133,36 +133,36 @@ do {								\
>   
>   #define __local_trylock(lock)					\
>   	({							\
> -		local_trylock_t *tl;				\
> +		local_trylock_t *__tl;				\
>   								\
>   		preempt_disable();				\
> -		tl = (lock);					\
> -		if (READ_ONCE(tl->acquired)) {			\
> +		__tl = (lock);					\
> +		if (READ_ONCE(__tl->acquired)) {		\
>   			preempt_enable();			\
> -			tl = NULL;				\
> +			__tl = NULL;				\
>   		} else {					\
> -			WRITE_ONCE(tl->acquired, 1);		\
> +			WRITE_ONCE(__tl->acquired, 1);		\
>   			local_trylock_acquire(			\
> -				(local_lock_t *)tl);		\
> +				(local_lock_t *)__tl);		\
>   		}						\
> -		!!tl;						\
> +		!!__tl;						\
>   	})
>   
>   #define __local_trylock_irqsave(lock, flags)			\
>   	({							\
> -		local_trylock_t *tl;				\
> +		local_trylock_t *__tl;				\
>   								\
>   		local_irq_save(flags);				\
> -		tl = (lock);					\
> -		if (READ_ONCE(tl->acquired)) {			\
> +		__tl = (lock);					\
> +		if (READ_ONCE(__tl->acquired)) {		\
>   			local_irq_restore(flags);		\
> -			tl = NULL;				\
> +			__tl = NULL;				\
>   		} else {					\
> -			WRITE_ONCE(tl->acquired, 1);		\
> +			WRITE_ONCE(__tl->acquired, 1);		\
>   			local_trylock_acquire(			\
> -				(local_lock_t *)tl);		\
> +				(local_lock_t *)__tl);		\
>   		}						\
> -		!!tl;						\
> +		!!__tl;						\
>   	})
>   
>   /* preemption or migration must be disabled before calling __local_lock_is_locked */
> @@ -170,16 +170,16 @@ do {								\
>   
>   #define __local_lock_release(lock)					\
>   	do {								\
> -		local_trylock_t *tl;					\
> -		local_lock_t *l;					\
> +		local_trylock_t *__tl;					\
> +		local_lock_t *__l;					\
>   									\
> -		l = (local_lock_t *)(lock);				\
> -		tl = (local_trylock_t *)l;				\
> -		local_lock_release(l);					\
> +		__l = (local_lock_t *)(lock);				\
> +		__tl = (local_trylock_t *)__l;				\
> +		local_lock_release(__l);				\
>   		_Generic((lock),					\
>   			local_trylock_t *: ({				\
> -				lockdep_assert(tl->acquired == 1);	\
> -				WRITE_ONCE(tl->acquired, 0);		\
> +				lockdep_assert(__tl->acquired == 1);	\
> +				WRITE_ONCE(__tl->acquired, 0);		\
>   			}),						\
>   			local_lock_t *: (void)0);			\
>   	} while (0)
> @@ -223,12 +223,12 @@ typedef spinlock_t local_trylock_t;
>   #define INIT_LOCAL_LOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
>   #define INIT_LOCAL_TRYLOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
>   
> -#define __local_lock_init(l)					\
> +#define __local_lock_init(__l)					\
>   	do {							\
> -		local_spin_lock_init((l));			\
> +		local_spin_lock_init((__l));			\
>   	} while (0)
>   
> -#define __local_trylock_init(l)			__local_lock_init(l)
> +#define __local_trylock_init(__l)			__local_lock_init(__l)
>   
>   #define __local_lock(__lock)					\
>   	do {							\

Make sense.

Acked-by: Waiman Long <longman@redhat.com>

Re: [PATCH v3] locking/local_lock: s/l/__l/ and s/tl/__tl/ to reduce risk of shadowing
Posted by Vincent Mailhol 2 months, 1 week ago
Hi Sebastian,

Thanks for the rebase and for this v3.

On 09/10/2025 at 19:39, Sebastian Andrzej Siewior wrote:

(...)

> @@ -223,12 +223,12 @@ typedef spinlock_t local_trylock_t;
>  #define INIT_LOCAL_LOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
>  #define INIT_LOCAL_TRYLOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
>  
> -#define __local_lock_init(l)					\
> +#define __local_lock_init(__l)					\
>  	do {							\
> -		local_spin_lock_init((l));			\
> +		local_spin_lock_init((__l));			\
>  	} while (0)
>  
> -#define __local_trylock_init(l)			__local_lock_init(l)
> +#define __local_trylock_init(__l)			__local_lock_init(__l)
>  
>  #define __local_lock(__lock)					\
>  	do {							\

The parameters of a function like macro can not shadow existing
symbols because, when invoked, these parameters would be substituted
during the macro expansion by the actual arguments. Only the local
variables declared in the macro would survive after the preprocessor
and thus only those may cause shadowing.

So this last part of the patch is not needed.


Yours sincerely,
Vincent Mailhol
Re: [PATCH v3] locking/local_lock: s/l/__l/ and s/tl/__tl/ to reduce risk of shadowing
Posted by Sebastian Andrzej Siewior 2 months, 1 week ago
On 2025-10-09 21:39:07 [+0900], Vincent Mailhol wrote:
> Hi Sebastian,
Hi Vincent,

> On 09/10/2025 at 19:39, Sebastian Andrzej Siewior wrote:
> 
> (...)
> 
> > @@ -223,12 +223,12 @@ typedef spinlock_t local_trylock_t;
> >  #define INIT_LOCAL_LOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
> >  #define INIT_LOCAL_TRYLOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
> >  
> > -#define __local_lock_init(l)					\
> > +#define __local_lock_init(__l)					\
> >  	do {							\
> > -		local_spin_lock_init((l));			\
> > +		local_spin_lock_init((__l));			\
> >  	} while (0)
> >  
> > -#define __local_trylock_init(l)			__local_lock_init(l)
> > +#define __local_trylock_init(__l)			__local_lock_init(__l)
> >  
> >  #define __local_lock(__lock)					\
> >  	do {							\
> 
> The parameters of a function like macro can not shadow existing
> symbols because, when invoked, these parameters would be substituted
> during the macro expansion by the actual arguments. Only the local
> variables declared in the macro would survive after the preprocessor
> and thus only those may cause shadowing.
> 
> So this last part of the patch is not needed.

Right, but then we have the same __l variable in the whole file. Isn't
this worth something?

> Yours sincerely,
> Vincent Mailhol

Sebastian
Re: [PATCH v3] locking/local_lock: s/l/__l/ and s/tl/__tl/ to reduce risk of shadowing
Posted by Vincent Mailhol 2 months, 1 week ago
On 09/10/2025 at 21:43, Sebastian Andrzej Siewior wrote:
> On 2025-10-09 21:39:07 [+0900], Vincent Mailhol wrote:
>> Hi Sebastian,
> Hi Vincent,
> 
>> On 09/10/2025 at 19:39, Sebastian Andrzej Siewior wrote:
>>
>> (...)
>>
>>> @@ -223,12 +223,12 @@ typedef spinlock_t local_trylock_t;
>>>  #define INIT_LOCAL_LOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
>>>  #define INIT_LOCAL_TRYLOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
>>>  
>>> -#define __local_lock_init(l)					\
>>> +#define __local_lock_init(__l)					\
>>>  	do {							\
>>> -		local_spin_lock_init((l));			\
>>> +		local_spin_lock_init((__l));			\
>>>  	} while (0)
>>>  
>>> -#define __local_trylock_init(l)			__local_lock_init(l)
>>> +#define __local_trylock_init(__l)			__local_lock_init(__l)
>>>  
>>>  #define __local_lock(__lock)					\
>>>  	do {							\
>>
>> The parameters of a function like macro can not shadow existing
>> symbols because, when invoked, these parameters would be substituted
>> during the macro expansion by the actual arguments. Only the local
>> variables declared in the macro would survive after the preprocessor
>> and thus only those may cause shadowing.
>>
>> So this last part of the patch is not needed.
> 
> Right, but then we have the same __l variable in the whole file. Isn't
> this worth something?

What I really wanted to point out is that this is not needed in
regards to the shadowing problem. So this part feels a bit out of
scope of what the patch is trying to achieve.

That said, if you as a maintainer think that it is better to add this
for the global harmony of the file, then I am OK. I wouldn't do that
in a file which I maintain, but the maintainer here is you, not me. It
make sense that you do it your preferred way.

In other words, if you like it this way, keep the patch as is :)


Yours sincerely,
Vincent Mailhol
Re: [PATCH v3] locking/local_lock: s/l/__l/ and s/tl/__tl/ to reduce risk of shadowing
Posted by Vincent Mailhol 3 weeks, 1 day ago
Hi Sebastian,

On Thu. 9 Oct. 2025 at 15:08, Vincent Mailhol <mailhol@kernel.org> wrote:
> On 09/10/2025 at 21:43, Sebastian Andrzej Siewior wrote:
> > On 2025-10-09 21:39:07 [+0900], Vincent Mailhol wrote:
> >> Hi Sebastian,
> > Hi Vincent,
> >
> >> On 09/10/2025 at 19:39, Sebastian Andrzej Siewior wrote:
> >>
> >> (...)
> >>
> >>> @@ -223,12 +223,12 @@ typedef spinlock_t local_trylock_t;
> >>>  #define INIT_LOCAL_LOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
> >>>  #define INIT_LOCAL_TRYLOCK(lockname) __LOCAL_SPIN_LOCK_UNLOCKED((lockname))
> >>>
> >>> -#define __local_lock_init(l)                                       \
> >>> +#define __local_lock_init(__l)                                     \
> >>>     do {                                                    \
> >>> -           local_spin_lock_init((l));                      \
> >>> +           local_spin_lock_init((__l));                    \
> >>>     } while (0)
> >>>
> >>> -#define __local_trylock_init(l)                    __local_lock_init(l)
> >>> +#define __local_trylock_init(__l)                  __local_lock_init(__l)
> >>>
> >>>  #define __local_lock(__lock)                                       \
> >>>     do {                                                    \
> >>
> >> The parameters of a function like macro can not shadow existing
> >> symbols because, when invoked, these parameters would be substituted
> >> during the macro expansion by the actual arguments. Only the local
> >> variables declared in the macro would survive after the preprocessor
> >> and thus only those may cause shadowing.
> >>
> >> So this last part of the patch is not needed.
> >
> > Right, but then we have the same __l variable in the whole file. Isn't
> > this worth something?
>
> What I really wanted to point out is that this is not needed in
> regards to the shadowing problem. So this part feels a bit out of
> scope of what the patch is trying to achieve.
>
> That said, if you as a maintainer think that it is better to add this
> for the global harmony of the file, then I am OK. I wouldn't do that
> in a file which I maintain, but the maintainer here is you, not me. It
> make sense that you do it your preferred way.
>
> In other words, if you like it this way, keep the patch as is :)

I just wanted to check if everything was OK with that patch. I am
asking because I did not find it in linux-next.


Yours sincerely,
Vincent Mailhol