diff mbox series

[1/1,iwl-net] idpf: disable local BH when scheduling napi for marker packets

Message ID 20240208004243.1762223-1-alan.brady@intel.com (mailing list archive)
State Awaiting Upstream
Delegated to: Netdev Maintainers
Headers show
Series [1/1,iwl-net] idpf: disable local BH when scheduling napi for marker packets | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1019 this patch: 1019
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers fail 3 blamed authors not CCed: anthony.l.nguyen@intel.com willemb@google.com sridhar.samudrala@intel.com; 6 maintainers not CCed: pabeni@redhat.com willemb@google.com sridhar.samudrala@intel.com edumazet@google.com anthony.l.nguyen@intel.com kuba@kernel.org
netdev/build_clang success Errors and warnings before: 1036 this patch: 1036
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 1036 this patch: 1036
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 10 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-02-08--12-00 (tests: 684)

Commit Message

Alan Brady Feb. 8, 2024, 12:42 a.m. UTC
From: Emil Tantilov <emil.s.tantilov@intel.com>

Fix softirq's not being handled during napi_schedule() call when
receiving marker packets for queue disable by disabling local bottom
half.

The issue can be seen on ifdown:
NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!!

Using ftrace to catch the failing scenario:
ifconfig   [003] d.... 22739.830624: softirq_raise: vec=3 [action=NET_RX]
<idle>-0   [003] ..s.. 22739.831357: softirq_entry: vec=3 [action=NET_RX]

No interrupt and CPU is idle.

After the patch, with BH locks:
ifconfig   [003] d.... 22993.928336: softirq_raise: vec=3 [action=NET_RX]
ifconfig   [003] ..s1. 22993.928337: softirq_entry: vec=3 [action=NET_RX]

Fixes: c2d548cad150 ("idpf: add TX splitq napi poll support")
Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Signed-off-by: Alan Brady <alan.brady@intel.com>
---
 drivers/net/ethernet/intel/idpf/idpf_virtchnl.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Simon Horman Feb. 9, 2024, 10:34 a.m. UTC | #1
On Wed, Feb 07, 2024 at 04:42:43PM -0800, Alan Brady wrote:
> From: Emil Tantilov <emil.s.tantilov@intel.com>
> 
> Fix softirq's not being handled during napi_schedule() call when
> receiving marker packets for queue disable by disabling local bottom
> half.
> 
> The issue can be seen on ifdown:
> NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!!
> 
> Using ftrace to catch the failing scenario:
> ifconfig   [003] d.... 22739.830624: softirq_raise: vec=3 [action=NET_RX]
> <idle>-0   [003] ..s.. 22739.831357: softirq_entry: vec=3 [action=NET_RX]
> 
> No interrupt and CPU is idle.
> 
> After the patch, with BH locks:
> ifconfig   [003] d.... 22993.928336: softirq_raise: vec=3 [action=NET_RX]
> ifconfig   [003] ..s1. 22993.928337: softirq_entry: vec=3 [action=NET_RX]
> 
> Fixes: c2d548cad150 ("idpf: add TX splitq napi poll support")
> Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> Signed-off-by: Alan Brady <alan.brady@intel.com>

Reviewed-by: Simon Horman <horms@kernel.org>
Alexander Lobakin Feb. 12, 2024, 2:41 p.m. UTC | #2
From: Alan Brady <alan.brady@intel.com>
Date: Wed,  7 Feb 2024 16:42:43 -0800

> From: Emil Tantilov <emil.s.tantilov@intel.com>
> 
> Fix softirq's not being handled during napi_schedule() call when
> receiving marker packets for queue disable by disabling local bottom
> half.
> 
> The issue can be seen on ifdown:
> NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!!
> 
> Using ftrace to catch the failing scenario:
> ifconfig   [003] d.... 22739.830624: softirq_raise: vec=3 [action=NET_RX]
> <idle>-0   [003] ..s.. 22739.831357: softirq_entry: vec=3 [action=NET_RX]
> 
> No interrupt and CPU is idle.
> 
> After the patch, with BH locks:

