Skip to content

Commit 3b4f06c

Browse files
tomz-xilinxdavem330
authored andcommitted
sfc: complete the next packet when we receive a timestamp
We now ignore the "completion" event when using tx queue timestamping, and only pay attention to the two (high and low) timestamp events. The NIC will send a pair of timestamp events for every packet transmitted. The current firmware may merge the completion events, and it is possible that future versions may reorder the completion and timestamp events. As such the completion event is not useful. Without this patch in place a merged completion event on a queue with timestamping will cause a "spurious TX completion" error. This affects SFN8000-series adapters. Signed-off-by: Tom Zhao <[email protected]> Acked-by: Martin Habets <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 68e1006 commit 3b4f06c

File tree

6 files changed

+78
-31
lines changed

6 files changed

+78
-31
lines changed

drivers/net/ethernet/sfc/ef10.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2853,29 +2853,32 @@ efx_ef10_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
28532853
}
28542854

28552855
/* Transmit timestamps are only available for 8XXX series. They result
2856-
* in three events per packet. These occur in order, and are:
2857-
* - the normal completion event
2856+
* in up to three events per packet. These occur in order, and are:
2857+
* - the normal completion event (may be omitted)
28582858
* - the low part of the timestamp
28592859
* - the high part of the timestamp
28602860
*
2861+
* It's possible for multiple completion events to appear before the
2862+
* corresponding timestamps. So we can for example get:
2863+
* COMP N
2864+
* COMP N+1
2865+
* TS_LO N
2866+
* TS_HI N
2867+
* TS_LO N+1
2868+
* TS_HI N+1
2869+
*
2870+
* In addition it's also possible for the adjacent completions to be
2871+
* merged, so we may not see COMP N above. As such, the completion
2872+
* events are not very useful here.
2873+
*
28612874
* Each part of the timestamp is itself split across two 16 bit
28622875
* fields in the event.
28632876
*/
28642877
tx_ev_type = EFX_QWORD_FIELD(*event, ESF_EZ_TX_SOFT1);
28652878

28662879
switch (tx_ev_type) {
28672880
case TX_TIMESTAMP_EVENT_TX_EV_COMPLETION:
2868-
/* In case of Queue flush or FLR, we might have received
2869-
* the previous TX completion event but not the Timestamp
2870-
* events.
2871-
*/
2872-
if (tx_queue->completed_desc_ptr != tx_queue->ptr_mask)
2873-
efx_xmit_done(tx_queue, tx_queue->completed_desc_ptr);
2874-
2875-
tx_ev_desc_ptr = EFX_QWORD_FIELD(*event,
2876-
ESF_DZ_TX_DESCR_INDX);
2877-
tx_queue->completed_desc_ptr =
2878-
tx_ev_desc_ptr & tx_queue->ptr_mask;
2881+
/* Ignore this event - see above. */
28792882
break;
28802883

28812884
case TX_TIMESTAMP_EVENT_TX_EV_TSTAMP_LO:
@@ -2887,8 +2890,7 @@ efx_ef10_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
28872890
ts_part = efx_ef10_extract_event_ts(event);
28882891
tx_queue->completed_timestamp_major = ts_part;
28892892

2890-
efx_xmit_done(tx_queue, tx_queue->completed_desc_ptr);
2891-
tx_queue->completed_desc_ptr = tx_queue->ptr_mask;
2893+
efx_xmit_done_single(tx_queue);
28922894
break;
28932895

28942896
default:

drivers/net/ethernet/sfc/efx.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
2020
struct net_device *net_dev);
2121
netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
2222
void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
23+
void efx_xmit_done_single(struct efx_tx_queue *tx_queue);
2324
int efx_setup_tc(struct net_device *net_dev, enum tc_setup_type type,
2425
void *type_data);
2526
extern unsigned int efx_piobuf_size;

