Skip to content

Commit da62bd8

Browse files
ixgbevf: multi-buffer AF_XDP Tx
Transmitting multi-buffer AF_XDP packets is not very straightforward given HW limitations in ixgbevf, namely that the first data descriptor must contain the length of the whole packet. Use private data of an sqe to store the length of an unfinished packet so far and the first descriptor index. Once EoP zero-copy descriptor is processed, write the accumulated length into the saved first descriptor. Signed-off-by: Larysa Zaremba <larysa.zaremba@intel.com>
1 parent 18c5c45 commit da62bd8

4 files changed

Lines changed: 62 additions & 9 deletions

File tree

drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4314,7 +4314,7 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
43144314
NETIF_F_HW_VLAN_CTAG_TX;
43154315

43164316
netdev->priv_flags |= IFF_UNICAST_FLT;
4317-
libeth_xdp_set_features_noredir(netdev, NULL, 1, NULL);
4317+
libeth_xdp_set_features_noredir(netdev, NULL, IXGBEVF_XSK_MAX_ZC_FRAGS);
43184318

43194319
/* MTU range: 68 - 1504 or 9710 */
43204320
netdev->min_mtu = ETH_MIN_MTU;

drivers/net/ethernet/intel/ixgbevf/ixgbevf_txrx_lib.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ static inline void ixgbevf_xdp_rs_and_bump(void *xdpsq, bool sent, bool flush)
3030
xdp_ring->xdp_sqes[xdp_ring->cached_ntu].rs_idx = ltu + 1;
3131
xdp_ring->cached_ntu = xdp_ring->next_to_use;
3232

33+
/* In case the packet was interrupted, discard it */
34+
xdp_ring->xdp_sqes[ltu].priv = 0;
35+
3336
/* Finish descriptor writes before bumping tail */
3437
wmb();
3538
ixgbevf_write_tail(xdp_ring, xdp_ring->next_to_use);

drivers/net/ethernet/intel/ixgbevf/ixgbevf_xsk.c

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,24 +133,73 @@ void ixgbevf_rx_xsk_ring_free_buffs(struct ixgbevf_ring *rx_ring)
133133
}
134134
}
135135

136+
struct ixgbevf_zc_sqe_priv {
137+
u32 first_desc;
138+
u32 len;
139+
};
140+
141+
static_assert(sizeof(struct ixgbevf_zc_sqe_priv) <=
142+
sizeof(typeof_member(struct libeth_sqe, priv)));
143+
136144
static void ixgbevf_xsk_xmit_desc(struct libeth_xdp_tx_desc desc, u32 i,
137145
const struct libeth_xdpsq *sq, u64 priv)
138146
{
139-
union ixgbe_adv_tx_desc *tx_desc =
140-
&((union ixgbe_adv_tx_desc *)sq->descs)[i];
147+
union ixgbe_adv_tx_desc *descs = sq->descs, *tx_desc = &descs[i];
148+
u32 ltu = (i ? : sq->count) - 1;
141149

142150
u32 cmd_type = IXGBE_ADVTXD_DTYP_DATA |
143151
IXGBE_ADVTXD_DCMD_DEXT |
144152
IXGBE_ADVTXD_DCMD_IFCS |
145-
IXGBE_TXD_CMD_EOP |
146153
desc.len;
147154

148-
tx_desc->read.olinfo_status =
149-
cpu_to_le32((desc.len << IXGBE_ADVTXD_PAYLEN_SHIFT) |
150-
IXGBE_ADVTXD_CC);
151-
152155
tx_desc->read.buffer_addr = cpu_to_le64(desc.addr);
153-
tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type);
156+
157+
if (likely((desc.flags & LIBETH_XDP_TX_LAST) && !sq->sqes[ltu].priv)) {
158+
tx_desc->read.olinfo_status =
159+
cpu_to_le32((desc.len << IXGBE_ADVTXD_PAYLEN_SHIFT) |
160+
IXGBE_ADVTXD_CC);
161+
tx_desc->read.cmd_type_len =
162+
cpu_to_le32(cmd_type | IXGBE_TXD_CMD_EOP);
163+
return;
164+
}
165+
166+
/* No previous packet */
167+
if (!sq->sqes[ltu].priv) {
168+
struct ixgbevf_zc_sqe_priv *sqe_priv =
169+
(void *)&sq->sqes[i].priv;
170+
171+
sqe_priv->first_desc = i;
172+
sqe_priv->len = desc.len;
173+
174+
tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type);
175+
176+
return;
177+
}
178+
179+
if (sq->sqes[ltu].priv) {
180+
struct ixgbevf_zc_sqe_priv *sqe_priv =
181+
(void *)&sq->sqes[i].priv;
182+
183+
sq->sqes[i].priv = sq->sqes[ltu].priv;
184+
sq->sqes[ltu].priv = 0;
185+
sqe_priv->len += desc.len;
186+
187+
if (desc.flags & LIBETH_XDP_TX_LAST) {
188+
union ixgbe_adv_tx_desc *first_desc =
189+
&descs[sqe_priv->first_desc];
190+
191+
first_desc->read.olinfo_status =
192+
cpu_to_le32((sqe_priv->len <<
193+
IXGBE_ADVTXD_PAYLEN_SHIFT) |
194+
IXGBE_ADVTXD_CC);
195+
tx_desc->read.cmd_type_len =
196+
cpu_to_le32(cmd_type | IXGBE_TXD_CMD_EOP);
197+
cmd_type |= IXGBE_TXD_CMD_EOP;
198+
sq->sqes[i].priv = 0;
199+
}
200+
201+
tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type);
202+
}
154203
}
155204

156205
LIBETH_XDP_DEFINE_START();

drivers/net/ethernet/intel/ixgbevf/ixgbevf_xsk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
/* Process compeletions as soon as possible */
88
#define IXGBEVF_XSK_TX_CLEAN_THRESH(r) ((r)->count - 1)
9+
#define IXGBEVF_XSK_MAX_ZC_FRAGS 18
910

1011
int ixgbevf_setup_xsk_pool(struct ixgbevf_adapter *adapter,
1112
struct xsk_buff_pool *pool, u16 qid);

0 commit comments

Comments
 (0)