Message ID | 20200713205318.32425-10-anthony.l.nguyen@intel.com |
---|---|
State | Accepted |
Delegated to: | Anthony Nguyen |
Headers | show |
Series | [S50,01/15] ice: Implement LFC workaround | expand |
> -----Original Message----- > From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of > Tony Nguyen > Sent: Monday, July 13, 2020 1:53 PM > To: intel-wired-lan@lists.osuosl.org > Subject: [Intel-wired-lan] [PATCH S50 10/15] ice: need_wakeup flag might > not be set for Tx > > From: Krzysztof Kazimierczak <krzysztof.kazimierczak@intel.com> > > This is a port of i40e commit 705639572e8c ("i40e: need_wakeup flag might > not be set for Tx"). > > Quoting the original commit message: > > "The need_wakeup flag for Tx might not be set for AF_XDP sockets that are > only used to send packets. This happens if there is at least one outstanding > packet that has not been completed by the hardware and we get that > corresponding completion (which will not generate an interrupt since > interrupts are disabled in the napi poll loop) between the time we stopped > processing the Tx completions and interrupts are enabled again. > In this case, the need_wakeup flag will have been cleared at the end of the > Tx completion processing as we believe we will get an interrupt from the > outstanding completion at a later point in time. But if this completion > interrupt occurs before interrupts are enable, we lose it and should at that > point really have set the need_wakeup flag since there are no more > outstanding completions that can generate an interrupt to continue the > processing. When this happens, user space will see a Tx queue > need_wakeup of 0 and skip issuing a syscall, which means will never get into > the Tx processing again and we have a deadlock." > > As a result, packet processing stops. This patch introduces a fix for this issue, > by always setting the need_wakeup flag at the end of an interrupt > processing. This ensures that the deadlock will not happen. > > Signed-off-by: Krzysztof Kazimierczak <krzysztof.kazimierczak@intel.com> > --- > drivers/net/ethernet/intel/ice/ice_xsk.c | 10 ++-------- > 1 file changed, 2 insertions(+), 8 deletions(-) Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c index 6badfd62dc63..87862918bc7a 100644 --- a/drivers/net/ethernet/intel/ice/ice_xsk.c +++ b/drivers/net/ethernet/intel/ice/ice_xsk.c @@ -706,8 +706,6 @@ static bool ice_xmit_zc(struct ice_ring *xdp_ring, int budget) if (tx_desc) { ice_xdp_ring_update_tail(xdp_ring); xsk_umem_consume_tx_done(xdp_ring->xsk_umem); - if (xsk_umem_uses_need_wakeup(xdp_ring->xsk_umem)) - xsk_clear_tx_need_wakeup(xdp_ring->xsk_umem); } return budget > 0 && work_done; @@ -783,12 +781,8 @@ bool ice_clean_tx_irq_zc(struct ice_ring *xdp_ring, int budget) if (xsk_frames) xsk_umem_complete_tx(xdp_ring->xsk_umem, xsk_frames); - if (xsk_umem_uses_need_wakeup(xdp_ring->xsk_umem)) { - if (xdp_ring->next_to_clean == xdp_ring->next_to_use) - xsk_set_tx_need_wakeup(xdp_ring->xsk_umem); - else - xsk_clear_tx_need_wakeup(xdp_ring->xsk_umem); - } + if (xsk_umem_uses_need_wakeup(xdp_ring->xsk_umem)) + xsk_set_tx_need_wakeup(xdp_ring->xsk_umem); ice_update_tx_ring_stats(xdp_ring, total_packets, total_bytes); xmit_done = ice_xmit_zc(xdp_ring, ICE_DFLT_IRQ_WORK);