drivers/net/ethernet/sfc/net_driver.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,6 @@ struct efx_tx_buffer {
208208
* avoid cache-line ping-pong between the xmit path and the
209209
* completion path.
210210
* @merge_events: Number of TX merged completion events
211-
* @completed_desc_ptr: Most recent completed pointer - only used with
212-
* timestamping.
213211
* @completed_timestamp_major: Top part of the most recent tx timestamp.
214212
* @completed_timestamp_minor: Low part of the most recent tx timestamp.
215213
* @insert_count: Current insert pointer
@@ -269,7 +267,6 @@ struct efx_tx_queue {
269267
unsigned int merge_events;
270268
unsigned int bytes_compl;
271269
unsigned int pkts_compl;
272-
unsigned int completed_desc_ptr;
273270
u32 completed_timestamp_major;
274271
u32 completed_timestamp_minor;
275272

drivers/net/ethernet/sfc/tx.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,44 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
535535
return efx_enqueue_skb(tx_queue, skb);
536536
}
537537

538+
void efx_xmit_done_single(struct efx_tx_queue *tx_queue)
539+
{
540+
unsigned int pkts_compl = 0, bytes_compl = 0;
541+
unsigned int read_ptr;
542+
bool finished = false;
543+
544+
read_ptr = tx_queue->read_count & tx_queue->ptr_mask;
545+
546+
while (!finished) {
547+
struct efx_tx_buffer *buffer = &tx_queue->buffer[read_ptr];
548+
549+
if (!efx_tx_buffer_in_use(buffer)) {
550+
struct efx_nic *efx = tx_queue->efx;
551+
552+
netif_err(efx, hw, efx->net_dev,
553+
"TX queue %d spurious single TX completion\n",
554+
tx_queue->queue);
555+
efx_schedule_reset(efx, RESET_TYPE_TX_SKIP);
556+
return;
557+
}
558+
559+
/* Need to check the flag before dequeueing. */
560+
if (buffer->flags & EFX_TX_BUF_SKB)
561+
finished = true;
562+
efx_dequeue_buffer(tx_queue, buffer, &pkts_compl, &bytes_compl);
563+
564+
++tx_queue->read_count;
565+
read_ptr = tx_queue->read_count & tx_queue->ptr_mask;
566+
}
567+
568+
tx_queue->pkts_compl += pkts_compl;
569+
tx_queue->bytes_compl += bytes_compl;
570+
571+
EFX_WARN_ON_PARANOID(pkts_compl != 1);
572+
573+
efx_xmit_done_check_empty(tx_queue);
574+
}
575+
538576
void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue)
539577
{
540578
struct efx_nic *efx = tx_queue->efx;

drivers/net/ethernet/sfc/tx_common.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ void efx_init_tx_queue(struct efx_tx_queue *tx_queue)
8080
tx_queue->xmit_more_available = false;
8181
tx_queue->timestamping = (efx_ptp_use_mac_tx_timestamps(efx) &&
8282
tx_queue->channel == efx_ptp_channel(efx));
83-
tx_queue->completed_desc_ptr = tx_queue->ptr_mask;
8483
tx_queue->completed_timestamp_major = 0;
8584
tx_queue->completed_timestamp_minor = 0;
8685

@@ -210,10 +209,9 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
210209
while (read_ptr != stop_index) {
211210
struct efx_tx_buffer *buffer = &tx_queue->buffer[read_ptr];
212211

213-
if (!(buffer->flags & EFX_TX_BUF_OPTION) &&
214-
unlikely(buffer->len == 0)) {
212+
if (!efx_tx_buffer_in_use(buffer)) {
215213
netif_err(efx, tx_err, efx->net_dev,
216-
"TX queue %d spurious TX completion id %x\n",
214+
"TX queue %d spurious TX completion id %d\n",
217215
tx_queue->queue, read_ptr);
218216
efx_schedule_reset(efx, RESET_TYPE_TX_SKIP);
219217
return;
@@ -226,6 +224,19 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
226224
}
227225
}
228226

227+
void efx_xmit_done_check_empty(struct efx_tx_queue *tx_queue)
228+
{
229+
if ((int)(tx_queue->read_count - tx_queue->old_write_count) >= 0) {
230+
tx_queue->old_write_count = READ_ONCE(tx_queue->write_count);
231+
if (tx_queue->read_count == tx_queue->old_write_count) {
232+
/* Ensure that read_count is flushed. */
233+
smp_mb();
234+
tx_queue->empty_read_count =
235+
tx_queue->read_count | EFX_EMPTY_COUNT_VALID;
236+
}
237+
}
238+
}
239+
229240
void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
230241
{
231242
unsigned int fill_level, pkts_compl = 0, bytes_compl = 0;
@@ -256,15 +267,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
256267
netif_tx_wake_queue(tx_queue->core_txq);
257268
}
258269

259-
/* Check whether the hardware queue is now empty */
260-
if ((int)(tx_queue->read_count - tx_queue->old_write_count) >= 0) {
261-
tx_queue->old_write_count = READ_ONCE(tx_queue->write_count);
262-
if (tx_queue->read_count == tx_queue->old_write_count) {
263-
smp_mb();
264-
tx_queue->empty_read_count =
265-
tx_queue->read_count | EFX_EMPTY_COUNT_VALID;
266-
}
267-
}
270+
efx_xmit_done_check_empty(tx_queue);
268271
}
269272

270273
/* Remove buffers put into a tx_queue for the current packet.

drivers/net/ethernet/sfc/tx_common.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ void efx_dequeue_buffer(struct efx_tx_queue *tx_queue,
2121
unsigned int *pkts_compl,
2222
unsigned int *bytes_compl);
2323

24+
static inline bool efx_tx_buffer_in_use(struct efx_tx_buffer *buffer)
25+
{
26+
return buffer->len || (buffer->flags & EFX_TX_BUF_OPTION);
27+
}
28+
29+
void efx_xmit_done_check_empty(struct efx_tx_queue *tx_queue);
2430
void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
2531

2632
void efx_enqueue_unwind(struct efx_tx_queue *tx_queue,

0 commit comments

Comments
 (0)