i40e: add xdp_buff to i40e_ring struct
authorTirthendu Sarkar <tirthendu.sarkar@intel.com>
Thu, 9 Mar 2023 18:56:14 +0000 (00:26 +0530)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Thu, 9 Mar 2023 21:11:24 +0000 (13:11 -0800)
Store xdp_buff on Rx ring struct in preparation for XDP multi-buffer
support. This will allow us to combine fragmented frames across
separate NAPI cycles in the same way as currently skb fragments are
handled. This means that skb pointer on Rx ring will become redundant
and will be removed in a later patch. As a consequence i40e_trace() now
uses xdp instead of skb pointer.

Truesize only needs to be calculated for page sizes bigger than 4k as it
is always half-page for 4k pages. With xdp_buff on ring, frame size can
now be set during xdp_init_buff() and need not be repopulated in each
NAPI call for 4k pages. As a consequence i40e_rx_frame_truesize() is now
used only for bigger pages.

Signed-off-by: Tirthendu Sarkar <tirthendu.sarkar@intel.com>
Tested-by: Chandan Kumar Rout <chandanx.rout@intel.com> (A Contingent Worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_trace.h
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/i40e/i40e_txrx.h

index e8cf5644bf1028ea761bbe9789650bde38f16c27..f2c151a01e77d96935ebc72f4f0fd5d66d56df71 100644 (file)
@@ -3616,6 +3616,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
                }
        }
 
+       xdp_init_buff(&ring->xdp, i40e_rx_pg_size(ring) / 2, &ring->xdp_rxq);
+
        rx_ctx.dbuff = DIV_ROUND_UP(ring->rx_buf_len,
                                    BIT_ULL(I40E_RXQ_CTX_DBUFF_SHIFT));
 
index 79d587ad5409875baede9f4b245fc47b2cc0b66b..33b4e30f5e0045cf47e5650f50f1db820880a961 100644 (file)
@@ -162,45 +162,45 @@ DECLARE_EVENT_CLASS(
 
        TP_PROTO(struct i40e_ring *ring,
                 union i40e_16byte_rx_desc *desc,
-                struct sk_buff *skb),
+                struct xdp_buff *xdp),
 
-       TP_ARGS(ring, desc, skb),
+       TP_ARGS(ring, desc, xdp),
 
        TP_STRUCT__entry(
                __field(void*, ring)
                __field(void*, desc)
-               __field(void*, skb)
+               __field(void*, xdp)
                __string(devname, ring->netdev->name)
        ),
 
        TP_fast_assign(
                __entry->ring = ring;
                __entry->desc = desc;
-               __entry->skb = skb;
+               __entry->xdp = xdp;
                __assign_str(devname, ring->netdev->name);
        ),
 
        TP_printk(
-               "netdev: %s ring: %p desc: %p skb %p",
+               "netdev: %s ring: %p desc: %p xdp %p",
                __get_str(devname), __entry->ring,
-               __entry->desc, __entry->skb)
+               __entry->desc, __entry->xdp)
 );
 
 DEFINE_EVENT(
        i40e_rx_template, i40e_clean_rx_irq,
        TP_PROTO(struct i40e_ring *ring,
                 union i40e_16byte_rx_desc *desc,
-                struct sk_buff *skb),
+                struct xdp_buff *xdp),
 
-       TP_ARGS(ring, desc, skb));
+       TP_ARGS(ring, desc, xdp));
 
 DEFINE_EVENT(
        i40e_rx_template, i40e_clean_rx_irq_rx,
        TP_PROTO(struct i40e_ring *ring,
                 union i40e_16byte_rx_desc *desc,
-                struct sk_buff *skb),
+                struct xdp_buff *xdp),
 
-       TP_ARGS(ring, desc, skb));
+       TP_ARGS(ring, desc, xdp));
 
 DECLARE_EVENT_CLASS(
        i40e_xmit_template,
index 7fa35ff52689565f374e375a35a2cfad488c6ad6..5544c2d43a9295782ac4fcce7e8b0513beddd5d8 100644 (file)
@@ -1619,21 +1619,19 @@ void i40e_release_rx_desc(struct i40e_ring *rx_ring, u32 val)
        writel(val, rx_ring->tail);
 }
 
+#if (PAGE_SIZE >= 8192)
 static unsigned int i40e_rx_frame_truesize(struct i40e_ring *rx_ring,
                                           unsigned int size)
 {
        unsigned int truesize;
 
-#if (PAGE_SIZE < 8192)
-       truesize = i40e_rx_pg_size(rx_ring) / 2; /* Must be power-of-2 */
-#else
        truesize = rx_ring->rx_offset ?
                SKB_DATA_ALIGN(size + rx_ring->rx_offset) +
                SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
                SKB_DATA_ALIGN(size);
-#endif
        return truesize;
 }
