Skip to content

Commit

Permalink
igc: enable XDP metadata in driver
Browse files Browse the repository at this point in the history
Enabling the XDP bpf_prog access to data_meta area is a very small
change. Hint passing 'true' to xdp_prepare_buff().

The SKB layers can also access data_meta area, which required more
driver changes to support. Reviewers, notice the igc driver have two
different functions that can create SKBs, depending on driver config.

Hint for testers, ethtool priv-flags legacy-rx enables
the function igc_construct_skb()

 ethtool --set-priv-flags DEV legacy-rx on

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Tested-by: Nechama Kraus <nechamax.kraus@linux.intel.com>
Reviewed-by: Alexander Lobakin <alexandr.lobakin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
  • Loading branch information
Jesper Dangaard Brouer authored and Tony Nguyen committed Nov 30, 2021
1 parent 4fa8fcd commit f51b5e2
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions drivers/net/ethernet/intel/igc/igc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1718,24 +1718,26 @@ static void igc_add_rx_frag(struct igc_ring *rx_ring,

static struct sk_buff *igc_build_skb(struct igc_ring *rx_ring,
struct igc_rx_buffer *rx_buffer,
union igc_adv_rx_desc *rx_desc,
unsigned int size)
struct xdp_buff *xdp)
{
void *va = page_address(rx_buffer->page) + rx_buffer->page_offset;
unsigned int size = xdp->data_end - xdp->data;
unsigned int truesize = igc_get_rx_frame_truesize(rx_ring, size);
unsigned int metasize = xdp->data - xdp->data_meta;
struct sk_buff *skb;

/* prefetch first cache line of first page */
net_prefetch(va);
net_prefetch(xdp->data_meta);

/* build an skb around the page buffer */
skb = build_skb(va - IGC_SKB_PAD, truesize);
skb = build_skb(xdp->data_hard_start, truesize);
if (unlikely(!skb))
return NULL;

/* update pointers within the skb to store the data */
skb_reserve(skb, IGC_SKB_PAD);
skb_reserve(skb, xdp->data - xdp->data_hard_start);
__skb_put(skb, size);
if (metasize)
skb_metadata_set(skb, metasize);

igc_rx_buffer_flip(rx_buffer, truesize);
return skb;
Expand All @@ -1746,17 +1748,19 @@ static struct sk_buff *igc_construct_skb(struct igc_ring *rx_ring,
struct xdp_buff *xdp,
ktime_t timestamp)
{
unsigned int metasize = xdp->data - xdp->data_meta;
unsigned int size = xdp->data_end - xdp->data;
unsigned int truesize = igc_get_rx_frame_truesize(rx_ring, size);
void *va = xdp->data;
unsigned int headlen;
struct sk_buff *skb;

/* prefetch first cache line of first page */
net_prefetch(va);
net_prefetch(xdp->data_meta);

/* allocate a skb to store the frags */
skb = napi_alloc_skb(&rx_ring->q_vector->napi, IGC_RX_HDR_LEN);
skb = napi_alloc_skb(&rx_ring->q_vector->napi,
IGC_RX_HDR_LEN + metasize);
if (unlikely(!skb))
return NULL;

Expand All @@ -1769,7 +1773,13 @@ static struct sk_buff *igc_construct_skb(struct igc_ring *rx_ring,
headlen = eth_get_headlen(skb->dev, va, IGC_RX_HDR_LEN);

/* align pull length to size of long to optimize memcpy performance */
memcpy(__skb_put(skb, headlen), va, ALIGN(headlen, sizeof(long)));
memcpy(__skb_put(skb, headlen + metasize), xdp->data_meta,
ALIGN(headlen + metasize, sizeof(long)));

if (metasize) {
skb_metadata_set(skb, metasize);
__skb_pull(skb, metasize);
}

/* update all of the pointers */
size -= headlen;
Expand Down Expand Up @@ -2354,7 +2364,8 @@ 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),
igc_rx_offset(rx_ring) + pkt_offset, size, false);
igc_rx_offset(rx_ring) + pkt_offset,
size, true);

skb = igc_xdp_run_prog(adapter, &xdp);
}
Expand All @@ -2378,7 +2389,7 @@ 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, rx_desc, size);
skb = igc_build_skb(rx_ring, rx_buffer, &xdp);
else
skb = igc_construct_skb(rx_ring, rx_buffer, &xdp,
timestamp);
Expand Down

0 comments on commit f51b5e2

Please sign in to comment.