Skip to content

Commit 1679c72

Browse files
ecree-solarflaredavem330
authored andcommitted
sfc: de-indirect TSO handling
Remove the tx_queue->handle_tso function pointer, and just use tx_queue->tso_version to decide which function to call, thus removing an indirect call from the fast path. Instead of passing a tso_v2 flag to efx_mcdi_tx_init(), set the desired tx_queue->tso_version before calling it. In efx_mcdi_tx_init(), report back failure to obtain a TSOv2 context by setting tx_queue->tso_version to 0, which will cause the TX path to use the GSO-based fallback. Signed-off-by: Edward Cree <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent fe0c406 commit 1679c72

File tree

9 files changed

+46
-37
lines changed

9 files changed

+46
-37
lines changed

drivers/net/ethernet/sfc/ef10.c

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2175,9 +2175,8 @@ static inline void efx_ef10_push_tx_desc(struct efx_tx_queue *tx_queue,
21752175

21762176
/* Add Firmware-Assisted TSO v2 option descriptors to a queue.
21772177
*/
2178-
static int efx_ef10_tx_tso_desc(struct efx_tx_queue *tx_queue,
2179-
struct sk_buff *skb,
2180-
bool *data_mapped)
2178+
int efx_ef10_tx_tso_desc(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
2179+
bool *data_mapped)
21812180
{
21822181
struct efx_tx_buffer *buffer;
21832182
struct tcphdr *tcp;
@@ -2266,7 +2265,6 @@ static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue)
22662265
struct efx_channel *channel = tx_queue->channel;
22672266
struct efx_nic *efx = tx_queue->efx;
22682267
struct efx_ef10_nic_data *nic_data;
2269-
bool tso_v2 = false;
22702268
efx_qword_t *txd;
22712269
int rc;
22722270

@@ -2289,15 +2287,18 @@ static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue)
22892287
* TSOv2 cannot be used with Hardware timestamping, and is never needed
22902288
* for XDP tx.
22912289
*/
2292-
if ((csum_offload || inner_csum) && (nic_data->datapath_caps2 &
2293-
(1 << MC_CMD_GET_CAPABILITIES_V2_OUT_TX_TSO_V2_LBN)) &&
2294-
!tx_queue->timestamping && !tx_queue->xdp_tx) {
2295-
tso_v2 = true;
2296-
netif_dbg(efx, hw, efx->net_dev, "Using TSOv2 for channel %u\n",
2297-
channel->channel);
2290+
if (efx_has_cap(efx, TX_TSO_V2)) {
2291+
if ((csum_offload || inner_csum) &&
2292+
!tx_queue->timestamping && !tx_queue->xdp_tx) {
2293+
tx_queue->tso_version = 2;
2294+
netif_dbg(efx, hw, efx->net_dev, "Using TSOv2 for channel %u\n",
2295+
channel->channel);
2296+
}
2297+
} else if (efx_has_cap(efx, TX_TSO)) {
2298+
tx_queue->tso_version = 1;
22982299
}
22992300

2300-
rc = efx_mcdi_tx_init(tx_queue, tso_v2);
2301+
rc = efx_mcdi_tx_init(tx_queue);
23012302
if (rc)
23022303
goto fail;
23032304

@@ -2315,20 +2316,12 @@ static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue)
23152316
ESF_DZ_TX_OPTION_TYPE,
23162317
ESE_DZ_TX_OPTION_DESC_CRC_CSUM,
23172318
ESF_DZ_TX_OPTION_UDP_TCP_CSUM, csum_offload,
2318-
ESF_DZ_TX_OPTION_IP_CSUM, csum_offload && !tso_v2,
2319+
ESF_DZ_TX_OPTION_IP_CSUM, csum_offload && tx_queue->tso_version != 2,
23192320
ESF_DZ_TX_OPTION_INNER_UDP_TCP_CSUM, inner_csum,
2320-
ESF_DZ_TX_OPTION_INNER_IP_CSUM, inner_csum && !tso_v2,
2321+
ESF_DZ_TX_OPTION_INNER_IP_CSUM, inner_csum && tx_queue->tso_version != 2,
23212322
ESF_DZ_TX_TIMESTAMP, tx_queue->timestamping);
23222323
tx_queue->write_count = 1;
23232324

