Patch "igc: Prevent garbled TX queue with XDP ZEROCOPY" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    igc: Prevent garbled TX queue with XDP ZEROCOPY

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     igc-prevent-garbled-tx-queue-with-xdp-zerocopy.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit bb43210055434ee1927664f677efc3176833d9d7
Author: Florian Kauer <florian.kauer@xxxxxxxxxxxxx>
Date:   Mon Jul 17 10:54:44 2023 -0700

    igc: Prevent garbled TX queue with XDP ZEROCOPY
    
    [ Upstream commit 78adb4bcf99effbb960c5f9091e2e062509d1030 ]
    
    In normal operation, each populated queue item has
    next_to_watch pointing to the last TX desc of the packet,
    while each cleaned item has it set to 0. In particular,
    next_to_use that points to the next (necessarily clean)
    item to use has next_to_watch set to 0.
    
    When the TX queue is used both by an application using
    AF_XDP with ZEROCOPY as well as a second non-XDP application
    generating high traffic, the queue pointers can get in
    an invalid state where next_to_use points to an item
    where next_to_watch is NOT set to 0.
    
    However, the implementation assumes at several places
    that this is never the case, so if it does hold,
    bad things happen. In particular, within the loop inside
    of igc_clean_tx_irq(), next_to_clean can overtake next_to_use.
    Finally, this prevents any further transmission via
    this queue and it never gets unblocked or signaled.
    Secondly, if the queue is in this garbled state,
    the inner loop of igc_clean_tx_ring() will never terminate,
    completely hogging a CPU core.
    
    The reason is that igc_xdp_xmit_zc() reads next_to_use
    before acquiring the lock, and writing it back
    (potentially unmodified) later. If it got modified
    before locking, the outdated next_to_use is written
    pointing to an item that was already used elsewhere
    (and thus next_to_watch got written).
    
    Fixes: 9acf59a752d4 ("igc: Enable TX via AF_XDP zero-copy")
    Signed-off-by: Florian Kauer <florian.kauer@xxxxxxxxxxxxx>
    Reviewed-by: Kurt Kanzenbach <kurt@xxxxxxxxxxxxx>
    Tested-by: Kurt Kanzenbach <kurt@xxxxxxxxxxxxx>
    Acked-by: Vinicius Costa Gomes <vinicius.gomes@xxxxxxxxx>
    Reviewed-by: Simon Horman <simon.horman@xxxxxxxxxxxx>
    Tested-by: Naama Meir <naamax.meir@xxxxxxxxxxxxxxx>
    Signed-off-by: Tony Nguyen <anthony.l.nguyen@xxxxxxxxx>
    Link: https://lore.kernel.org/r/20230717175444.3217831-1-anthony.l.nguyen@xxxxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
index 6b747c7dc935f..67b77effb3409 100644
--- a/drivers/net/ethernet/intel/igc/igc_main.c
+++ b/drivers/net/ethernet/intel/igc/igc_main.c
@@ -2750,9 +2750,8 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)
 	struct netdev_queue *nq = txring_txq(ring);
 	union igc_adv_tx_desc *tx_desc = NULL;
 	int cpu = smp_processor_id();
-	u16 ntu = ring->next_to_use;
 	struct xdp_desc xdp_desc;
-	u16 budget;
+	u16 budget, ntu;
 
 	if (!netif_carrier_ok(ring->netdev))
 		return;
@@ -2762,6 +2761,7 @@ static void igc_xdp_xmit_zc(struct igc_ring *ring)
 	/* Avoid transmit queue timeout since we share it with the slow path */
 	txq_trans_cond_update(nq);
 
+	ntu = ring->next_to_use;
 	budget = igc_desc_unused(ring);
 
 	while (xsk_tx_peek_desc(pool, &xdp_desc) && budget--) {



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux