]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
idpf: improve when to set RE bit logic
authorJoshua Hay <joshua.a.hay@intel.com>
Mon, 15 Dec 2025 21:42:43 +0000 (13:42 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 8 Jan 2026 09:15:03 +0000 (10:15 +0100)
[ Upstream commit f2d18e16479cac7a708d77cbfb4220a9114a71fc ]

Track the gap between next_to_use and the last RE index. Set RE again
if the gap is large enough to ensure RE bit is set frequently. This is
critical before removing the stashing mechanisms because the
opportunistic descriptor ring cleaning from the out-of-order completions
will go away. Previously the descriptors would be "cleaned" by both the
descriptor (RE) completion and the out-of-order completions. Without the
latter, we must ensure the RE bit is set more frequently. Otherwise,
it's theoretically possible for the descriptor ring next_to_clean to
never advance.  The previous implementation was dependent on the start
of a packet falling on a 64th index in the descriptor ring, which is not
guaranteed with large packets.

Signed-off-by: Luigi Rizzo <lrizzo@google.com>
Signed-off-by: Brian Vazquez <brianvv@google.com>
Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
Reviewed-by: Madhu Chittim <madhu.chittim@intel.com>
Tested-by: Samuel Salin <Samuel.salin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/intel/idpf/idpf_txrx.c
drivers/net/ethernet/intel/idpf/idpf_txrx.h

index bbcedb31dfee0004799644e750663446f0f83dbc..1835696697460f82692149469a692851f52da9e5 100644 (file)
@@ -313,6 +313,8 @@ static int idpf_tx_desc_alloc(const struct idpf_vport *vport,
         */
        idpf_queue_change(GEN_CHK, refillq);
 
+       tx_q->last_re = tx_q->desc_count - IDPF_TX_SPLITQ_RE_MIN_GAP;
+
        return 0;
 
 err_alloc:
@@ -2708,6 +2710,21 @@ netdev_tx_t idpf_tx_drop_skb(struct idpf_tx_queue *tx_q, struct sk_buff *skb)
        return NETDEV_TX_OK;
 }
 
+/**
+ * idpf_tx_splitq_need_re - check whether RE bit needs to be set
+ * @tx_q: pointer to Tx queue
+ *
+ * Return: true if RE bit needs to be set, false otherwise
+ */
+static bool idpf_tx_splitq_need_re(struct idpf_tx_queue *tx_q)
+{
+       int gap = tx_q->next_to_use - tx_q->last_re;
+
+       gap += (gap < 0) ? tx_q->desc_count : 0;
+
+       return gap >= IDPF_TX_SPLITQ_RE_MIN_GAP;
+}
+
 /**
  * idpf_tx_splitq_frame - Sends buffer on Tx ring using flex descriptors
  * @skb: send buffer
@@ -2788,9 +2805,10 @@ static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
                 * MIN_RING size to ensure it will be set at least once each
                 * time around the ring.
                 */
-               if (!(tx_q->next_to_use % IDPF_TX_SPLITQ_RE_MIN_GAP)) {
+               if (idpf_tx_splitq_need_re(tx_q)) {
                        tx_params.eop_cmd |= IDPF_TXD_FLEX_FLOW_CMD_RE;
                        tx_q->txq_grp->num_completions_pending++;
+                       tx_q->last_re = tx_q->next_to_use;
                }
 
                if (skb->ip_summed == CHECKSUM_PARTIAL)
index 510c6e95af3a5729c38197a391c855e09cf5b63b..d731e9e28407e3da66fbcd7f14878de32177206c 100644 (file)
@@ -623,6 +623,8 @@ libeth_cacheline_set_assert(struct idpf_rx_queue, 64,
  * @netdev: &net_device corresponding to this queue
  * @next_to_use: Next descriptor to use
  * @next_to_clean: Next descriptor to clean
+ * @last_re: last descriptor index that RE bit was set
+ * @tx_max_bufs: Max buffers that can be transmitted with scatter-gather
  * @cleaned_bytes: Splitq only, TXQ only: When a TX completion is received on
  *                the TX completion queue, it can be for any TXQ associated
  *                with that completion queue. This means we can clean up to
@@ -633,7 +635,6 @@ libeth_cacheline_set_assert(struct idpf_rx_queue, 64,
  *                only once at the end of the cleaning routine.
  * @clean_budget: singleq only, queue cleaning budget
  * @cleaned_pkts: Number of packets cleaned for the above said case
- * @tx_max_bufs: Max buffers that can be transmitted with scatter-gather
  * @stash: Tx buffer stash for Flow-based scheduling mode
  * @refillq: Pointer to refill queue
  * @compl_tag_bufid_m: Completion tag buffer id mask
@@ -674,6 +675,8 @@ struct idpf_tx_queue {
        __cacheline_group_begin_aligned(read_write);
        u16 next_to_use;
        u16 next_to_clean;
+       u16 last_re;
+       u16 tx_max_bufs;
 
        union {
                u32 cleaned_bytes;
@@ -681,7 +684,6 @@ struct idpf_tx_queue {
        };
        u16 cleaned_pkts;
 
-       u16 tx_max_bufs;
        struct idpf_txq_stash *stash;
        struct idpf_sw_queue *refillq;