Skip to content

Commit 496e051

Browse files
Mintz, Yuvaldavem330
authored andcommitted
qede: Add basic XDP support
Add support for the ndo_xdp callback. This patch would support XDP_PASS, XDP_DROP and XDP_ABORTED commands. This also adds a per Rx queue statistic which counts number of packets which didn't reach the stack [due to XDP]. Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 9eb2235 commit 496e051

3 files changed

Lines changed: 127 additions & 3 deletions

File tree

drivers/net/ethernet/qlogic/qede/qede.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/bitmap.h>
1717
#include <linux/kernel.h>
1818
#include <linux/mutex.h>
19+
#include <linux/bpf.h>
1920
#include <linux/io.h>
2021
#include <linux/qed/common_hsi.h>
2122
#include <linux/qed/eth_common.h>
@@ -187,6 +188,8 @@ struct qede_dev {
187188
bool wol_enabled;
188189

189190
struct qede_rdma_dev rdma_info;
191+
192+
struct bpf_prog *xdp_prog;
190193
};
191194

192195
enum QEDE_STATE {
@@ -249,6 +252,8 @@ struct qede_rx_queue {
249252
/* Required for the allocation of replacement buffers */
250253
struct device *dev;
251254

255+
struct bpf_prog *xdp_prog;
256+
252257
u16 sw_rx_cons;
253258
u16 sw_rx_prod;
254259

@@ -271,6 +276,8 @@ struct qede_rx_queue {
271276
u64 rx_alloc_errors;
272277
u64 rx_ip_frags;
273278

279+
u64 xdp_no_pass;
280+
274281
void *handle;
275282
};
276283

@@ -325,6 +332,7 @@ struct qede_fastpath {
325332
struct qede_dev *edev;
326333
#define QEDE_FASTPATH_TX BIT(0)
327334
#define QEDE_FASTPATH_RX BIT(1)
335+
#define QEDE_FASTPATH_XDP BIT(2)
328336
#define QEDE_FASTPATH_COMBINED (QEDE_FASTPATH_TX | QEDE_FASTPATH_RX)
329337
u8 type;
330338
u8 id;
@@ -358,6 +366,7 @@ struct qede_reload_args {
358366
void (*func)(struct qede_dev *edev, struct qede_reload_args *args);
359367
union {
360368
netdev_features_t features;
369+
struct bpf_prog *new_prog;
361370
u16 mtu;
362371
} u;
363372
};

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ static const struct {
3232
QEDE_RQSTAT(rx_hw_errors),
3333
QEDE_RQSTAT(rx_alloc_errors),
3434
QEDE_RQSTAT(rx_ip_frags),
35+
QEDE_RQSTAT(xdp_no_pass),
3536
};
3637

3738
#define QEDE_NUM_RQSTATS ARRAY_SIZE(qede_rqstats_arr)

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

Lines changed: 117 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,39 @@ static bool qede_pkt_is_ip_fragmented(struct eth_fast_path_rx_reg_cqe *cqe,
14181418
return false;
14191419
}
14201420

1421+
/* Return true iff packet is to be passed to stack */
1422+
static bool qede_rx_xdp(struct qede_dev *edev,
1423+
struct qede_fastpath *fp,
1424+
struct qede_rx_queue *rxq,
1425+
struct bpf_prog *prog,
1426+
struct sw_rx_data *bd,
1427+
struct eth_fast_path_rx_reg_cqe *cqe)
1428+
{
1429+
u16 len = le16_to_cpu(cqe->len_on_first_bd);
1430+
struct xdp_buff xdp;
1431+
enum xdp_action act;
1432+
1433+
xdp.data = page_address(bd->data) + cqe->placement_offset;
1434+
xdp.data_end = xdp.data + len;
1435+
act = bpf_prog_run_xdp(prog, &xdp);
1436+
1437+
if (act == XDP_PASS)
1438+
return true;
1439+
1440+
/* Count number of packets not to be passed to stack */
1441+
rxq->xdp_no_pass++;
1442+
1443+
switch (act) {
1444+
default:
1445+
bpf_warn_invalid_xdp_action(act);
1446+
case XDP_ABORTED:
1447+
case XDP_DROP:
1448+
qede_recycle_rx_bd_ring(rxq, cqe->bd_num);
1449+
}
1450+
1451+
return false;
1452+
}
1453+
14211454
static struct sk_buff *qede_rx_allocate_skb(struct qede_dev *edev,
14221455
struct qede_rx_queue *rxq,
14231456
struct sw_rx_data *bd, u16 len,
@@ -1560,6 +1593,7 @@ static int qede_rx_process_cqe(struct qede_dev *edev,
15601593
struct qede_fastpath *fp,
15611594
struct qede_rx_queue *rxq)
15621595
{
1596+
struct bpf_prog *xdp_prog = READ_ONCE(rxq->xdp_prog);
15631597
struct eth_fast_path_rx_reg_cqe *fp_cqe;
15641598
u16 len, pad, bd_cons_idx, parse_flag;
15651599
enum eth_rx_cqe_type cqe_type;
@@ -1596,6 +1630,11 @@ static int qede_rx_process_cqe(struct qede_dev *edev,
15961630
len = le16_to_cpu(fp_cqe->len_on_first_bd);
15971631
pad = fp_cqe->placement_offset;
15981632

1633+
/* Run eBPF program if one is attached */
1634+
if (xdp_prog)
1635+
if (!qede_rx_xdp(edev, fp, rxq, xdp_prog, bd, fp_cqe))
1636+
return 1;
1637+
15991638
/* If this is an error packet then drop it */
16001639
flags = cqe->fast_path_regular.pars_flags.flags;
16011640
parse_flag = le16_to_cpu(flags);
@@ -2226,7 +2265,16 @@ int qede_set_features(struct net_device *dev, netdev_features_t features)
22262265
args.u.features = features;
22272266
args.func = &qede_set_features_reload;
22282267

2229-
qede_reload(edev, &args, false);
2268+
/* Make sure that we definitely need to reload.
2269+
* In case of an eBPF attached program, there will be no FW
2270+
* aggregations, so no need to actually reload.
2271+
*/
2272+
__qede_lock(edev);
2273+
if (edev->xdp_prog)
2274+
args.func(edev, &args);
2275+
else
2276+
qede_reload(edev, &args, true);
2277+
__qede_unlock(edev);
22302278

22312279
return 1;
22322280
}
@@ -2338,6 +2386,43 @@ static netdev_features_t qede_features_check(struct sk_buff *skb,
23382386
return features;
23392387
}
23402388

2389+
static void qede_xdp_reload_func(struct qede_dev *edev,
2390+
struct qede_reload_args *args)
2391+
{
2392+
struct bpf_prog *old;
2393+
2394+
old = xchg(&edev->xdp_prog, args->u.new_prog);
2395+
if (old)
2396+
bpf_prog_put(old);
2397+
}
2398+
2399+
static int qede_xdp_set(struct qede_dev *edev, struct bpf_prog *prog)
2400+
{
2401+
struct qede_reload_args args;
2402+
2403+
/* If we're called, there was already a bpf reference increment */
2404+
args.func = &qede_xdp_reload_func;
2405+
args.u.new_prog = prog;
2406+
qede_reload(edev, &args, false);
2407+
2408+
return 0;
2409+
}
2410+
2411+
static int qede_xdp(struct net_device *dev, struct netdev_xdp *xdp)
2412+
{
2413+
struct qede_dev *edev = netdev_priv(dev);
2414+
2415+
switch (xdp->command) {
2416+
case XDP_SETUP_PROG:
2417+
return qede_xdp_set(edev, xdp->prog);
2418+
case XDP_QUERY_PROG:
2419+
xdp->prog_attached = !!edev->xdp_prog;
2420+
return 0;
2421+
default:
2422+
return -EINVAL;
2423+
}
2424+
}
2425+
23412426
static const struct net_device_ops qede_netdev_ops = {
23422427
.ndo_open = qede_open,
23432428
.ndo_stop = qede_close,
@@ -2363,6 +2448,7 @@ static const struct net_device_ops qede_netdev_ops = {
23632448
.ndo_udp_tunnel_add = qede_udp_tunnel_add,
23642449
.ndo_udp_tunnel_del = qede_udp_tunnel_del,
23652450
.ndo_features_check = qede_features_check,
2451+
.ndo_xdp = qede_xdp,
23662452
};
23672453

23682454
/* -------------------------------------------------------------------------
@@ -2559,6 +2645,9 @@ static int qede_alloc_fp_array(struct qede_dev *edev)
25592645
fp->rxq = kzalloc(sizeof(*fp->rxq), GFP_KERNEL);
25602646
if (!fp->rxq)
25612647
goto err;
2648+
2649+
if (edev->xdp_prog)
2650+
fp->type |= QEDE_FASTPATH_XDP;
25622651
}
25632652
}
25642653

@@ -2756,6 +2845,10 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode)
27562845

27572846
pci_set_drvdata(pdev, NULL);
27582847

2848+
/* Release edev's reference to XDP's bpf if such exist */
2849+
if (edev->xdp_prog)
2850+
bpf_prog_put(edev->xdp_prog);
2851+
27592852
free_netdev(ndev);
27602853

27612854
/* Use global ops since we've freed edev */
@@ -2907,6 +3000,10 @@ static int qede_alloc_sge_mem(struct qede_dev *edev, struct qede_rx_queue *rxq)
29073000
dma_addr_t mapping;
29083001
int i;
29093002

3003+
/* Don't perform FW aggregations in case of XDP */
3004+
if (edev->xdp_prog)
3005+
edev->gro_disable = 1;
3006+
29103007
if (edev->gro_disable)
29113008
return 0;
29123009

@@ -2959,8 +3056,13 @@ static int qede_alloc_mem_rxq(struct qede_dev *edev, struct qede_rx_queue *rxq)
29593056
if (rxq->rx_buf_size > PAGE_SIZE)
29603057
rxq->rx_buf_size = PAGE_SIZE;
29613058

2962-
/* Segment size to spilt a page in multiple equal parts */
2963-
rxq->rx_buf_seg_size = roundup_pow_of_two(rxq->rx_buf_size);
3059+
/* Segment size to spilt a page in multiple equal parts,
3060+
* unless XDP is used in which case we'd use the entire page.
3061+
*/
3062+
if (!edev->xdp_prog)
3063+
rxq->rx_buf_seg_size = roundup_pow_of_two(rxq->rx_buf_size);
3064+
else
3065+
rxq->rx_buf_seg_size = PAGE_SIZE;
29643066

29653067
/* Allocate the parallel driver ring for Rx buffers */
29663068
size = sizeof(*rxq->sw_rx_ring) * RX_RING_SIZE;
@@ -3368,6 +3470,9 @@ static int qede_stop_queues(struct qede_dev *edev)
33683470
return rc;
33693471
}
33703472
}
3473+
3474+
if (fp->type & QEDE_FASTPATH_XDP)
3475+
bpf_prog_put(fp->rxq->xdp_prog);
33713476
}
33723477

33733478
/* Stop the vport */
@@ -3495,6 +3600,15 @@ static int qede_start_queues(struct qede_dev *edev, bool clear_stats)
34953600
qede_update_rx_prod(edev, rxq);
34963601
}
34973602

3603+
if (fp->type & QEDE_FASTPATH_XDP) {
3604+
fp->rxq->xdp_prog = bpf_prog_add(edev->xdp_prog, 1);
3605+
if (IS_ERR(fp->rxq->xdp_prog)) {
3606+
rc = PTR_ERR(fp->rxq->xdp_prog);
3607+
fp->rxq->xdp_prog = NULL;
3608+
return rc;
3609+
}
3610+
}
3611+
34983612
if (fp->type & QEDE_FASTPATH_TX) {
34993613
rc = qede_start_txq(edev, fp, fp->txq, i, TX_PI(0));
35003614
if (rc)

0 commit comments

Comments
 (0)