+#endif
 
 /**
  * i40e_alloc_mapped_page - recycle or make a new page
@@ -2405,21 +2403,16 @@ static void i40e_inc_ntp(struct i40e_ring *rx_ring)
 static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget,
                             unsigned int *rx_cleaned)
 {
-       unsigned int total_rx_bytes = 0, total_rx_packets = 0, frame_sz = 0;
+       unsigned int total_rx_bytes = 0, total_rx_packets = 0;
        u16 cleaned_count = I40E_DESC_UNUSED(rx_ring);
        unsigned int offset = rx_ring->rx_offset;
+       struct xdp_buff *xdp = &rx_ring->xdp;
        struct sk_buff *skb = rx_ring->skb;
        unsigned int xdp_xmit = 0;
        struct bpf_prog *xdp_prog;
        bool failure = false;
-       struct xdp_buff xdp;
        int xdp_res = 0;
 
-#if (PAGE_SIZE < 8192)
-       frame_sz = i40e_rx_frame_truesize(rx_ring, 0);
-#endif
-       xdp_init_buff(&xdp, frame_sz, &rx_ring->xdp_rxq);
-
        xdp_prog = READ_ONCE(rx_ring->xdp_prog);
 
        while (likely(total_rx_packets < (unsigned int)budget)) {
@@ -2467,7 +2460,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget,
                if (!size)
                        break;
 
-               i40e_trace(clean_rx_irq, rx_ring, rx_desc, skb);
+               i40e_trace(clean_rx_irq, rx_ring, rx_desc, xdp);
                rx_buffer = i40e_get_rx_buffer(rx_ring, size);
 
                /* retrieve a buffer from the ring */
@@ -2476,19 +2469,19 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget,
 
                        hard_start = page_address(rx_buffer->page) +
                                     rx_buffer->page_offset - offset;
-                       xdp_prepare_buff(&xdp, hard_start, offset, size, true);
-                       xdp_buff_clear_frags_flag(&xdp);
+                       xdp_prepare_buff(xdp, hard_start, offset, size, true);
+                       xdp_buff_clear_frags_flag(xdp);
 #if (PAGE_SIZE > 4096)
                        /* At larger PAGE_SIZE, frame_sz depend on len size */
-                       xdp.frame_sz = i40e_rx_frame_truesize(rx_ring, size);
+                       xdp->frame_sz = i40e_rx_frame_truesize(rx_ring, size);
 #endif
-                       xdp_res = i40e_run_xdp(rx_ring, &xdp, xdp_prog);
+                       xdp_res = i40e_run_xdp(rx_ring, xdp, xdp_prog);
                }
 
                if (xdp_res) {
                        if (xdp_res & (I40E_XDP_TX | I40E_XDP_REDIR)) {
                                xdp_xmit |= xdp_res;
-                               i40e_rx_buffer_flip(rx_buffer, xdp.frame_sz);
+                               i40e_rx_buffer_flip(rx_buffer, xdp->frame_sz);
                        } else {
                                rx_buffer->pagecnt_bias++;
                        }
@@ -2497,9 +2490,9 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget,
                } else if (skb) {
                        i40e_add_rx_frag(rx_ring, rx_buffer, skb, size);
                } else if (ring_uses_build_skb(rx_ring)) {
-                       skb = i40e_build_skb(rx_ring, rx_buffer, &xdp);
+                       skb = i40e_build_skb(rx_ring, rx_buffer, xdp);
                } else {
-                       skb = i40e_construct_skb(rx_ring, rx_buffer, &xdp);
+                       skb = i40e_construct_skb(rx_ring, rx_buffer, xdp);
                }
 
                /* exit if we failed to retrieve a buffer */
@@ -2528,7 +2521,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget,
                /* populate checksum, VLAN, and protocol */
                i40e_process_skb_fields(rx_ring, rx_desc, skb);
 
-               i40e_trace(clean_rx_irq_rx, rx_ring, rx_desc, skb);
+               i40e_trace(clean_rx_irq_rx, rx_ring, rx_desc, xdp);
                napi_gro_receive(&rx_ring->q_vector->napi, skb);
                skb = NULL;
 
index 75888a9ab06d91f512e9b0b2f079dba50662bd4b..55da9fde9d1708743d1f83d1ab23396daf650eb0 100644 (file)
@@ -337,6 +337,13 @@ struct i40e_ring {
        u8 dcb_tc;                      /* Traffic class of ring */
        u8 __iomem *tail;
 
+       /* Storing xdp_buff on ring helps in saving the state of partially built
+        * packet when i40e_clean_rx_ring_irq() must return before it sees EOP
+        * and to resume packet building for this ring in the next call to
+        * i40e_clean_rx_ring_irq().
+        */
+       struct xdp_buff xdp;
+
        /* Next descriptor to be processed; next_to_clean is updated only on
         * processing EOP descriptor
         */