Skip to content

Commit ec706a8

Browse files
fomichevAlexei Starovoitov
authored andcommitted
net/mlx5e: Implement AF_XDP TX timestamp and checksum offload
TX timestamp: - requires passing clock, not sure I'm passing the correct one (from cq->mdev), but the timestamp value looks convincing TX checksum: - looks like device does packet parsing (and doesn't accept custom start/offset), so I'm ignoring user offsets Cc: Saeed Mahameed <[email protected]> Signed-off-by: Stanislav Fomichev <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 9276009 commit ec706a8

File tree

5 files changed

+89
-16
lines changed

5 files changed

+89
-16
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,10 +484,12 @@ struct mlx5e_xdp_info_fifo {
484484

485485
struct mlx5e_xdpsq;
486486
struct mlx5e_xmit_data;
487+
struct xsk_tx_metadata;
487488
typedef int (*mlx5e_fp_xmit_xdp_frame_check)(struct mlx5e_xdpsq *);
488489
typedef bool (*mlx5e_fp_xmit_xdp_frame)(struct mlx5e_xdpsq *,
489490
struct mlx5e_xmit_data *,
490-
int);
491+
int,
492+
struct xsk_tx_metadata *);
491493

492494
struct mlx5e_xdpsq {
493495
/* data path */

drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ mlx5e_xmit_xdp_buff(struct mlx5e_xdpsq *sq, struct mlx5e_rq *rq,
103103
xdptxd->dma_addr = dma_addr;
104104

105105
if (unlikely(!INDIRECT_CALL_2(sq->xmit_xdp_frame, mlx5e_xmit_xdp_frame_mpwqe,
106-
mlx5e_xmit_xdp_frame, sq, xdptxd, 0)))
106+
mlx5e_xmit_xdp_frame, sq, xdptxd, 0, NULL)))
107107
return false;
108108

109109
/* xmit_mode == MLX5E_XDP_XMIT_MODE_FRAME */
@@ -145,7 +145,7 @@ mlx5e_xmit_xdp_buff(struct mlx5e_xdpsq *sq, struct mlx5e_rq *rq,
145145
xdptxd->dma_addr = dma_addr;
146146

147147
if (unlikely(!INDIRECT_CALL_2(sq->xmit_xdp_frame, mlx5e_xmit_xdp_frame_mpwqe,
148-
mlx5e_xmit_xdp_frame, sq, xdptxd, 0)))
148+
mlx5e_xmit_xdp_frame, sq, xdptxd, 0, NULL)))
149149
return false;
150150

151151
/* xmit_mode == MLX5E_XDP_XMIT_MODE_PAGE */
@@ -261,6 +261,37 @@ const struct xdp_metadata_ops mlx5e_xdp_metadata_ops = {
261261
.xmo_rx_hash = mlx5e_xdp_rx_hash,
262262
};
263263

264+
struct mlx5e_xsk_tx_complete {
265+
struct mlx5_cqe64 *cqe;
266+
struct mlx5e_cq *cq;
267+
};
268+
269+
static u64 mlx5e_xsk_fill_timestamp(void *_priv)
270+
{
271+
struct mlx5e_xsk_tx_complete *priv = _priv;
272+
u64 ts;
273+
274+
ts = get_cqe_ts(priv->cqe);
275+
276+
if (mlx5_is_real_time_rq(priv->cq->mdev) || mlx5_is_real_time_sq(priv->cq->mdev))
277+
return mlx5_real_time_cyc2time(&priv->cq->mdev->clock, ts);
278+
279+
return mlx5_timecounter_cyc2time(&priv->cq->mdev->clock, ts);
280+
}
281+
282+
static void mlx5e_xsk_request_checksum(u16 csum_start, u16 csum_offset, void *priv)
283+
{
284+
struct mlx5_wqe_eth_seg *eseg = priv;
285+
286+
/* HW/FW is doing parsing, so offsets are largely ignored. */
287+
eseg->cs_flags |= MLX5_ETH_WQE_L3_CSUM | MLX5_ETH_WQE_L4_CSUM;
288+
}
289+
290+
const struct xsk_tx_metadata_ops mlx5e_xsk_tx_metadata_ops = {
291+
.tmo_fill_timestamp = mlx5e_xsk_fill_timestamp,
292+
.tmo_request_checksum = mlx5e_xsk_request_checksum,
293+
};
294+
264295
/* returns true if packet was consumed by xdp */
265296
bool mlx5e_xdp_handle(struct mlx5e_rq *rq,
266297
struct bpf_prog *prog, struct mlx5e_xdp_buff *mxbuf)
@@ -398,11 +429,11 @@ INDIRECT_CALLABLE_SCOPE int mlx5e_xmit_xdp_frame_check_mpwqe(struct mlx5e_xdpsq
398429

399430
INDIRECT_CALLABLE_SCOPE bool
400431
mlx5e_xmit_xdp_frame(struct mlx5e_xdpsq *sq, struct mlx5e_xmit_data *xdptxd,
401-
int check_result);
432+
int check_result, struct xsk_tx_metadata *meta);
402433

