Fix the following spam coming from <net/netdev_queues.h> when building
with W=12 and/or C=1:
Clang:
drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:9: warning: declaration shadows a local variable [-Wshadow]
1992 | return netif_txq_maybe_stop(nq, IDPF_DESC_UNUSED(tx_q), size, size);
| ^
./include/net/netdev_queues.h:137:11: note: expanded from macro 'netif_txq_maybe_stop'
137 | _res = netif_txq_try_stop(txq, get_desc, start_thrs); \
| ^
./include/net/netdev_queues.h:92:7: note: expanded from macro 'netif_txq_try_stop'
92 | int _res; \
| ^
drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:9: note: previous declaration is here
./include/net/netdev_queues.h:133:7: note: expanded from macro 'netif_txq_maybe_stop'
133 | int _res; \
| ^
Sparse:
drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:16: warning: symbol '_res' shadows an earlier one
drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:16: originally declared here
Use __UNIQUE_ID() in all of the macros which declare local variables.
Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
---
include/net/netdev_queues.h | 54 +++++++++++++++++++++++++++----------
1 file changed, 40 insertions(+), 14 deletions(-)
diff --git a/include/net/netdev_queues.h b/include/net/netdev_queues.h
index 1ec408585373..317d6bfe32c7 100644
--- a/include/net/netdev_queues.h
+++ b/include/net/netdev_queues.h
@@ -87,14 +87,14 @@ struct netdev_stat_ops {
* be updated before invoking the macros.
*/
-#define netif_txq_try_stop(txq, get_desc, start_thrs) \
+#define _netif_txq_try_stop(txq, get_desc, start_thrs, _res) \
({ \
int _res; \
\
netif_tx_stop_queue(txq); \
/* Producer index and stop bit must be visible \
* to consumer before we recheck. \
- * Pairs with a barrier in __netif_txq_completed_wake(). \
+ * Pairs with a barrier in ___netif_txq_completed_wake(). \
*/ \
smp_mb__after_atomic(); \
\
@@ -107,16 +107,20 @@ struct netdev_stat_ops {
_res = -1; \
} \
_res; \
- }) \
+ })
+#define netif_txq_try_stop(txq, get_desc, start_thrs) \
+ _netif_txq_try_stop(txq, get_desc, start_thrs, \
+ __UNIQUE_ID(res_))
/**
- * netif_txq_maybe_stop() - locklessly stop a Tx queue, if needed
+ * _netif_txq_maybe_stop() - locklessly stop a Tx queue, if needed
* @txq: struct netdev_queue to stop/start
* @get_desc: get current number of free descriptors (see requirements below!)
* @stop_thrs: minimal number of available descriptors for queue to be left
* enabled
* @start_thrs: minimal number of descriptors to re-enable the queue, can be
* equal to @stop_thrs or higher to avoid frequent waking
+ * @_res: __UNIQUE_ID() to avoid variable name clash
*
* All arguments may be evaluated multiple times, beware of side effects.
* @get_desc must be a formula or a function call, it must always
@@ -128,7 +132,8 @@ struct netdev_stat_ops {
* 1 if the queue was left enabled
* -1 if the queue was re-enabled (raced with waking)
*/
-#define netif_txq_maybe_stop(txq, get_desc, stop_thrs, start_thrs) \
+#define _netif_txq_maybe_stop(txq, get_desc, stop_thrs, start_thrs, \
+ _res) \
({ \
int _res; \
\
@@ -136,7 +141,10 @@ struct netdev_stat_ops {
if (unlikely(get_desc < stop_thrs)) \
_res = netif_txq_try_stop(txq, get_desc, start_thrs); \
_res; \
- }) \
+ })
+#define netif_txq_maybe_stop(txq, get_desc, stop_thrs, start_thrs) \
+ _netif_txq_maybe_stop(txq, get_desc, stop_thrs, start_thrs, \
+ __UNIQUE_ID(res_))
/* Variant of netdev_tx_completed_queue() which guarantees smp_mb() if
* @bytes != 0, regardless of kernel config.
@@ -152,7 +160,7 @@ netdev_txq_completed_mb(struct netdev_queue *dev_queue,
}
/**
- * __netif_txq_completed_wake() - locklessly wake a Tx queue, if needed
+ * ___netif_txq_completed_wake() - locklessly wake a Tx queue, if needed
* @txq: struct netdev_queue to stop/start
* @pkts: number of packets completed
* @bytes: number of bytes completed
@@ -160,6 +168,7 @@ netdev_txq_completed_mb(struct netdev_queue *dev_queue,
* @start_thrs: minimal number of descriptors to re-enable the queue
* @down_cond: down condition, predicate indicating that the queue should
* not be woken up even if descriptors are available
+ * @_res: __UNIQUE_ID() to avoid variable name clash
*
* All arguments may be evaluated multiple times.
* @get_desc must be a formula or a function call, it must always
@@ -171,15 +180,15 @@ netdev_txq_completed_mb(struct netdev_queue *dev_queue,
* 1 if the queue was already enabled (or disabled but @down_cond is true)
* -1 if the queue was left unchanged (@start_thrs not reached)
*/
-#define __netif_txq_completed_wake(txq, pkts, bytes, \
- get_desc, start_thrs, down_cond) \
+#define ___netif_txq_completed_wake(txq, pkts, bytes, get_desc, \
+ start_thrs, down_cond, _res) \
({ \
int _res; \
\
/* Report to BQL and piggy back on its barrier. \
* Barrier makes sure that anybody stopping the queue \
* after this point sees the new consumer index. \
- * Pairs with barrier in netif_txq_try_stop(). \
+ * Pairs with barrier in _netif_txq_try_stop(). \
*/ \
netdev_txq_completed_mb(txq, pkts, bytes); \
\
@@ -194,30 +203,43 @@ netdev_txq_completed_mb(struct netdev_queue *dev_queue,
} \
_res; \
})
+#define __netif_txq_completed_wake(txq, pkts, bytes, get_desc, \
+ start_thrs, down_cond) \
+ ___netif_txq_completed_wake(txq, pkts, bytes, get_desc, \
+ start_thrs, down_cond, \
+ __UNIQUE_ID(res_))
#define netif_txq_completed_wake(txq, pkts, bytes, get_desc, start_thrs) \
__netif_txq_completed_wake(txq, pkts, bytes, get_desc, start_thrs, false)
/* subqueue variants follow */
-#define netif_subqueue_try_stop(dev, idx, get_desc, start_thrs) \
+#define _netif_subqueue_try_stop(dev, idx, get_desc, start_thrs, txq) \
({ \
struct netdev_queue *txq; \
\
txq = netdev_get_tx_queue(dev, idx); \
netif_txq_try_stop(txq, get_desc, start_thrs); \
})
+#define netif_subqueue_try_stop(dev, idx, get_desc, start_thrs) \
+ _netif_subqueue_try_stop(dev, idx, get_desc, start_thrs, \
+ __UNIQUE_ID(txq_))
-#define netif_subqueue_maybe_stop(dev, idx, get_desc, stop_thrs, start_thrs) \
+#define _netif_subqueue_maybe_stop(dev, idx, get_desc, stop_thrs, \
+ start_thrs, txq) \
({ \
struct netdev_queue *txq; \
\
txq = netdev_get_tx_queue(dev, idx); \
netif_txq_maybe_stop(txq, get_desc, stop_thrs, start_thrs); \
})
+#define netif_subqueue_maybe_stop(dev, idx, get_desc, stop_thrs, \
+ start_thrs) \
+ _netif_subqueue_maybe_stop(dev, idx, get_desc, stop_thrs, \
+ start_thrs, __UNIQUE_ID(txq_))
-#define netif_subqueue_completed_wake(dev, idx, pkts, bytes, \
- get_desc, start_thrs) \
+#define _netif_subqueue_completed_wake(dev, idx, pkts, bytes, get_desc, \
+ start_thrs, txq) \
({ \
struct netdev_queue *txq; \
\
@@ -225,5 +247,9 @@ netdev_txq_completed_mb(struct netdev_queue *dev_queue,
netif_txq_completed_wake(txq, pkts, bytes, \
get_desc, start_thrs); \
})
+#define netif_subqueue_completed_wake(dev, idx, pkts, bytes, get_desc, \
+ start_thrs) \
+ _netif_subqueue_completed_wake(dev, idx, pkts, bytes, get_desc, \
+ start_thrs, __UNIQUE_ID(txq_))
#endif
--
2.44.0
On Fri, 29 Mar 2024 18:00:00 +0100 Alexander Lobakin wrote: > drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:9: warning: declaration shadows a local variable [-Wshadow] > 1992 | return netif_txq_maybe_stop(nq, IDPF_DESC_UNUSED(tx_q), size, size); > | ^ > ./include/net/netdev_queues.h:137:11: note: expanded from macro 'netif_txq_maybe_stop' > 137 | _res = netif_txq_try_stop(txq, get_desc, start_thrs); \ > | ^ > ./include/net/netdev_queues.h:92:7: note: expanded from macro 'netif_txq_try_stop' > 92 | int _res; \ > | ^ > drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:9: note: previous declaration is here > ./include/net/netdev_queues.h:133:7: note: expanded from macro 'netif_txq_maybe_stop' > 133 | int _res; \ > | ^ > > Sparse: > > drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:16: warning: symbol '_res' shadows an earlier one > drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:16: originally declared here I don't see these building with LLVM=1 W=12 C=1 and I really don't like complicating the code because the compiler is stupid. Can't you solve this with some renames? Add another underscore or something?
On Fri, 29 Mar 2024 13:18:57 -0700 Jakub Kicinski wrote:
> > Sparse:
> >
> > drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:16: warning: symbol '_res' shadows an earlier one
> > drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:16: originally declared here
>
> I don't see these building with LLVM=1 W=12 C=1
> and I really don't like complicating the code because the compiler
> is stupid. Can't you solve this with some renames? Add another
> underscore or something?
I'm stupid I tried on the test branch which already had your fix..
This is enough:
diff --git a/include/net/netdev_queues.h b/include/net/netdev_queues.h
index 1ec408585373..2270fbb99cf7 100644
--- a/include/net/netdev_queues.h
+++ b/include/net/netdev_queues.h
@@ -89,7 +89,7 @@ struct netdev_stat_ops {
#define netif_txq_try_stop(txq, get_desc, start_thrs) \
({ \
- int _res; \
+ int __res; \
\
netif_tx_stop_queue(txq); \
/* Producer index and stop bit must be visible \
@@ -101,12 +101,12 @@ struct netdev_stat_ops {
/* We need to check again in a case another \
* CPU has just made room available. \
*/ \
- _res = 0; \
+ __res = 0; \
if (unlikely(get_desc >= start_thrs)) { \
netif_tx_start_queue(txq); \
- _res = -1; \
+ __res = -1; \
} \
- _res; \
+ __res; \
}) \
/**
From: Jakub Kicinski <kuba@kernel.org>
Date: Fri, 29 Mar 2024 13:53:44 -0700
> On Fri, 29 Mar 2024 13:18:57 -0700 Jakub Kicinski wrote:
>>> Sparse:
>>>
>>> drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:16: warning: symbol '_res' shadows an earlier one
>>> drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:16: originally declared here
>>
>> I don't see these building with LLVM=1 W=12 C=1
>> and I really don't like complicating the code because the compiler
>> is stupid. Can't you solve this with some renames? Add another
It's not the compiler, its warnings are valid actually. Shadowing makes
it very easy to confuse variables and make bugs...
>> underscore or something?
>
> I'm stupid I tried on the test branch which already had your fix..
:D Sometimes it happens.
>
> This is enough:
>
> diff --git a/include/net/netdev_queues.h b/include/net/netdev_queues.h
> index 1ec408585373..2270fbb99cf7 100644
> --- a/include/net/netdev_queues.h
> +++ b/include/net/netdev_queues.h
> @@ -89,7 +89,7 @@ struct netdev_stat_ops {
>
> #define netif_txq_try_stop(txq, get_desc, start_thrs) \
> ({ \
> - int _res; \
> + int __res; \
> \
> netif_tx_stop_queue(txq); \
> /* Producer index and stop bit must be visible \
> @@ -101,12 +101,12 @@ struct netdev_stat_ops {
> /* We need to check again in a case another \
> * CPU has just made room available. \
> */ \
> - _res = 0; \
> + __res = 0; \
> if (unlikely(get_desc >= start_thrs)) { \
> netif_tx_start_queue(txq); \
> - _res = -1; \
> + __res = -1; \
> } \
> - _res; \
> + __res; \
> }) \
>
> /**
But what if there's a function which calls one of these functions and
already has _res or __res or something? I know renaming is enough for
the warnings I mentioned, but without __UNIQUE_ID() anything can happen
anytime, so I wanted to fix that once and for all :z
I already saw some macros which have a layer of indirection for
__UNIQUE_ID(), but previously they didn't and then there were fixes
which added underscores, renamed variables etc etc...
Thanks,
Olek
On Tue, Apr 2, 2024 at 1:55 PM Alexander Lobakin
<aleksander.lobakin@intel.com> wrote:
>
> From: Jakub Kicinski <kuba@kernel.org>
> Date: Fri, 29 Mar 2024 13:53:44 -0700
>
> > On Fri, 29 Mar 2024 13:18:57 -0700 Jakub Kicinski wrote:
> >>> Sparse:
> >>>
> >>> drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:16: warning: symbol '_res' shadows an earlier one
> >>> drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:16: originally declared here
> >>
> >> I don't see these building with LLVM=1 W=12 C=1
> >> and I really don't like complicating the code because the compiler
> >> is stupid. Can't you solve this with some renames? Add another
>
> It's not the compiler, its warnings are valid actually. Shadowing makes
> it very easy to confuse variables and make bugs...
>
> >> underscore or something?
> >
> > I'm stupid I tried on the test branch which already had your fix..
>
> :D Sometimes it happens.
>
> >
> > This is enough:
> >
> > diff --git a/include/net/netdev_queues.h b/include/net/netdev_queues.h
> > index 1ec408585373..2270fbb99cf7 100644
> > --- a/include/net/netdev_queues.h
> > +++ b/include/net/netdev_queues.h
> > @@ -89,7 +89,7 @@ struct netdev_stat_ops {
> >
> > #define netif_txq_try_stop(txq, get_desc, start_thrs) \
> > ({ \
> > - int _res; \
> > + int __res; \
> > \
> > netif_tx_stop_queue(txq); \
> > /* Producer index and stop bit must be visible \
> > @@ -101,12 +101,12 @@ struct netdev_stat_ops {
> > /* We need to check again in a case another \
> > * CPU has just made room available. \
> > */ \
> > - _res = 0; \
> > + __res = 0; \
> > if (unlikely(get_desc >= start_thrs)) { \
> > netif_tx_start_queue(txq); \
> > - _res = -1; \
> > + __res = -1; \
> > } \
> > - _res; \
> > + __res; \
> > }) \
> >
> > /**
>
> But what if there's a function which calls one of these functions and
> already has _res or __res or something? I know renaming is enough for
> the warnings I mentioned, but without __UNIQUE_ID() anything can happen
> anytime, so I wanted to fix that once and for all :z
>
> I already saw some macros which have a layer of indirection for
> __UNIQUE_ID(), but previously they didn't and then there were fixes
> which added underscores, renamed variables etc etc...
>
We have hundreds of macros in include/ directory which use local names without
__UNIQUE_ID()
What is the plan ? Hundreds of patches obfuscating them more than they are ?
Can you show us how rb_entry_safe() (random choice) would be rewritten ?
From: Eric Dumazet <edumazet@google.com>
Date: Tue, 2 Apr 2024 14:45:07 +0200
> On Tue, Apr 2, 2024 at 1:55 PM Alexander Lobakin
> <aleksander.lobakin@intel.com> wrote:
>>
>> From: Jakub Kicinski <kuba@kernel.org>
>> Date: Fri, 29 Mar 2024 13:53:44 -0700
>>
>>> On Fri, 29 Mar 2024 13:18:57 -0700 Jakub Kicinski wrote:
>>>>> Sparse:
>>>>>
>>>>> drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:16: warning: symbol '_res' shadows an earlier one
>>>>> drivers/net/ethernet/intel/idpf/idpf_txrx.c:1992:16: originally declared here
>>>>
>>>> I don't see these building with LLVM=1 W=12 C=1
>>>> and I really don't like complicating the code because the compiler
>>>> is stupid. Can't you solve this with some renames? Add another
>>
>> It's not the compiler, its warnings are valid actually. Shadowing makes
>> it very easy to confuse variables and make bugs...
>>
>>>> underscore or something?
>>>
>>> I'm stupid I tried on the test branch which already had your fix..
>>
>> :D Sometimes it happens.
>>
>>>
>>> This is enough:
>>>
>>> diff --git a/include/net/netdev_queues.h b/include/net/netdev_queues.h
>>> index 1ec408585373..2270fbb99cf7 100644
>>> --- a/include/net/netdev_queues.h
>>> +++ b/include/net/netdev_queues.h
>>> @@ -89,7 +89,7 @@ struct netdev_stat_ops {
>>>
>>> #define netif_txq_try_stop(txq, get_desc, start_thrs) \
>>> ({ \
>>> - int _res; \
>>> + int __res; \
>>> \
>>> netif_tx_stop_queue(txq); \
>>> /* Producer index and stop bit must be visible \
>>> @@ -101,12 +101,12 @@ struct netdev_stat_ops {
>>> /* We need to check again in a case another \
>>> * CPU has just made room available. \
>>> */ \
>>> - _res = 0; \
>>> + __res = 0; \
>>> if (unlikely(get_desc >= start_thrs)) { \
>>> netif_tx_start_queue(txq); \
>>> - _res = -1; \
>>> + __res = -1; \
>>> } \
>>> - _res; \
>>> + __res; \
>>> }) \
>>>
>>> /**
>>
>> But what if there's a function which calls one of these functions and
>> already has _res or __res or something? I know renaming is enough for
>> the warnings I mentioned, but without __UNIQUE_ID() anything can happen
>> anytime, so I wanted to fix that once and for all :z
>>
>> I already saw some macros which have a layer of indirection for
>> __UNIQUE_ID(), but previously they didn't and then there were fixes
>> which added underscores, renamed variables etc etc...
>>
>
> We have hundreds of macros in include/ directory which use local names without
> __UNIQUE_ID()
Most of them were added before __UNIQUE_ID() became norm, weren't they?
Lots of them were switched to __UNIQUE_ID() because of issues, weren't they?
>
> What is the plan ? Hundreds of patches obfuscating them more than they are ?
Only those which flood the console when building with W=12 C=1 to
recheck that my new code is fine.
>
> Can you show us how rb_entry_safe() (random choice) would be rewritten ?
Is it unique in some way?
#define _rb_entry_safe(ptr, type, member, ____ptr) \
({ typeof(ptr) ____ptr = (ptr); \
____ptr ? rb_entry(____ptr, type, member) : NULL; \
})
#define rb_entry_safe(ptr, type, member) \
_rb_entry_safe(ptr, type, member, \
__UNIQUE_ID(ptr_)
(@____ptr can be renamed if needed, this one would give the smallest
code diff)
If you think +1 layer is a terrible obfuscating, look at
<linux/fortify-string.h> :D
Thanks,
Olek
On Tue, 2 Apr 2024 17:53:08 +0200 Alexander Lobakin wrote: > >> But what if there's a function which calls one of these functions and > >> already has _res or __res or something? I know renaming is enough for > >> the warnings I mentioned, but without __UNIQUE_ID() anything can happen > >> anytime, so I wanted to fix that once and for all :z > >> > >> I already saw some macros which have a layer of indirection for > >> __UNIQUE_ID(), but previously they didn't and then there were fixes > >> which added underscores, renamed variables etc etc... > >> > > > > We have hundreds of macros in include/ directory which use local names without > > __UNIQUE_ID() > > Most of them were added before __UNIQUE_ID() became norm, weren't they? > Lots of them were switched to __UNIQUE_ID() because of issues, weren't they? Lots of ugly code gets into the kernel. Just look at your patch and then look at mine. I understand __UNIQUE_ID() may be useful for libraries or global macros in the kernel, but within a subsystem, for macros which are rarely used, we can just patch the macro var names. Sprinkling __UNIQUE_ID() is in bad taste. > > What is the plan ? Hundreds of patches obfuscating them more than they are ? > > Only those which flood the console when building with W=12 C=1 to > recheck that my new code is fine. I have never seen this warning be useful in the context of a macro. Sure if you shadow inside a function that may be pernicious. But well written macro will not be a problem. I guess that it may be really hard for the compiler to understand that something was a macro but perhaps we should either: - ignore the warning if the shadowing happens inside a compound statement - add a declaration attribute to turn the warning off ?
© 2016 - 2026 Red Hat, Inc.