2324-
if (tso_v2) {
2325-
tx_queue->handle_tso = efx_ef10_tx_tso_desc;
2326-
tx_queue->tso_version = 2;
2327-
} else if (nic_data->datapath_caps &
2328-
(1 << MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_LBN)) {
2329-
tx_queue->tso_version = 1;
2330-
}
2331-
23322325
wmb();
23332326
efx_ef10_push_tx_desc(tx_queue, txd);
23342327

drivers/net/ethernet/sfc/ef100_tx.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,14 @@ void ef100_tx_init(struct efx_tx_queue *tx_queue)
3737
tx_queue->channel->channel -
3838
tx_queue->efx->tx_channel_offset);
3939

40-
if (efx_mcdi_tx_init(tx_queue, false))
40+
/* This value is purely documentational; as EF100 never passes through
41+
* the switch statement in tx.c:__efx_enqueue_skb(), that switch does
42+
* not handle case 3. EF100's TSOv3 descriptors are generated by
43+
* ef100_make_tso_desc().
44+
* Meanwhile, all efx_mcdi_tx_init() cares about is that it's not 2.
45+
*/
46+
tx_queue->tso_version = 3;
47+
if (efx_mcdi_tx_init(tx_queue))
4148
netdev_WARN(tx_queue->efx->net_dev,
4249
"failed to initialise TXQ %d\n", tx_queue->queue);
4350
}

drivers/net/ethernet/sfc/farch.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,8 @@ void efx_farch_tx_init(struct efx_tx_queue *tx_queue)
415415
FFE_BZ_TX_PACE_OFF :
416416
FFE_BZ_TX_PACE_RESERVED);
417417
efx_writeo_table(efx, &reg, FR_BZ_TX_PACE_TBL, tx_queue->queue);
418+
419+
tx_queue->tso_version = 1;
418420
}
419421

420422
static void efx_farch_flush_tx_queue(struct efx_tx_queue *tx_queue)

drivers/net/ethernet/sfc/mcdi_functions.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ void efx_mcdi_ev_fini(struct efx_channel *channel)
160160
outbuf, outlen, rc);
161161
}
162162

163-
int efx_mcdi_tx_init(struct efx_tx_queue *tx_queue, bool tso_v2)
163+
int efx_mcdi_tx_init(struct efx_tx_queue *tx_queue)
164164
{
165165
MCDI_DECLARE_BUF(inbuf, MC_CMD_INIT_TXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 /
166166
EFX_BUF_SIZE));
@@ -195,6 +195,8 @@ int efx_mcdi_tx_init(struct efx_tx_queue *tx_queue, bool tso_v2)
195195
inlen = MC_CMD_INIT_TXQ_IN_LEN(entries);
196196

