igc: Add igc_xdp_buff wrapper for xdp_buff in driver
authorJesper Dangaard Brouer <brouer@redhat.com>
Tue, 18 Apr 2023 13:30:47 +0000 (15:30 +0200)
committerDaniel Borkmann <daniel@iogearbox.net>
Thu, 27 Apr 2023 16:42:19 +0000 (18:42 +0200)
Driver specific metadata data for XDP-hints kfuncs are propagated via tail
extending the struct xdp_buff with a locally scoped driver struct.

Zero-Copy AF_XDP/XSK does similar tricks via struct xdp_buff_xsk. This
xdp_buff_xsk struct contains a CB area (24 bytes) that can be used for
extending the locally scoped driver into. The XSK_CHECK_PRIV_TYPE define
catch size violations build time.

The changes needed for AF_XDP zero-copy in igc_clean_rx_irq_zc()
is done in next patch, because the member rx_desc isn't available
at this point.

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Song Yoong Siang <yoong.siang.song@intel.com>
Link: https://lore.kernel.org/bpf/168182464779.616355.3761989884165609387.stgit@firesoul
drivers/net/ethernet/intel/igc/igc.h
drivers/net/ethernet/intel/igc/igc_main.c

index f7f9e21..76a5115 100644 (file)
@@ -499,6 +499,11 @@ struct igc_rx_buffer {
        };
 };
 
+/* context wrapper around xdp_buff to provide access to descriptor metadata */
+struct igc_xdp_buff {
+       struct xdp_buff xdp;
+};
+
 struct igc_q_vector {
        struct igc_adapter *adapter;    /* backlink */
        void __iomem *itr_register;
index f6b03e0..06bf8a7 100644 (file)
@@ -2233,6 +2233,8 @@ static bool igc_alloc_rx_buffers_zc(struct igc_ring *ring, u16 count)
        if (!count)
                return ok;
 
+       XSK_CHECK_PRIV_TYPE(struct igc_xdp_buff);
+
        desc = IGC_RX_DESC(ring, i);
        bi = &ring->rx_buffer_info[i];
        i -= ring->count;
@@ -2517,8 +2519,8 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
                union igc_adv_rx_desc *rx_desc;
                struct igc_rx_buffer *rx_buffer;
                unsigned int size, truesize;
+               struct igc_xdp_buff ctx;
                ktime_t timestamp = 0;
-               struct xdp_buff xdp;
                int pkt_offset = 0;
                void *pktbuf;
 
@@ -2552,13 +2554,13 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
                }
 
                if (!skb) {
-                       xdp_init_buff(&xdp, truesize, &rx_ring->xdp_rxq);
-                       xdp_prepare_buff(&xdp, pktbuf - igc_rx_offset(rx_ring),
+                       xdp_init_buff(&ctx.xdp, truesize, &rx_ring->xdp_rxq);
+                       xdp_prepare_buff(&ctx.xdp, pktbuf - igc_rx_offset(rx_ring),
                                         igc_rx_offset(rx_ring) + pkt_offset,
                                         size, true);
-                       xdp_buff_clear_frags_flag(&xdp);
+                       xdp_buff_clear_frags_flag(&ctx.xdp);
 
-                       skb = igc_xdp_run_prog(adapter, &xdp);
+                       skb = igc_xdp_run_prog(adapter, &ctx.xdp);
                }
 
                if (IS_ERR(skb)) {
@@ -2580,9 +2582,9 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
                } else if (skb)
                        igc_add_rx_frag(rx_ring, rx_buffer, skb, size);
                else if (ring_uses_build_skb(rx_ring))
-                       skb = igc_build_skb(rx_ring, rx_buffer, &xdp);
+                       skb = igc_build_skb(rx_ring, rx_buffer, &ctx.xdp);
                else
-                       skb = igc_construct_skb(rx_ring, rx_buffer, &xdp,
+                       skb = igc_construct_skb(rx_ring, rx_buffer, &ctx.xdp,
                                                timestamp);
 
                /* exit if we failed to retrieve a buffer */