[dpdk-dev,v2,50/55] net/sfc: discard scattered packet on Rx correctly

Message ID 1480436367-20749-51-git-send-email-arybchenko@solarflare.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers

Checks

Context Check Description
checkpatch/checkpatch success coding style OK

Commit Message

Andrew Rybchenko Nov. 29, 2016, 4:19 p.m. UTC
  Since Rx scatter is not supported, all scattered packets are discarded.
It is not always possible to disable scatter on Huntington, so we
should handle scattered packets correctly in any case.

Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/sfc_ev.c | 22 +++++++++++++++++++++-
 drivers/net/sfc/sfc_rx.c |  8 ++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)
  

Patch

diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c
index d9e8459..eed1b52 100644
--- a/drivers/net/sfc/sfc_ev.c
+++ b/drivers/net/sfc/sfc_ev.c
@@ -91,7 +91,27 @@  sfc_ev_rx(void *arg, __rte_unused uint32_t label, uint32_t id,
 	delta = (stop >= pending_id) ? (stop - pending_id) :
 		(rxq->ptr_mask + 1 - pending_id + stop);
 
-	if (unlikely(delta > rxq->batch_max)) {
+	if (delta == 0) {
+		/*
+		 * Rx event with no new descriptors done and zero length
+		 * is used to abort scattered packet when there is no room
+		 * for the tail.
+		 */
+		if (unlikely(size != 0)) {
+			evq->exception = B_TRUE;
+			sfc_err(evq->sa,
+				"EVQ %u RxQ %u invalid RX abort "
+				"(id=%#x size=%u flags=%#x); needs restart\n",
+				evq->evq_index, sfc_rxq_sw_index(rxq),
+				id, size, flags);
+			goto done;
+		}
+
+		/* Add discard flag to the first fragment */
+		rxq->sw_desc[pending_id].flags |= EFX_DISCARD;
+		/* Remove continue flag from the last fragment */
+		rxq->sw_desc[id].flags &= ~EFX_PKT_CONT;
+	} else if (unlikely(delta > rxq->batch_max)) {
 		evq->exception = B_TRUE;
 
 		sfc_err(evq->sa,
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 5587620..bd41131 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -137,6 +137,7 @@  sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	unsigned int completed;
 	unsigned int prefix_size = rxq->prefix_size;
 	unsigned int done_pkts = 0;
+	boolean_t discard_next = B_FALSE;
 
 	if (unlikely((rxq->state & SFC_RXQ_RUNNING) == 0))
 		return 0;
@@ -156,9 +157,15 @@  sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		m = rxd->mbuf;
 		desc_flags = rxd->flags;
 
+		if (discard_next)
+			goto discard;
+
 		if (desc_flags & (EFX_ADDR_MISMATCH | EFX_DISCARD))
 			goto discard;
 
+		if (desc_flags & EFX_PKT_CONT)
+			goto discard;
+
 		if (desc_flags & EFX_PKT_PREFIX_LEN) {
 			uint16_t tmp_size;
 			int rc __rte_unused;
@@ -182,6 +189,7 @@  sfc_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		continue;
 
 discard:
+		discard_next = ((desc_flags & EFX_PKT_CONT) != 0);
 		rte_mempool_put(rxq->refill_mb_pool, m);
 		rxd->mbuf = NULL;
 	}