Skip to content

Commit 75eaae1

Browse files
praveenkaligineedidavem330
authored andcommitted
gve: Add XDP DROP and TX support for GQI-QPL format
Add support for XDP PASS, DROP and TX actions. This patch contains the following changes: 1) Support installing/uninstalling XDP program 2) Add dedicated XDP TX queues 3) Add support for XDP DROP action 4) Add support for XDP TX action Signed-off-by: Praveen Kaligineedi <[email protected]> Reviewed-by: Jeroen de Borst <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7fc2bf7 commit 75eaae1

File tree

5 files changed

+687
-39
lines changed

5 files changed

+687
-39
lines changed

drivers/net/ethernet/google/gve/gve.h

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@
4747

4848
#define GVE_RX_BUFFER_SIZE_DQO 2048
4949

50+
#define GVE_XDP_ACTIONS 5
51+
52+
#define GVE_TX_MAX_HEADER_SIZE 182
53+
5054
/* Each slot in the desc ring has a 1:1 mapping to a slot in the data ring */
5155
struct gve_rx_desc_queue {
5256
struct gve_rx_desc *desc_ring; /* the descriptor ring */
@@ -230,14 +234,19 @@ struct gve_rx_ring {
230234
u64 rx_frag_flip_cnt; /* free-running count of rx segments where page_flip was used */
231235
u64 rx_frag_copy_cnt; /* free-running count of rx segments copied */
232236
u64 rx_frag_alloc_cnt; /* free-running count of rx page allocations */
233-
237+
u64 xdp_tx_errors;
238+
u64 xdp_redirect_errors;
239+
u64 xdp_actions[GVE_XDP_ACTIONS];
234240
u32 q_num; /* queue index */
235241
u32 ntfy_id; /* notification block index */
236242
struct gve_queue_resources *q_resources; /* head and tail pointer idx */
237243
dma_addr_t q_resources_bus; /* dma address for the queue resources */
238244
struct u64_stats_sync statss; /* sync stats for 32bit archs */
239245

240246
struct gve_rx_ctx ctx; /* Info for packet currently being processed in this ring. */
247+
248+
/* XDP stuff */
249+
struct xdp_rxq_info xdp_rxq;
241250
};
242251

243252
/* A TX desc ring entry */
@@ -259,6 +268,9 @@ struct gve_tx_iovec {
259268
*/
260269
struct gve_tx_buffer_state {
261270
struct sk_buff *skb; /* skb for this pkt */
271+
struct {
272+
u16 size; /* size of xmitted xdp pkt */
273+
} xdp;
262274
union {
263275
struct gve_tx_iovec iov[GVE_TX_MAX_IOVEC]; /* segments of this pkt */
264276
struct {
@@ -526,9 +538,11 @@ struct gve_priv {
526538
u16 rx_data_slot_cnt; /* rx buffer length */
527539
u64 max_registered_pages;
528540
u64 num_registered_pages; /* num pages registered with NIC */
541+
struct bpf_prog *xdp_prog; /* XDP BPF program */
529542
u32 rx_copybreak; /* copy packets smaller than this */
530543
u16 default_num_queues; /* default num queues to set up */
531544

545+
u16 num_xdp_queues;
532546
struct gve_queue_config tx_cfg;
533547
struct gve_queue_config rx_cfg;
534548
struct gve_qpl_config qpl_cfg; /* map used QPL ids */
@@ -785,7 +799,17 @@ static inline u32 gve_num_tx_qpls(struct gve_priv *priv)
785799
if (priv->queue_format != GVE_GQI_QPL_FORMAT)
786800
return 0;
787801

788-
return priv->tx_cfg.num_queues;
802+
return priv->tx_cfg.num_queues + priv->num_xdp_queues;
803+
}
804+
805+
/* Returns the number of XDP tx queue page lists
806+
*/
807+
static inline u32 gve_num_xdp_qpls(struct gve_priv *priv)
808+
{
809+
if (priv->queue_format != GVE_GQI_QPL_FORMAT)
810+
return 0;
811+
812+
return priv->num_xdp_queues;
789813
}
790814

791815
/* Returns the number of rx queue page lists
@@ -874,7 +898,17 @@ static inline bool gve_is_gqi(struct gve_priv *priv)
874898

875899
static inline u32 gve_num_tx_queues(struct gve_priv *priv)
876900
{
877-
return priv->tx_cfg.num_queues;
901+
return priv->tx_cfg.num_queues + priv->num_xdp_queues;
902+
}
903+
904+
static inline u32 gve_xdp_tx_queue_id(struct gve_priv *priv, u32 queue_id)
905+
{
906+
return priv->tx_cfg.num_queues + queue_id;
907+
}
908+
909+
static inline u32 gve_xdp_tx_start_queue_id(struct gve_priv *priv)
910+
{
911+
return gve_xdp_tx_queue_id(priv, 0);
878912
}
879913

880914
/* buffers */
@@ -885,7 +919,11 @@ void gve_free_page(struct device *dev, struct page *page, dma_addr_t dma,
885919
enum dma_data_direction);
886920
/* tx handling */
887921
netdev_tx_t gve_tx(struct sk_buff *skb, struct net_device *dev);
922+
int gve_xdp_xmit_one(struct gve_priv *priv, struct gve_tx_ring *tx,
923+
void *data, int len);
924+
void gve_xdp_tx_flush(struct gve_priv *priv, u32 xdp_qid);
888925
bool gve_tx_poll(struct gve_notify_block *block, int budget);
926+
bool gve_xdp_poll(struct gve_notify_block *block, int budget);
889927
int gve_tx_alloc_rings(struct gve_priv *priv, int start_id, int num_rings);
890928
void gve_tx_free_rings_gqi(struct gve_priv *priv, int start_id, int num_rings);
891929
u32 gve_tx_load_event_counter(struct gve_priv *priv,

drivers/net/ethernet/google/gve/gve_ethtool.c

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ static u32 gve_get_msglevel(struct net_device *netdev)
3434
return priv->msg_enable;
3535
}
3636

37+
/* For the following stats column string names, make sure the order
38+
* matches how it is filled in the code. For xdp_aborted, xdp_drop,
39+
* xdp_pass, xdp_tx, xdp_redirect, make sure it also matches the order
40+
* as declared in enum xdp_action inside file uapi/linux/bpf.h .
41+
*/
3742
static const char gve_gstrings_main_stats[][ETH_GSTRING_LEN] = {
3843
"rx_packets", "tx_packets", "rx_bytes", "tx_bytes",
3944
"rx_dropped", "tx_dropped", "tx_timeouts",
@@ -49,6 +54,9 @@ static const char gve_gstrings_rx_stats[][ETH_GSTRING_LEN] = {
4954
"rx_dropped_pkt[%u]", "rx_copybreak_pkt[%u]", "rx_copied_pkt[%u]",
5055
"rx_queue_drop_cnt[%u]", "rx_no_buffers_posted[%u]",
5156
"rx_drops_packet_over_mru[%u]", "rx_drops_invalid_checksum[%u]",
57+
"rx_xdp_aborted[%u]", "rx_xdp_drop[%u]", "rx_xdp_pass[%u]",
58+
"rx_xdp_tx[%u]", "rx_xdp_redirect[%u]",
59+
"rx_xdp_tx_errors[%u]", "rx_xdp_redirect_errors[%u]",
5260
};
5361

5462
static const char gve_gstrings_tx_stats[][ETH_GSTRING_LEN] = {
@@ -289,14 +297,25 @@ gve_get_ethtool_stats(struct net_device *netdev,
289297
if (skip_nic_stats) {
290298
/* skip NIC rx stats */
291299
i += NIC_RX_STATS_REPORT_NUM;
292-
continue;
293-
}
294-
for (j = 0; j < NIC_RX_STATS_REPORT_NUM; j++) {
295-
u64 value =
296-
be64_to_cpu(report_stats[rx_qid_to_stats_idx[ring] + j].value);
300+
} else {
301+
stats_idx = rx_qid_to_stats_idx[ring];
302+
for (j = 0; j < NIC_RX_STATS_REPORT_NUM; j++) {
303+
u64 value =
304+
be64_to_cpu(report_stats[stats_idx + j].value);
297305

298-
data[i++] = value;
306+
data[i++] = value;
307+
}
299308
}
309+
/* XDP rx counters */
310+
do {
311+
start = u64_stats_fetch_begin(&priv->rx[ring].statss);
312+
for (j = 0; j < GVE_XDP_ACTIONS; j++)
313+
data[i + j] = rx->xdp_actions[j];
314+
data[i + j++] = rx->xdp_tx_errors;
315+
data[i + j++] = rx->xdp_redirect_errors;
316+
} while (u64_stats_fetch_retry(&priv->rx[ring].statss,
317+
start));
318+
i += GVE_XDP_ACTIONS + 2; /* XDP rx counters */
300319
}
301320
} else {
302321
i += priv->rx_cfg.num_queues * NUM_GVE_RX_CNTS;
@@ -418,6 +437,12 @@ static int gve_set_channels(struct net_device *netdev,
418437
if (!new_rx || !new_tx)
419438
return -EINVAL;
420439

440+
if (priv->num_xdp_queues &&
441+
(new_tx != new_rx || (2 * new_tx > priv->tx_cfg.max_queues))) {
442+
dev_err(&priv->pdev->dev, "XDP load failed: The number of configured RX queues should be equal to the number of configured TX queues and the number of configured RX/TX queues should be less than or equal to half the maximum number of RX/TX queues");
443+
return -EINVAL;
444+
}
445+
421446
if (!netif_carrier_ok(netdev)) {
422447
priv->tx_cfg.num_queues = new_tx;
423448
priv->rx_cfg.num_queues = new_rx;

0 commit comments

Comments
 (0)