Minor: local_bh_{en,dis}able() are not "BH locks", it's BH
enabling/disabling. It doesn't lock/unlock anything.

> ifconfig   [003] d.... 22993.928336: softirq_raise: vec=3 [action=NET_RX]
> ifconfig   [003] ..s1. 22993.928337: softirq_entry: vec=3 [action=NET_RX]
> 
> Fixes: c2d548cad150 ("idpf: add TX splitq napi poll support")
> Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> Signed-off-by: Alan Brady <alan.brady@intel.com>

Thanks,
Olek
Emil Tantilov Feb. 12, 2024, 5:43 p.m. UTC | #3
On 2/12/2024 6:41 AM, Alexander Lobakin wrote:
> From: Alan Brady <alan.brady@intel.com>
> Date: Wed,  7 Feb 2024 16:42:43 -0800
> 
>> From: Emil Tantilov <emil.s.tantilov@intel.com>
>>
>> Fix softirq's not being handled during napi_schedule() call when
>> receiving marker packets for queue disable by disabling local bottom
>> half.
>>
>> The issue can be seen on ifdown:
>> NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!!
>>
>> Using ftrace to catch the failing scenario:
>> ifconfig   [003] d.... 22739.830624: softirq_raise: vec=3 [action=NET_RX]
>> <idle>-0   [003] ..s.. 22739.831357: softirq_entry: vec=3 [action=NET_RX]
>>
>> No interrupt and CPU is idle.
>>
>> After the patch, with BH locks:
> 
> Minor: local_bh_{en,dis}able() are not "BH locks", it's BH
> enabling/disabling. It doesn't lock/unlock anything.

Good catch, we can change it to:
"After the patch when disabling local BH before calling napi_schedule:"

> 
>> ifconfig   [003] d.... 22993.928336: softirq_raise: vec=3 [action=NET_RX]
>> ifconfig   [003] ..s1. 22993.928337: softirq_entry: vec=3 [action=NET_RX]
>>
>> Fixes: c2d548cad150 ("idpf: add TX splitq napi poll support")
>> Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
>> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
>> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
>> Signed-off-by: Alan Brady <alan.brady@intel.com>
> 
> Thanks,
> Olek

Thanks,
Emil
Alexander Lobakin Feb. 13, 2024, 1:16 p.m. UTC | #4
From: Alan Brady <alan.brady@intel.com>
Date: Wed,  7 Feb 2024 16:42:43 -0800

> From: Emil Tantilov <emil.s.tantilov@intel.com>
> 
> Fix softirq's not being handled during napi_schedule() call when
> receiving marker packets for queue disable by disabling local bottom
> half.

BTW, how exactly does this help?

__napi_schedule() already disables interrupts (local_irq_save()).
napi_schedule_prep() only has READ_ONCE() and other atomic read/write
helpers.

It's always been safe to call napi_schedule() with enabled BH, so I
don't really understand how this works.

> 
> The issue can be seen on ifdown:
> NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!!
> 
> Using ftrace to catch the failing scenario:
> ifconfig   [003] d.... 22739.830624: softirq_raise: vec=3 [action=NET_RX]
> <idle>-0   [003] ..s.. 22739.831357: softirq_entry: vec=3 [action=NET_RX]
> 
> No interrupt and CPU is idle.
> 
> After the patch, with BH locks:
> ifconfig   [003] d.... 22993.928336: softirq_raise: vec=3 [action=NET_RX]
> ifconfig   [003] ..s1. 22993.928337: softirq_entry: vec=3 [action=NET_RX]
> 
> Fixes: c2d548cad150 ("idpf: add TX splitq napi poll support")
> Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> Signed-off-by: Alan Brady <alan.brady@intel.com>
> ---
>  drivers/net/ethernet/intel/idpf/idpf_virtchnl.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> index d0cdd63b3d5b..390977a76de2 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> @@ -2087,8 +2087,10 @@ int idpf_send_disable_queues_msg(struct idpf_vport *vport)
>  		set_bit(__IDPF_Q_POLL_MODE, vport->txqs[i]->flags);
>  
>  	/* schedule the napi to receive all the marker packets */
> +	local_bh_disable();
>  	for (i = 0; i < vport->num_q_vectors; i++)
>  		napi_schedule(&vport->q_vectors[i].napi);
> +	local_bh_enable();
>  
>  	return idpf_wait_for_marker_event(vport);
>  }

