Skip to content

Commit efc2214

Browse files
mfijalkoJeff Kirsher
authored and
Jeff Kirsher
committed
ice: Add support for XDP
Add support for XDP. Implement ndo_bpf and ndo_xdp_xmit. Upon load of an XDP program, allocate additional Tx rings for dedicated XDP use. The following actions are supported: XDP_TX, XDP_DROP, XDP_REDIRECT, XDP_PASS, and XDP_ABORTED. Signed-off-by: Maciej Fijalkowski <[email protected]> Signed-off-by: Tony Nguyen <[email protected]> Tested-by: Andrew Bowers <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent e75d1b2 commit efc2214

File tree

8 files changed

+825
-57
lines changed

8 files changed

+825
-57
lines changed

drivers/net/ethernet/intel/ice/ice.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929
#include <linux/ip.h>
3030
#include <linux/sctp.h>
3131
#include <linux/ipv6.h>
32+
#include <linux/pkt_sched.h>
3233
#include <linux/if_bridge.h>
3334
#include <linux/ctype.h>
35+
#include <linux/bpf.h>
3436
#include <linux/avf/virtchnl.h>
3537
#include <net/ipv6.h>
3638
#include "ice_devids.h"
@@ -78,8 +80,7 @@ extern const char ice_drv_ver[];
7880

7981
#define ICE_DFLT_NETIF_M (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)
8082

81-
#define ICE_MAX_MTU (ICE_AQ_SET_MAC_FRAME_SIZE_MAX - \
82-
(ETH_HLEN + ETH_FCS_LEN + (VLAN_HLEN * 2)))
83+
#define ICE_MAX_MTU (ICE_AQ_SET_MAC_FRAME_SIZE_MAX - ICE_ETH_PKT_HDR_PAD)
8384

8485
#define ICE_UP_TABLE_TRANSLATE(val, i) \
8586
(((val) << ICE_AQ_VSI_UP_TABLE_UP##i##_S) & \
@@ -282,6 +283,10 @@ struct ice_vsi {
282283
u16 num_rx_desc;
283284
u16 num_tx_desc;
284285
struct ice_tc_cfg tc_cfg;
286+
struct bpf_prog *xdp_prog;
287+
struct ice_ring **xdp_rings; /* XDP ring array */
288+
u16 num_xdp_txq; /* Used XDP queues */
289+
u8 xdp_mapping_mode; /* ICE_MAP_MODE_[CONTIG|SCATTER] */
285290
} ____cacheline_internodealigned_in_smp;
286291

287292
/* struct that defines an interrupt vector */
@@ -425,6 +430,16 @@ static inline struct ice_pf *ice_netdev_to_pf(struct net_device *netdev)
425430
return np->vsi->back;
426431
}
427432

433+
static inline bool ice_is_xdp_ena_vsi(struct ice_vsi *vsi)
434+
{
435+
return !!vsi->xdp_prog;
436+
}
437+
438+
static inline void ice_set_ring_xdp(struct ice_ring *ring)
439+
{
440+
ring->flags |= ICE_TX_FLAGS_RING_XDP;
441+
}
442+
428443
/**
429444
* ice_get_main_vsi - Get the PF VSI
430445
* @pf: PF instance
@@ -451,6 +466,11 @@ int ice_up(struct ice_vsi *vsi);
451466
int ice_down(struct ice_vsi *vsi);
452467
int ice_vsi_cfg(struct ice_vsi *vsi);
453468
struct ice_vsi *ice_lb_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi);
469+
int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog);
470+
int ice_destroy_xdp_rings(struct ice_vsi *vsi);
471+
int
472+
ice_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
473+
u32 flags);
454474
int ice_set_rss(struct ice_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
455475
int ice_get_rss(struct ice_vsi *vsi, u8 *seed, u8 *lut, u16 lut_size);
456476
void ice_fill_rss_lut(u8 *lut, u16 rss_table_size, u16 rss_size);

drivers/net/ethernet/intel/ice/ice_base.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,9 @@ static void ice_cfg_itr_gran(struct ice_hw *hw)
198198
*/
199199
static u16 ice_calc_q_handle(struct ice_vsi *vsi, struct ice_ring *ring, u8 tc)
200200
{
201+
WARN_ONCE(ice_ring_is_xdp(ring) && tc,
202+
"XDP ring can't belong to TC other than 0");
203+
201204
/* Idea here for calculation is that we subtract the number of queue
202205
* count from TC that ring belongs to from it's absolute queue index
203206
* and as a result we get the queue's index within TC.
@@ -287,14 +290,30 @@ int ice_setup_rx_ctx(struct ice_ring *ring)
287290
/* clear the context structure first */
288291
memset(&rlan_ctx, 0, sizeof(rlan_ctx));
289292

293+
ring->rx_buf_len = vsi->rx_buf_len;
294+
295+
if (ring->vsi->type == ICE_VSI_PF) {
296+
if (!xdp_rxq_info_is_reg(&ring->xdp_rxq))
297+
xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev,
298+
ring->q_index);
299+
300+
err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
301+
MEM_TYPE_PAGE_SHARED, NULL);
302+
if (err)
303+
return err;
304+
}
305+
/* Receive Queue Base Address.
306+
* Indicates the starting address of the descriptor queue defined in
307+
* 128 Byte units.
308+
*/
290309
rlan_ctx.base = ring->dma >> 7;
291310

