Skip to content

Commit 059eeb0

Browse files
Mintz, Yuvaldavem330
authored andcommitted
qede: Support XDP adjustment of headers
In case an XDP program is attached, reserve XDP_PACKET_HEADROOM bytes at the beginning of the packet for the program to play with. Modify the XDP logic in the driver to fill-in the missing bits and re-calculate offsets and length after the program has finished running to properly reflect the current status of the packet. We can then go and remove the limitation of not supporting XDP programs where xdp_adjust_head is set. Signed-off-by: Yuval Mintz <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 15ed8a4 commit 059eeb0

File tree

3 files changed

+12
-11
lines changed

3 files changed

+12
-11
lines changed

drivers/net/ethernet/qlogic/qede/qede_filter.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -520,11 +520,6 @@ static int qede_xdp_set(struct qede_dev *edev, struct bpf_prog *prog)
520520
{
521521
struct qede_reload_args args;
522522

523-
if (prog && prog->xdp_adjust_head) {
524-
DP_ERR(edev, "Does not support bpf_xdp_adjust_head()\n");
525-
return -EOPNOTSUPP;
526-
}
527-
528523
/* If we're called, there was already a bpf reference increment */
529524
args.func = &qede_xdp_reload_func;
530525
args.u.new_prog = prog;

drivers/net/ethernet/qlogic/qede/qede_fp.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -994,14 +994,14 @@ static bool qede_rx_xdp(struct qede_dev *edev,
994994
struct bpf_prog *prog,
995995
struct sw_rx_data *bd,
996996
struct eth_fast_path_rx_reg_cqe *cqe,
997-
u16 data_offset)
997+
u16 *data_offset, u16 *len)
998998
{
999-
u16 len = le16_to_cpu(cqe->len_on_first_bd);
1000999
struct xdp_buff xdp;
10011000
enum xdp_action act;
10021001

1003-
xdp.data = page_address(bd->data) + data_offset;
1004-
xdp.data_end = xdp.data + len;
1002+
xdp.data_hard_start = page_address(bd->data);
1003+
xdp.data = xdp.data_hard_start + *data_offset;
1004+
xdp.data_end = xdp.data + *len;
10051005

10061006
/* Queues always have a full reset currently, so for the time
10071007
* being until there's atomic program replace just mark read
@@ -1011,6 +1011,10 @@ static bool qede_rx_xdp(struct qede_dev *edev,
10111011
act = bpf_prog_run_xdp(prog, &xdp);
10121012
rcu_read_unlock();
10131013

1014+
/* Recalculate, as XDP might have changed the headers */
1015+
*data_offset = xdp.data - xdp.data_hard_start;
1016+
*len = xdp.data_end - xdp.data;
1017+
10141018
if (act == XDP_PASS)
10151019
return true;
10161020

@@ -1029,7 +1033,7 @@ static bool qede_rx_xdp(struct qede_dev *edev,
10291033
/* Now if there's a transmission problem, we'd still have to
10301034
* throw current buffer, as replacement was already allocated.
10311035
*/
1032-
if (qede_xdp_xmit(edev, fp, bd, data_offset, len)) {
1036+
if (qede_xdp_xmit(edev, fp, bd, *data_offset, *len)) {
10331037
dma_unmap_page(rxq->dev, bd->mapping,
10341038
PAGE_SIZE, DMA_BIDIRECTIONAL);
10351039
__free_page(bd->data);
@@ -1231,7 +1235,8 @@ static int qede_rx_process_cqe(struct qede_dev *edev,
12311235

12321236
/* Run eBPF program if one is attached */
12331237
if (xdp_prog)
1234-
if (!qede_rx_xdp(edev, fp, rxq, xdp_prog, bd, fp_cqe, pad))
1238+
if (!qede_rx_xdp(edev, fp, rxq, xdp_prog, bd, fp_cqe,
1239+
&pad, &len))
12351240
return 0;
12361241

12371242
/* If this is an error packet then drop it */

drivers/net/ethernet/qlogic/qede/qede_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,7 @@ static int qede_alloc_mem_rxq(struct qede_dev *edev, struct qede_rx_queue *rxq)
11871187
rxq->num_rx_buffers = edev->q_num_rx_buffers;
11881188

11891189
rxq->rx_buf_size = NET_IP_ALIGN + ETH_OVERHEAD + edev->ndev->mtu;
1190+
rxq->rx_headroom = edev->xdp_prog ? XDP_PACKET_HEADROOM : 0;
11901191

11911192
/* Make sure that the headroom and payload fit in a single page */
11921193
if (rxq->rx_buf_size + rxq->rx_headroom > PAGE_SIZE)

0 commit comments

Comments
 (0)