Thanks,
Olek
Alexander Lobakin Feb. 14, 2024, 2:54 p.m. UTC | #5
From: Alexander Lobakin <aleksander.lobakin@intel.com>
Date: Tue, 13 Feb 2024 14:16:47 +0100

> From: Alan Brady <alan.brady@intel.com>
> Date: Wed,  7 Feb 2024 16:42:43 -0800
> 
>> From: Emil Tantilov <emil.s.tantilov@intel.com>
>>
>> Fix softirq's not being handled during napi_schedule() call when
>> receiving marker packets for queue disable by disabling local bottom
>> half.
> 
> BTW, how exactly does this help?
> 
> __napi_schedule() already disables interrupts (local_irq_save()).
> napi_schedule_prep() only has READ_ONCE() and other atomic read/write
> helpers.
> 
> It's always been safe to call napi_schedule() with enabled BH, so I
> don't really understand how this works.

This also needs to be dropped from the fixes queue until investigated.
For now, it looks like a cheap hack (without the explanation how exactly
it does help), not a proper fix.

Thanks,
Olek
Emil Tantilov Feb. 14, 2024, 3:39 p.m. UTC | #6
On 2/14/2024 6:54 AM, Alexander Lobakin wrote:
> From: Alexander Lobakin <aleksander.lobakin@intel.com>
> Date: Tue, 13 Feb 2024 14:16:47 +0100
> 
>> From: Alan Brady <alan.brady@intel.com>
>> Date: Wed,  7 Feb 2024 16:42:43 -0800
>>
>>> From: Emil Tantilov <emil.s.tantilov@intel.com>
>>>
>>> Fix softirq's not being handled during napi_schedule() call when
>>> receiving marker packets for queue disable by disabling local bottom
>>> half.
>>
>> BTW, how exactly does this help?
>>
>> __napi_schedule() already disables interrupts (local_irq_save()).
>> napi_schedule_prep() only has READ_ONCE() and other atomic read/write
>> helpers.
>>
>> It's always been safe to call napi_schedule() with enabled BH, so I
>> don't really understand how this works.

It's been a while since I debugged this, I'll have to take a look again, 
but its not so much about being safe as it is about making sure the 
marker packets are received in those cases - like ifdown in the trace.

> This also needs to be dropped from the fixes queue until investigated.
> For now, it looks like a cheap hack (without the explanation how exactly
> it does help), not a proper fix.

It does fix the issue at hand. Looking at the kernel code I see multiple 
examples of napi_schedule() being wrapped with local_bh_disable/enable, 
so this appears to be a common (not uncommon?) technique.

Thanks,
Emil

> 
> Thanks,
> Olek
Jakub Kicinski Feb. 15, 2024, 12:36 a.m. UTC | #7
On Tue, 13 Feb 2024 14:16:47 +0100 Alexander Lobakin wrote:
> > Fix softirq's not being handled during napi_schedule() call when
> > receiving marker packets for queue disable by disabling local bottom
> > half.  
> 
> BTW, how exactly does this help?
> 
> __napi_schedule() already disables interrupts (local_irq_save()).
> napi_schedule_prep() only has READ_ONCE() and other atomic read/write
> helpers.
> 
> It's always been safe to call napi_schedule() with enabled BH, so I
> don't really understand how this works.

Sorry for late reply. IIRC the problem isn't a race but the fact that
local_irq_restore() does not have a hook for BH. IOW we may just set 
the bit that the BH is pending but never call into softirq.c to run it.
Alexander Lobakin Feb. 15, 2024, 1:28 p.m. UTC | #8
From: Tantilov, Emil S <emil.s.tantilov@intel.com>
Date: Wed, 14 Feb 2024 07:39:53 -0800