292311
rlan_ctx.qlen = ring->count;
293312

294313
/* Receive Packet Data Buffer Size.
295314
* The Packet Data Buffer Size is defined in 128 byte units.
296315
*/
297-
rlan_ctx.dbuf = vsi->rx_buf_len >> ICE_RLAN_CTX_DBUF_S;
316+
rlan_ctx.dbuf = ring->rx_buf_len >> ICE_RLAN_CTX_DBUF_S;
298317

299318
/* use 32 byte descriptors */
300319
rlan_ctx.dsize = 1;
@@ -657,6 +676,13 @@ ice_cfg_txq_interrupt(struct ice_vsi *vsi, u16 txq, u16 msix_idx, u16 itr_idx)
657676
((msix_idx << QINT_TQCTL_MSIX_INDX_S) & QINT_TQCTL_MSIX_INDX_M);
658677

659678
wr32(hw, QINT_TQCTL(vsi->txq_map[txq]), val);
679+
if (ice_is_xdp_ena_vsi(vsi)) {
680+
u32 xdp_txq = txq + vsi->num_xdp_txq;
681+
682+
wr32(hw, QINT_TQCTL(vsi->txq_map[xdp_txq]),
683+
val);
684+
}
685+
ice_flush(hw);
660686
}
661687

662688
/**

drivers/net/ethernet/intel/ice/ice_ethtool.c

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2577,6 +2577,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
25772577
{
25782578
struct ice_ring *tx_rings = NULL, *rx_rings = NULL;
25792579
struct ice_netdev_priv *np = netdev_priv(netdev);
2580+
struct ice_ring *xdp_rings = NULL;
25802581
struct ice_vsi *vsi = np->vsi;
25812582
struct ice_pf *pf = vsi->back;
25822583
int i, timeout = 50, err = 0;
@@ -2624,6 +2625,11 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
26242625
vsi->tx_rings[i]->count = new_tx_cnt;
26252626
for (i = 0; i < vsi->alloc_rxq; i++)
26262627
vsi->rx_rings[i]->count = new_rx_cnt;
2628+
if (ice_is_xdp_ena_vsi(vsi))
2629+
for (i = 0; i < vsi->num_xdp_txq; i++)
2630+
vsi->xdp_rings[i]->count = new_tx_cnt;
2631+
vsi->num_tx_desc = new_tx_cnt;
2632+
vsi->num_rx_desc = new_rx_cnt;
26272633
netdev_dbg(netdev, "Link is down, descriptor count change happens when link is brought up\n");
26282634
goto done;
26292635
}
@@ -2650,15 +2656,43 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
26502656
tx_rings[i].tx_buf = NULL;
26512657
err = ice_setup_tx_ring(&tx_rings[i]);
26522658
if (err) {
2653-
while (i) {
2654-
i--;
2659+
while (i--)
26552660
ice_clean_tx_ring(&tx_rings[i]);
2656-
}
26572661
devm_kfree(&pf->pdev->dev, tx_rings);
26582662
goto done;
26592663
}
26602664
}
26612665

2666+
if (!ice_is_xdp_ena_vsi(vsi))
2667+
goto process_rx;
2668+
2669+
/* alloc updated XDP resources */
2670+
netdev_info(netdev, "Changing XDP descriptor count from %d to %d\n",
2671+
vsi->xdp_rings[0]->count, new_tx_cnt);
2672+
2673+
xdp_rings = devm_kcalloc(&pf->pdev->dev, vsi->num_xdp_txq,
2674+
sizeof(*xdp_rings), GFP_KERNEL);
2675+
if (!xdp_rings) {
2676+
err = -ENOMEM;
2677+
goto free_tx;
2678+
}
2679+
2680+
for (i = 0; i < vsi->num_xdp_txq; i++) {
2681+
/* clone ring and setup updated count */
2682+
xdp_rings[i] = *vsi->xdp_rings[i];
2683+
xdp_rings[i].count = new_tx_cnt;
2684+
xdp_rings[i].desc = NULL;
2685+
xdp_rings[i].tx_buf = NULL;
2686+
err = ice_setup_tx_ring(&xdp_rings[i]);
2687+
if (err) {
2688+
while (i--)
2689+
ice_clean_tx_ring(&xdp_rings[i]);
2690+
devm_kfree(&pf->pdev->dev, xdp_rings);
2691+
goto free_tx;
2692+
}
2693+
ice_set_ring_xdp(&xdp_rings[i]);
2694+
}
2695+
26622696
process_rx:
26632697
if (new_rx_cnt == vsi->rx_rings[0]->count)
26642698
goto process_link;
@@ -2737,6 +2771,16 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
27372771
devm_kfree(&pf->pdev->dev, rx_rings);
27382772
}
27392773

