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)
Reviewed-by: Andrew Lee <a...@solarflare.com> Reviewed-by: Robert Stonehouse <rstoneho...@solarflare.com> Signed-off-by: Andrew Rybchenko <arybche...@solarflare.com> --- 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 29d3a6b..995dfe6 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -187,6 +187,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 96b95cc..36aede8 100644 --- a/drivers/net/sfc/sfc_ev.c +++ b/drivers/net/sfc/sfc_ev.c @@ -30,6 +30,7 @@ #include <rte_debug.h> #include <rte_cycles.h> #include <rte_alarm.h> +#include <rte_branch_prediction.h> #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.5.5