403434
INDIRECT_CALLABLE_SCOPE bool
404435
mlx5e_xmit_xdp_frame_mpwqe(struct mlx5e_xdpsq *sq, struct mlx5e_xmit_data *xdptxd,
405-
int check_result)
436+
int check_result, struct xsk_tx_metadata *meta)
406437
{
407438
struct mlx5e_tx_mpwqe *session = &sq->mpwqe;
408439
struct mlx5e_xdpsq_stats *stats = sq->stats;
@@ -420,7 +451,7 @@ mlx5e_xmit_xdp_frame_mpwqe(struct mlx5e_xdpsq *sq, struct mlx5e_xmit_data *xdptx
420451
*/
421452
if (unlikely(sq->mpwqe.wqe))
422453
mlx5e_xdp_mpwqe_complete(sq);
423-
return mlx5e_xmit_xdp_frame(sq, xdptxd, 0);
454+
return mlx5e_xmit_xdp_frame(sq, xdptxd, 0, meta);
424455
}
425456
if (!xdptxd->len) {
426457
skb_frag_t *frag = &xdptxdf->sinfo->frags[0];
@@ -450,6 +481,7 @@ mlx5e_xmit_xdp_frame_mpwqe(struct mlx5e_xdpsq *sq, struct mlx5e_xmit_data *xdptx
450481
* and it's safe to complete it at any time.
451482
*/
452483
mlx5e_xdp_mpwqe_session_start(sq);
484+
xsk_tx_metadata_request(meta, &mlx5e_xsk_tx_metadata_ops, &session->wqe->eth);
453485
}
454486

455487
mlx5e_xdp_mpwqe_add_dseg(sq, p, stats);
@@ -480,7 +512,7 @@ INDIRECT_CALLABLE_SCOPE int mlx5e_xmit_xdp_frame_check(struct mlx5e_xdpsq *sq)
480512

481513
INDIRECT_CALLABLE_SCOPE bool
482514
mlx5e_xmit_xdp_frame(struct mlx5e_xdpsq *sq, struct mlx5e_xmit_data *xdptxd,
483-
int check_result)
515+
int check_result, struct xsk_tx_metadata *meta)
484516
{
485517
struct mlx5e_xmit_data_frags *xdptxdf =
486518
container_of(xdptxd, struct mlx5e_xmit_data_frags, xd);
@@ -599,6 +631,8 @@ mlx5e_xmit_xdp_frame(struct mlx5e_xdpsq *sq, struct mlx5e_xmit_data *xdptxd,
599631
sq->pc++;
600632
}
601633

634+
xsk_tx_metadata_request(meta, &mlx5e_xsk_tx_metadata_ops, eseg);
635+
602636
sq->doorbell_cseg = cseg;
603637

604638
stats->xmit++;
@@ -608,7 +642,9 @@ mlx5e_xmit_xdp_frame(struct mlx5e_xdpsq *sq, struct mlx5e_xmit_data *xdptxd,
608642
static void mlx5e_free_xdpsq_desc(struct mlx5e_xdpsq *sq,
609643
struct mlx5e_xdp_wqe_info *wi,
610644
u32 *xsk_frames,
611-
struct xdp_frame_bulk *bq)
645+
struct xdp_frame_bulk *bq,
646+
struct mlx5e_cq *cq,
647+
struct mlx5_cqe64 *cqe)
612648
{
613649
struct mlx5e_xdp_info_fifo *xdpi_fifo = &sq->db.xdpi_fifo;
614650
u16 i;
@@ -668,10 +704,24 @@ static void mlx5e_free_xdpsq_desc(struct mlx5e_xdpsq *sq,
668704

669705
break;
670706
}
671-
case MLX5E_XDP_XMIT_MODE_XSK:
707+
case MLX5E_XDP_XMIT_MODE_XSK: {
672708
/* AF_XDP send */
709+
struct xsk_tx_metadata_compl *compl = NULL;
710+
struct mlx5e_xsk_tx_complete priv = {
711+
.cqe = cqe,
712+
.cq = cq,
713+
};
714+
715+
if (xp_tx_metadata_enabled(sq->xsk_pool)) {
716+
xdpi = mlx5e_xdpi_fifo_pop(xdpi_fifo);
717+
compl = &xdpi.xsk_meta;
718+
719+
xsk_tx_metadata_complete(compl, &mlx5e_xsk_tx_metadata_ops, &priv);
720+
}
721+
673722
(*xsk_frames)++;
674723
break;
724+
}
675725
default:
676726
WARN_ON_ONCE(true);
677727
}
@@ -720,7 +770,7 @@ bool mlx5e_poll_xdpsq_cq(struct mlx5e_cq *cq)
720770

721771
sqcc += wi->num_wqebbs;
722772

723-
mlx5e_free_xdpsq_desc(sq, wi, &xsk_frames, &bq);
773+
mlx5e_free_xdpsq_desc(sq, wi, &xsk_frames, &bq, cq, cqe);
724774
} while (!last_wqe);
725775

726776
if (unlikely(get_cqe_opcode(cqe) != MLX5_CQE_REQ)) {
@@ -767,7 +817,7 @@ void mlx5e_free_xdpsq_descs(struct mlx5e_xdpsq *sq)
767817

768818
sq->cc += wi->num_wqebbs;
769819

770-
mlx5e_free_xdpsq_desc(sq, wi, &xsk_frames, &bq);
820+
mlx5e_free_xdpsq_desc(sq, wi, &xsk_frames, &bq, NULL, NULL);
771821
}
772822

773823
xdp_flush_frame_bulk(&bq);
@@ -840,7 +890,7 @@ int mlx5e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
840890
}
841891

