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,
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;
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;
continue;
discard:
+ discard_next = ((desc_flags & EFX_PKT_CONT) != 0);
rte_mempool_put(rxq->refill_mb_pool, m);
rxd->mbuf = NULL;
}