Skip to content

Commit f81da39

Browse files
emuslndavem330
authored andcommitted
ionic: Add XDP packet headroom
If an xdp program is loaded, add headroom at the beginning of the frame to allow for editing and insertions that an XDP program might need room for, and tailroom used later for XDP frame tracking. These are only needed in the first Rx buffer in a packet, not for any trailing frags. Co-developed-by: Brett Creeley <[email protected]> Signed-off-by: Brett Creeley <[email protected]> Signed-off-by: Shannon Nelson <[email protected]> Reviewed-by: Jacob Keller <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 180e35c commit f81da39

File tree

1 file changed

+45
-23
lines changed

1 file changed

+45
-23
lines changed

drivers/net/ethernet/pensando/ionic/ionic_txrx.c

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@ static bool ionic_rx_buf_recycle(struct ionic_queue *q,
189189

190190
static struct sk_buff *ionic_rx_frags(struct ionic_queue *q,
191191
struct ionic_desc_info *desc_info,
192-
struct ionic_rxq_comp *comp,
192+
unsigned int headroom,
193+
unsigned int len,
194+
unsigned int num_sg_elems,
193195
bool synced)
194196
{
195197
struct net_device *netdev = q->lif->netdev;
@@ -199,12 +201,10 @@ static struct sk_buff *ionic_rx_frags(struct ionic_queue *q,
199201
struct sk_buff *skb;
200202
unsigned int i;
201203
u16 frag_len;
202-
u16 len;
203204

204205
stats = q_to_rx_stats(q);
205206

206207
buf_info = &desc_info->bufs[0];
207-
len = le16_to_cpu(comp->len);
208208

209209
prefetchw(buf_info->page);
210210

@@ -216,30 +216,37 @@ static struct sk_buff *ionic_rx_frags(struct ionic_queue *q,
216216
return NULL;
217217
}
218218

219-
i = comp->num_sg_elems + 1;
219+
i = num_sg_elems + 1;
220220
do {
221221
if (unlikely(!buf_info->page)) {
222222
dev_kfree_skb(skb);
223223
return NULL;
224224
}
225225

226-
frag_len = min_t(u16, len, ionic_rx_buf_size(buf_info));
226+
if (headroom)
227+
frag_len = min_t(u16, len, IONIC_XDP_MAX_LINEAR_MTU + VLAN_ETH_HLEN);
228+
else
229+
frag_len = min_t(u16, len, ionic_rx_buf_size(buf_info));
227230
len -= frag_len;
228231

229232
if (!synced)
230233
dma_sync_single_range_for_cpu(dev, ionic_rx_buf_pa(buf_info),
231-
0, frag_len, DMA_FROM_DEVICE);
234+
headroom, frag_len, DMA_FROM_DEVICE);
232235

233236
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
234-
buf_info->page, buf_info->page_offset, frag_len,
235-
IONIC_PAGE_SIZE);
237+
buf_info->page, buf_info->page_offset + headroom,
238+
frag_len, IONIC_PAGE_SIZE);
236239

237240
if (!ionic_rx_buf_recycle(q, buf_info, frag_len)) {
238241
dma_unmap_page(dev, buf_info->dma_addr,
239242
IONIC_PAGE_SIZE, DMA_FROM_DEVICE);
240243
buf_info->page = NULL;
241244
}
242245

246+
/* only needed on the first buffer */
247+
if (headroom)
248+
headroom = 0;
249+
243250
buf_info++;
244251

245252
i--;
@@ -250,20 +257,19 @@ static struct sk_buff *ionic_rx_frags(struct ionic_queue *q,
250257

251258
static struct sk_buff *ionic_rx_copybreak(struct ionic_queue *q,
252259
struct ionic_desc_info *desc_info,
253-
struct ionic_rxq_comp *comp,
260+
unsigned int headroom,
261+
unsigned int len,
254262
bool synced)
255263
{
256264
struct net_device *netdev = q->lif->netdev;
257265
struct ionic_buf_info *buf_info;
258266
struct ionic_rx_stats *stats;
259267
struct device *dev = q->dev;
260268
struct sk_buff *skb;
261-
u16 len;
262269

263270
stats = q_to_rx_stats(q);
264271

265272
buf_info = &desc_info->bufs[0];
266-
len = le16_to_cpu(comp->len);
267273

268274
skb = napi_alloc_skb(&q_to_qcq(q)->napi, len);
269275
if (unlikely(!skb)) {
@@ -280,10 +286,10 @@ static struct sk_buff *ionic_rx_copybreak(struct ionic_queue *q,
280286

281287
if (!synced)
282288
dma_sync_single_range_for_cpu(dev, ionic_rx_buf_pa(buf_info),
283-
0, len, DMA_FROM_DEVICE);
284-
skb_copy_to_linear_data(skb, ionic_rx_buf_va(buf_info), len);
289+
headroom, len, DMA_FROM_DEVICE);
290+
skb_copy_to_linear_data(skb, ionic_rx_buf_va(buf_info) + headroom, len);
285291
dma_sync_single_range_for_device(dev, ionic_rx_buf_pa(buf_info),
286-
0, len, DMA_FROM_DEVICE);
292+
headroom, len, DMA_FROM_DEVICE);
287293

288294
skb_put(skb, len);
289295
skb->protocol = eth_type_trans(skb, q->lif->netdev);
@@ -303,10 +309,10 @@ static bool ionic_run_xdp(struct ionic_rx_stats *stats,
303309

304310
xdp_init_buff(&xdp_buf, IONIC_PAGE_SIZE, rxq->xdp_rxq_info);
305311
xdp_prepare_buff(&xdp_buf, ionic_rx_buf_va(buf_info),
306-
0, len, false);
312+
XDP_PACKET_HEADROOM, len, false);
307313

308314
dma_sync_single_range_for_cpu(rxq->dev, ionic_rx_buf_pa(buf_info),
309-
0, len,
315+
XDP_PACKET_HEADROOM, len,
310316
DMA_FROM_DEVICE);
311317

312318
prefetchw(&xdp_buf.data_hard_start);
@@ -345,6 +351,7 @@ static void ionic_rx_clean(struct ionic_queue *q,
345351
struct ionic_rx_stats *stats;
346352
struct ionic_rxq_comp *comp;
347353
struct bpf_prog *xdp_prog;
354+
unsigned int headroom;
348355
struct sk_buff *skb;
349356
u16 len;
350357

@@ -366,10 +373,12 @@ static void ionic_rx_clean(struct ionic_queue *q,
366373
ionic_run_xdp(stats, netdev, xdp_prog, q, desc_info->bufs, len))
367374
return;
368375

376+
headroom = q->xdp_rxq_info ? XDP_PACKET_HEADROOM : 0;
369377
if (len <= q->lif->rx_copybreak)
370-
skb = ionic_rx_copybreak(q, desc_info, comp, !!xdp_prog);
378+
skb = ionic_rx_copybreak(q, desc_info, headroom, len, !!xdp_prog);
371379
else
372-
skb = ionic_rx_frags(q, desc_info, comp, !!xdp_prog);
380+
skb = ionic_rx_frags(q, desc_info, headroom, len,
381+
comp->num_sg_elems, !!xdp_prog);
373382

374383
if (unlikely(!skb)) {
375384
stats->dropped++;
@@ -493,8 +502,9 @@ void ionic_rx_fill(struct ionic_queue *q)
493502
unsigned int frag_len;
494503
unsigned int nfrags;
495504
unsigned int n_fill;
496-
unsigned int i, j;
497505
unsigned int len;
506+
unsigned int i;
507+
unsigned int j;
498508

499509
n_fill = ionic_q_space_avail(q);
500510

@@ -503,9 +513,12 @@ void ionic_rx_fill(struct ionic_queue *q)
503513
if (n_fill < fill_threshold)
504514
return;
505515

506-
len = netdev->mtu + ETH_HLEN + VLAN_HLEN;
516+
len = netdev->mtu + VLAN_ETH_HLEN;
507517

508518
for (i = n_fill; i; i--) {
519+
unsigned int headroom;
520+
unsigned int buf_len;
521+
509522
nfrags = 0;
510523
remain_len = len;
511524
desc_info = &q->info[q->head_idx];
@@ -520,9 +533,18 @@ void ionic_rx_fill(struct ionic_queue *q)
520533
}
521534
}
522535

523-
/* fill main descriptor - buf[0] */
524-
desc->addr = cpu_to_le64(ionic_rx_buf_pa(buf_info));
525-
frag_len = min_t(u16, len, ionic_rx_buf_size(buf_info));
536+
/* fill main descriptor - buf[0]
537+
* XDP uses space in the first buffer, so account for
538+
* head room, tail room, and ip header in the first frag size.
539+
*/
540+
headroom = q->xdp_rxq_info ? XDP_PACKET_HEADROOM : 0;
541+
if (q->xdp_rxq_info)
542+
buf_len = IONIC_XDP_MAX_LINEAR_MTU + VLAN_ETH_HLEN;
543+
else
544+
buf_len = ionic_rx_buf_size(buf_info);
545+
frag_len = min_t(u16, len, buf_len);
546+
547+
desc->addr = cpu_to_le64(ionic_rx_buf_pa(buf_info) + headroom);
526548
desc->len = cpu_to_le16(frag_len);
527549
remain_len -= frag_len;
528550
buf_info++;

0 commit comments

Comments
 (0)