197197
do {
198+
bool tso_v2 = tx_queue->tso_version == 2;
199+
198200
/* TSOv2 implies IP header checksum offload for TSO frames,
199201
* so we can safely disable IP header checksum offload for
200202
* everything else. If we don't have TSOv2, then we have to
@@ -217,7 +219,7 @@ int efx_mcdi_tx_init(struct efx_tx_queue *tx_queue, bool tso_v2)
217219
NULL, 0, NULL);
218220
if (rc == -ENOSPC && tso_v2) {
219221
/* Retry without TSOv2 if we're short on contexts. */
220-
tso_v2 = false;
222+
tx_queue->tso_version = 0;
221223
netif_warn(efx, probe, efx->net_dev,
222224
"TSOv2 context not available to segment in "
223225
"hardware. TCP performance may be reduced.\n"

drivers/net/ethernet/sfc/mcdi_functions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ int efx_mcdi_ev_probe(struct efx_channel *channel);
1919
int efx_mcdi_ev_init(struct efx_channel *channel, bool v1_cut_thru, bool v2);
2020
void efx_mcdi_ev_remove(struct efx_channel *channel);
2121
void efx_mcdi_ev_fini(struct efx_channel *channel);
22-
int efx_mcdi_tx_init(struct efx_tx_queue *tx_queue, bool tso_v2);
22+
int efx_mcdi_tx_init(struct efx_tx_queue *tx_queue);
2323
void efx_mcdi_tx_remove(struct efx_tx_queue *tx_queue);
2424
void efx_mcdi_tx_fini(struct efx_tx_queue *tx_queue);
2525
int efx_mcdi_rx_probe(struct efx_rx_queue *rx_queue);

drivers/net/ethernet/sfc/net_driver.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,6 @@ struct efx_tx_buffer {
208208
* @initialised: Has hardware queue been initialised?
209209
* @timestamping: Is timestamping enabled for this channel?
210210
* @xdp_tx: Is this an XDP tx queue?
211-
* @handle_tso: TSO xmit preparation handler. Sets up the TSO metadata and
212-
* may also map tx data, depending on the nature of the TSO implementation.
213211
* @read_count: Current read pointer.
214212
* This is the number of buffers that have been removed from both rings.
215213
* @old_write_count: The value of @write_count when last checked.
@@ -272,9 +270,6 @@ struct efx_tx_queue {
272270
bool timestamping;
273271
bool xdp_tx;
274272

275-
/* Function pointers used in the fast path. */
276-
int (*handle_tso)(struct efx_tx_queue*, struct sk_buff*, bool *);
277-
278273
/* Members used mainly on the completion path */
279274
unsigned int read_count ____cacheline_aligned_in_smp;
280275
unsigned int old_write_count;

drivers/net/ethernet/sfc/nic.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ struct efx_ef10_nic_data {
297297
u64 licensed_features;
298298
};
299299

300+
/* TSOv2 */
301+
int efx_ef10_tx_tso_desc(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
302+
bool *data_mapped);
303+
300304
int efx_init_sriov(void);
301305
void efx_fini_sriov(void);
302306

drivers/net/ethernet/sfc/tx.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,18 @@ netdev_tx_t __efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb
338338
* size limit.
339339
*/
340340
if (segments) {
341-
EFX_WARN_ON_ONCE_PARANOID(!tx_queue->handle_tso);
342-
rc = tx_queue->handle_tso(tx_queue, skb, &data_mapped);
341+
switch (tx_queue->tso_version) {
342+
case 1:
343+
rc = efx_enqueue_skb_tso(tx_queue, skb, &data_mapped);
344+
break;
345+
case 2:
346+
rc = efx_ef10_tx_tso_desc(tx_queue, skb, &data_mapped);
347+
break;
348+
case 0: /* No TSO on this queue, SW fallback needed */
349+
default:
350+
rc = -EINVAL;
351+
break;
352+
}
343353
if (rc == -EINVAL) {
344354
rc = efx_tx_tso_fallback(tx_queue, skb);
345355
tx_queue->tso_fallbacks++;

drivers/net/ethernet/sfc/tx_common.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,7 @@ void efx_init_tx_queue(struct efx_tx_queue *tx_queue)
8686
tx_queue->completed_timestamp_minor = 0;
8787

8888
tx_queue->xdp_tx = efx_channel_is_xdp_tx(tx_queue->channel);
89-
90-
/* Set up default function pointers. These may get replaced by
91-
* efx_nic_init_tx() based off NIC/queue capabilities.
92-
*/
93-
tx_queue->handle_tso = efx_enqueue_skb_tso;
89+
tx_queue->tso_version = 0;
9490

9591
/* Set up TX descriptor ring */
9692
efx_nic_init_tx(tx_queue);

0 commit comments

Comments
 (0)