Message ID | 20240329170000.3241460-3-aleksander.lobakin@intel.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | net: fix variable shadowing spam from headers | expand |
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 ?
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
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(-)