2774+
if (xdp_rings) {
2775+
for (i = 0; i < vsi->num_xdp_txq; i++) {
2776+
ice_free_tx_ring(vsi->xdp_rings[i]);
2777+
*vsi->xdp_rings[i] = xdp_rings[i];
2778+
}
2779+
devm_kfree(&pf->pdev->dev, xdp_rings);
2780+
}
2781+
2782+
vsi->num_tx_desc = new_tx_cnt;
2783+
vsi->num_rx_desc = new_rx_cnt;
27402784
ice_up(vsi);
27412785
}
27422786
goto done;

drivers/net/ethernet/intel/ice/ice_lib.c

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ static int ice_vsi_alloc_arrays(struct ice_vsi *vsi)
4646
if (!vsi->rx_rings)
4747
goto err_rings;
4848

49-
vsi->txq_map = devm_kcalloc(&pf->pdev->dev, vsi->alloc_txq,
49+
/* XDP will have vsi->alloc_txq Tx queues as well, so double the size */
50+
vsi->txq_map = devm_kcalloc(&pf->pdev->dev, (2 * vsi->alloc_txq),
5051
sizeof(*vsi->txq_map), GFP_KERNEL);
5152

5253
if (!vsi->txq_map)
@@ -1183,6 +1184,20 @@ int ice_vsi_kill_vlan(struct ice_vsi *vsi, u16 vid)
11831184
return err;
11841185
}
11851186

1187+
/**
1188+
* ice_vsi_cfg_frame_size - setup max frame size and Rx buffer length
1189+
* @vsi: VSI
1190+
*/
1191+
void ice_vsi_cfg_frame_size(struct ice_vsi *vsi)
1192+
{
1193+
if (vsi->netdev && vsi->netdev->mtu > ETH_DATA_LEN)
1194+
vsi->max_frame = vsi->netdev->mtu + ICE_ETH_PKT_HDR_PAD;
1195+
else
1196+
vsi->max_frame = ICE_RXBUF_2048;
1197+
1198+
vsi->rx_buf_len = ICE_RXBUF_2048;
1199+
}
1200+
11861201
/**
11871202
* ice_vsi_cfg_rxqs - Configure the VSI for Rx
11881203
* @vsi: the VSI being configured
@@ -1197,13 +1212,7 @@ int ice_vsi_cfg_rxqs(struct ice_vsi *vsi)
11971212
if (vsi->type == ICE_VSI_VF)
11981213
goto setup_rings;
11991214

1200-
if (vsi->netdev && vsi->netdev->mtu > ETH_DATA_LEN)
1201-
vsi->max_frame = vsi->netdev->mtu +
1202-
ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
1203-
else
1204-
vsi->max_frame = ICE_RXBUF_2048;
1205-
1206-
vsi->rx_buf_len = ICE_RXBUF_2048;
1215+
ice_vsi_cfg_frame_size(vsi);
12071216
setup_rings:
12081217
/* set up individual rings */
12091218
for (i = 0; i < vsi->num_rxq; i++) {
@@ -1265,6 +1274,18 @@ int ice_vsi_cfg_lan_txqs(struct ice_vsi *vsi)
12651274
return ice_vsi_cfg_txqs(vsi, vsi->tx_rings);
12661275
}
12671276

