From 77f2d0534d1bc3db3fc18e76425d478aa87151c4 Mon Sep 17 00:00:00 2001 From: Andrew Rybchenko Date: Fri, 2 Dec 2016 07:41:20 +0000 Subject: [PATCH] net/sfc: restart RxQ in case of exception on event queue Examples of recoverable exceptions are: - unexpected Rx event (Rx scatter abort with non-zero size, too big Rx descriptors batch completed) - Rx error due to invalid Rx descriptors push - Rx error due to Rx descriptor read error (e.g. unmapped Rx ring and denied by IOMMU) Signed-off-by: Andrew Rybchenko Reviewed-by: Andrew Lee Reviewed-by: Robert Stonehouse --- drivers/net/sfc/sfc.h | 6 ++++++ drivers/net/sfc/sfc_ev.c | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 543c36828c..c6bb5e8c42 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -190,6 +190,12 @@ sfc_adapter_lock(struct sfc_adapter *sa) rte_spinlock_lock(&sa->lock); } +static inline int +sfc_adapter_trylock(struct sfc_adapter *sa) +{ + return rte_spinlock_trylock(&sa->lock); +} + static inline void sfc_adapter_unlock(struct sfc_adapter *sa) { diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c index 96b95cccbe..36aede811c 100644 --- a/drivers/net/sfc/sfc_ev.c +++ b/drivers/net/sfc/sfc_ev.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "efx.h" @@ -320,6 +321,31 @@ sfc_ev_qpoll(struct sfc_evq *evq) efx_ev_qpoll(evq->common, &evq->read_ptr, &sfc_ev_callbacks, evq); + if (unlikely(evq->exception) && sfc_adapter_trylock(evq->sa)) { + struct sfc_adapter *sa = evq->sa; + int rc; + + if ((evq->rxq != NULL) && (evq->rxq->state & SFC_RXQ_RUNNING)) { + unsigned int rxq_sw_index = sfc_rxq_sw_index(evq->rxq); + + sfc_warn(sa, + "restart RxQ %u because of exception on its EvQ %u", + rxq_sw_index, evq->evq_index); + + sfc_rx_qstop(sa, rxq_sw_index); + rc = sfc_rx_qstart(sa, rxq_sw_index); + if (rc != 0) + sfc_err(sa, "cannot restart RxQ %u", + rxq_sw_index); + } + + if (evq->exception) + sfc_panic(sa, "unrecoverable exception on EvQ %u", + evq->evq_index); + + sfc_adapter_unlock(sa); + } + /* Poll-mode driver does not re-prime the event queue for interrupts */ } -- 2.20.1