842892
ret = INDIRECT_CALL_2(sq->xmit_xdp_frame, mlx5e_xmit_xdp_frame_mpwqe,
843-
mlx5e_xmit_xdp_frame, sq, xdptxd, 0);
893+
mlx5e_xmit_xdp_frame, sq, xdptxd, 0, NULL);
844894
if (unlikely(!ret)) {
845895
int j;
846896

drivers/net/ethernet/mellanox/mlx5/core/en/xdp.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#define __MLX5_EN_XDP_H__
3434

3535
#include <linux/indirect_call_wrapper.h>
36+
#include <net/xdp_sock.h>
3637

3738
#include "en.h"
3839
#include "en/txrx.h"
@@ -82,7 +83,7 @@ enum mlx5e_xdp_xmit_mode {
8283
* num, page_1, page_2, ... , page_num.
8384
*
8485
* MLX5E_XDP_XMIT_MODE_XSK:
85-
* none.
86+
* frame.xsk_meta.
8687
*/
8788
#define MLX5E_XDP_FIFO_ENTRIES2DS_MAX_RATIO 4
8889

@@ -97,6 +98,7 @@ union mlx5e_xdp_info {
9798
u8 num;
9899
struct page *page;
99100
} page;
101+
struct xsk_tx_metadata_compl xsk_meta;
100102
};
101103

102104
struct mlx5e_xsk_param;
@@ -112,13 +114,16 @@ int mlx5e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
112114
u32 flags);
113115

114116
extern const struct xdp_metadata_ops mlx5e_xdp_metadata_ops;
117+
extern const struct xsk_tx_metadata_ops mlx5e_xsk_tx_metadata_ops;
115118