1277+
/**
1278+
* ice_vsi_cfg_xdp_txqs - Configure Tx queues dedicated for XDP in given VSI
1279+
* @vsi: the VSI being configured
1280+
*
1281+
* Return 0 on success and a negative value on error
1282+
* Configure the Tx queues dedicated for XDP in given VSI for operation.
1283+
*/
1284+
int ice_vsi_cfg_xdp_txqs(struct ice_vsi *vsi)
1285+
{
1286+
return ice_vsi_cfg_txqs(vsi, vsi->xdp_rings);
1287+
}
1288+
12681289
/**
12691290
* ice_intrl_usec_to_reg - convert interrupt rate limit to register value
12701291
* @intrl: interrupt rate limit in usecs
@@ -1488,6 +1509,15 @@ ice_vsi_stop_lan_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src,
14881509
return ice_vsi_stop_tx_rings(vsi, rst_src, rel_vmvf_num, vsi->tx_rings);
14891510
}
14901511

1512+
/**
1513+
* ice_vsi_stop_xdp_tx_rings - Disable XDP Tx rings
1514+
* @vsi: the VSI being configured
1515+
*/
1516+
int ice_vsi_stop_xdp_tx_rings(struct ice_vsi *vsi)
1517+
{
1518+
return ice_vsi_stop_tx_rings(vsi, ICE_NO_RESET, 0, vsi->xdp_rings);
1519+
}
1520+
14911521
/**
14921522
* ice_cfg_vlan_pruning - enable or disable VLAN pruning on the VSI
14931523
* @vsi: VSI to enable or disable VLAN pruning on
@@ -1885,6 +1915,11 @@ static void ice_vsi_release_msix(struct ice_vsi *vsi)
18851915
wr32(hw, GLINT_ITR(ICE_IDX_ITR1, reg_idx), 0);
18861916
for (q = 0; q < q_vector->num_ring_tx; q++) {
18871917
wr32(hw, QINT_TQCTL(vsi->txq_map[txq]), 0);
1918+
if (ice_is_xdp_ena_vsi(vsi)) {
1919+
u32 xdp_txq = txq + vsi->num_xdp_txq;
1920+
1921+
wr32(hw, QINT_TQCTL(vsi->txq_map[xdp_txq]), 0);
1922+
}
18881923
txq++;
18891924
}
18901925

@@ -2259,6 +2294,11 @@ int ice_vsi_rebuild(struct ice_vsi *vsi)
22592294
vsi->base_vector = 0;
22602295
}
22612296

2297+
if (ice_is_xdp_ena_vsi(vsi))
2298+
/* return value check can be skipped here, it always returns
2299+
* 0 if reset is in progress
2300+
*/
2301+
ice_destroy_xdp_rings(vsi);
22622302
ice_vsi_put_qs(vsi);
22632303
ice_vsi_clear_rings(vsi);
22642304
ice_vsi_free_arrays(vsi);
@@ -2299,6 +2339,12 @@ int ice_vsi_rebuild(struct ice_vsi *vsi)
22992339
goto err_vectors;
23002340

23012341
ice_vsi_map_rings_to_vectors(vsi);
2342+
if (ice_is_xdp_ena_vsi(vsi)) {
2343+
vsi->num_xdp_txq = vsi->alloc_txq;
2344+
ret = ice_prepare_xdp_rings(vsi, vsi->xdp_prog);
2345+
if (ret)
2346+
goto err_vectors;
2347+
}
23022348
/* Do not exit if configuring RSS had an issue, at least
23032349
* receive traffic on first queue. Hence no need to capture
23042350
* return value
@@ -2325,9 +2371,13 @@ int ice_vsi_rebuild(struct ice_vsi *vsi)
23252371
}
23262372

23272373
/* configure VSI nodes based on number of queues and TC's */
2328-
for (i = 0; i < vsi->tc_cfg.numtc; i++)
2374+
for (i = 0; i < vsi->tc_cfg.numtc; i++) {
23292375
max_txqs[i] = vsi->alloc_txq;
23302376

2377+
if (ice_is_xdp_ena_vsi(vsi))
2378+
max_txqs[i] += vsi->num_xdp_txq;
2379+
}
2380+
23312381
status = ice_cfg_vsi_lan(vsi->port_info, vsi->idx, vsi->tc_cfg.ena_tc,
23322382
max_txqs);
23332383
if (status) {

drivers/net/ethernet/intel/ice/ice_lib.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ int
3636
ice_vsi_stop_lan_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src,
3737
u16 rel_vmvf_num);
3838

39+
int ice_vsi_cfg_xdp_txqs(struct ice_vsi *vsi);
40+
41+
int ice_vsi_stop_xdp_tx_rings(struct ice_vsi *vsi);
42+
3943
int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena, bool vlan_promisc);
4044

4145
void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create);
@@ -79,6 +83,8 @@ void ice_vsi_free_tx_rings(struct ice_vsi *vsi);
7983

8084
int ice_vsi_manage_rss_lut(struct ice_vsi *vsi, bool ena);
8185

86+
void ice_vsi_cfg_frame_size(struct ice_vsi *vsi);
87+
8288
u32 ice_intrl_usec_to_reg(u8 intrl, u8 gran);
8389

8490
char *ice_nvm_version_str(struct ice_hw *hw);

0 commit comments

Comments
 (0)