> 
> 
> On 2/14/2024 6:54 AM, Alexander Lobakin wrote:
>> From: Alexander Lobakin <aleksander.lobakin@intel.com>
>> Date: Tue, 13 Feb 2024 14:16:47 +0100
>>
>>> From: Alan Brady <alan.brady@intel.com>
>>> Date: Wed,  7 Feb 2024 16:42:43 -0800
>>>
>>>> From: Emil Tantilov <emil.s.tantilov@intel.com>
>>>>
>>>> Fix softirq's not being handled during napi_schedule() call when
>>>> receiving marker packets for queue disable by disabling local bottom
>>>> half.
>>>
>>> BTW, how exactly does this help?
>>>
>>> __napi_schedule() already disables interrupts (local_irq_save()).
>>> napi_schedule_prep() only has READ_ONCE() and other atomic read/write
>>> helpers.
>>>
>>> It's always been safe to call napi_schedule() with enabled BH, so I
>>> don't really understand how this works.
> 
> It's been a while since I debugged this, I'll have to take a look again,
> but its not so much about being safe as it is about making sure the
> marker packets are received in those cases - like ifdown in the trace.
> 
>> This also needs to be dropped from the fixes queue until investigated.
>> For now, it looks like a cheap hack (without the explanation how exactly
>> it does help), not a proper fix.
> 
> It does fix the issue at hand. Looking at the kernel code I see multiple

Sometimes adding debug prints fixes bugs, fixing something doesn't mean
it's the correct way.

> examples of napi_schedule() being wrapped with local_bh_disable/enable,

"Everybody do that" doesn't prove anything until explained how exactly
this helps.

> so this appears to be a common (not uncommon?) technique.
> 
> Thanks,
> Emil
> 
>>
>> Thanks,
>> Olek

Thanks,
Olek
Singh, Krishneil K March 5, 2024, 12:44 a.m. UTC | #9
> -----Original Message-----
> From: Alan Brady <alan.brady@intel.com>
> Sent: Wednesday, February 7, 2024 4:43 PM
> To: intel-wired-lan@lists.osuosl.org
> Cc: netdev@vger.kernel.org; Tantilov, Emil S <emil.s.tantilov@intel.com>;
> Brandeburg, Jesse <jesse.brandeburg@intel.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Brady, Alan <alan.brady@intel.com>
> Subject: [PATCH 1/1 iwl-net] idpf: disable local BH when scheduling napi for
> marker packets
> 
> From: Emil Tantilov <emil.s.tantilov@intel.com>
> 
> Fix softirq's not being handled during napi_schedule() call when
> receiving marker packets for queue disable by disabling local bottom
> half.
> 
> The issue can be seen on ifdown:
> NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!!
> 
> Using ftrace to catch the failing scenario:
> ifconfig   [003] d.... 22739.830624: softirq_raise: vec=3 [action=NET_RX]
> <idle>-0   [003] ..s.. 22739.831357: softirq_entry: vec=3 [action=NET_RX]
> 
> No interrupt and CPU is idle.
> 
> After the patch, with BH locks:
> ifconfig   [003] d.... 22993.928336: softirq_raise: vec=3 [action=NET_RX]
> ifconfig   [003] ..s1. 22993.928337: softirq_entry: vec=3 [action=NET_RX]
> 
> Fixes: c2d548cad150 ("idpf: add TX splitq napi poll support")
> Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> Signed-off-by: Alan Brady <alan.brady@intel.com>
> ---
>  drivers/net/ethernet/intel/idpf/idpf_virtchnl.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> index d0cdd63b3d5b..390977a76de2 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c

Tested-by: Krishneil Singh <krishneil.k.singh@intel.com>
diff mbox series

Patch

diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
index d0cdd63b3d5b..390977a76de2 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
@@ -2087,8 +2087,10 @@  int idpf_send_disable_queues_msg(struct idpf_vport *vport)
 		set_bit(__IDPF_Q_POLL_MODE, vport->txqs[i]->flags);
 
 	/* schedule the napi to receive all the marker packets */
+	local_bh_disable();
 	for (i = 0; i < vport->num_q_vectors; i++)
 		napi_schedule(&vport->q_vectors[i].napi);
+	local_bh_enable();
 
 	return idpf_wait_for_marker_event(vport);
 }