116119
INDIRECT_CALLABLE_DECLARE(bool mlx5e_xmit_xdp_frame_mpwqe(struct mlx5e_xdpsq *sq,
117120
struct mlx5e_xmit_data *xdptxd,
118-
int check_result));
121+
int check_result,
122+
struct xsk_tx_metadata *meta));
119123
INDIRECT_CALLABLE_DECLARE(bool mlx5e_xmit_xdp_frame(struct mlx5e_xdpsq *sq,
120124
struct mlx5e_xmit_data *xdptxd,
121-
int check_result));
125+
int check_result,
126+
struct xsk_tx_metadata *meta));
122127
INDIRECT_CALLABLE_DECLARE(int mlx5e_xmit_xdp_frame_check_mpwqe(struct mlx5e_xdpsq *sq));
123128
INDIRECT_CALLABLE_DECLARE(int mlx5e_xmit_xdp_frame_check(struct mlx5e_xdpsq *sq));
124129

drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,16 @@ static void mlx5e_xsk_tx_post_err(struct mlx5e_xdpsq *sq,
5555

5656
nopwqe = mlx5e_post_nop(&sq->wq, sq->sqn, &sq->pc);
5757
mlx5e_xdpi_fifo_push(&sq->db.xdpi_fifo, *xdpi);
58+
if (xp_tx_metadata_enabled(sq->xsk_pool))
59+
mlx5e_xdpi_fifo_push(&sq->db.xdpi_fifo,
60+
(union mlx5e_xdp_info) { .xsk_meta = {} });
5861
sq->doorbell_cseg = &nopwqe->ctrl;
5962
}
6063

6164
bool mlx5e_xsk_tx(struct mlx5e_xdpsq *sq, unsigned int budget)
6265
{
6366
struct xsk_buff_pool *pool = sq->xsk_pool;
67+
struct xsk_tx_metadata *meta = NULL;
6468
union mlx5e_xdp_info xdpi;
6569
bool work_done = true;
6670
bool flush = false;
@@ -93,19 +97,30 @@ bool mlx5e_xsk_tx(struct mlx5e_xdpsq *sq, unsigned int budget)
9397
xdptxd.dma_addr = xsk_buff_raw_get_dma(pool, desc.addr);
9498
xdptxd.data = xsk_buff_raw_get_data(pool, desc.addr);
9599
xdptxd.len = desc.len;
100+
meta = xsk_buff_get_metadata(pool, desc.addr);
96101

97102
xsk_buff_raw_dma_sync_for_device(pool, xdptxd.dma_addr, xdptxd.len);
98103

99104
ret = INDIRECT_CALL_2(sq->xmit_xdp_frame, mlx5e_xmit_xdp_frame_mpwqe,
100105
mlx5e_xmit_xdp_frame, sq, &xdptxd,
101-
check_result);
106+
check_result, meta);
102107
if (unlikely(!ret)) {
103108
if (sq->mpwqe.wqe)
104109
mlx5e_xdp_mpwqe_complete(sq);
105110

106111
mlx5e_xsk_tx_post_err(sq, &xdpi);
107112
} else {
108113
mlx5e_xdpi_fifo_push(&sq->db.xdpi_fifo, xdpi);
114+
if (xp_tx_metadata_enabled(sq->xsk_pool)) {
115+
struct xsk_tx_metadata_compl compl;
116+
117+
xsk_tx_metadata_to_compl(meta, &compl);
118+
XSK_TX_COMPL_FITS(void *);
119+
120+
mlx5e_xdpi_fifo_push(&sq->db.xdpi_fifo,
121+
(union mlx5e_xdp_info)
122+
{ .xsk_meta = compl });
123+
}
109124
}
110125

111126
flush = true;

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5164,6 +5164,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
51645164

51655165
netdev->netdev_ops = &mlx5e_netdev_ops;
51665166
netdev->xdp_metadata_ops = &mlx5e_xdp_metadata_ops;
5167+
netdev->xsk_tx_metadata_ops = &mlx5e_xsk_tx_metadata_ops;
51675168

51685169
mlx5e_dcbnl_build_netdev(netdev);
51695170

0 commit comments

Comments
 (0)