From: Andrew Rybchenko Date: Sun, 24 Dec 2017 10:46:33 +0000 (+0000) Subject: net/sfc: handle MC reboot event X-Git-Tag: spdx-start~487 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=e77f9f1906cb105bb5988d0ec9fc28aa30eff5fc;p=dpdk.git net/sfc: handle MC reboot event Implement handling of the MC reboot event received on management event queue or detected by MCDI processing. Signed-off-by: Andrew Rybchenko Reviewed-by: Ivan Malov Reviewed-by: Andy Moreton --- diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index 49d7e93705..0dcfdd800a 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -33,6 +33,7 @@ #include #include +#include #include "efx.h" @@ -389,6 +390,58 @@ sfc_stop(struct sfc_adapter *sa) sfc_log_init(sa, "done"); } +static int +sfc_restart(struct sfc_adapter *sa) +{ + int rc; + + SFC_ASSERT(sfc_adapter_is_locked(sa)); + + if (sa->state != SFC_ADAPTER_STARTED) + return EINVAL; + + sfc_stop(sa); + + rc = sfc_start(sa); + if (rc != 0) + sfc_err(sa, "restart failed"); + + return rc; +} + +static void +sfc_restart_if_required(void *arg) +{ + struct sfc_adapter *sa = arg; + + /* If restart is scheduled, clear the flag and do it */ + if (rte_atomic32_cmpset((volatile uint32_t *)&sa->restart_required, + 1, 0)) { + sfc_adapter_lock(sa); + if (sa->state == SFC_ADAPTER_STARTED) + (void)sfc_restart(sa); + sfc_adapter_unlock(sa); + } +} + +void +sfc_schedule_restart(struct sfc_adapter *sa) +{ + int rc; + + /* Schedule restart alarm if it is not scheduled yet */ + if (!rte_atomic32_test_and_set(&sa->restart_required)) + return; + + rc = rte_eal_alarm_set(1, sfc_restart_if_required, sa); + if (rc == -ENOTSUP) + sfc_warn(sa, "alarms are not supported, restart is pending"); + else if (rc != 0) + sfc_err(sa, "cannot arm restart alarm (rc=%d)", rc); + else + sfc_info(sa, "restart scheduled"); +} + int sfc_configure(struct sfc_adapter *sa) { @@ -679,6 +732,7 @@ sfc_probe(struct sfc_adapter *sa) SFC_ASSERT(sfc_adapter_is_locked(sa)); sa->socket_id = rte_socket_id(); + rte_atomic32_init(&sa->restart_required); sfc_log_init(sa, "init mem bar"); rc = sfc_mem_bar_init(sa); @@ -743,6 +797,14 @@ sfc_unprobe(struct sfc_adapter *sa) sfc_mcdi_fini(sa); + /* + * Make sure there is no pending alarm to restart since we are + * going to free device private which is passed as the callback + * opaque data. A new alarm cannot be scheduled since MCDI is + * shut down. + */ + rte_eal_alarm_cancel(sfc_restart_if_required, sa); + sfc_log_init(sa, "destroy nic"); sa->nic = NULL; efx_nic_destroy(enp); diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index ef980a40f7..77882eb6b3 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -39,6 +39,7 @@ #include #include #include +#include #include "efx.h" @@ -197,6 +198,7 @@ struct sfc_adapter { efx_family_t family; efx_nic_t *nic; rte_spinlock_t nic_lock; + rte_atomic32_t restart_required; struct sfc_mcdi mcdi; struct sfc_intr intr; @@ -329,6 +331,8 @@ void sfc_detach(struct sfc_adapter *sa); int sfc_start(struct sfc_adapter *sa); void sfc_stop(struct sfc_adapter *sa); +void sfc_schedule_restart(struct sfc_adapter *sa); + int sfc_mcdi_init(struct sfc_adapter *sa); void sfc_mcdi_fini(struct sfc_adapter *sa); diff --git a/drivers/net/sfc/sfc_mcdi.c b/drivers/net/sfc/sfc_mcdi.c index 0faad3ed77..f4763abd68 100644 --- a/drivers/net/sfc/sfc_mcdi.c +++ b/drivers/net/sfc/sfc_mcdi.c @@ -176,7 +176,7 @@ sfc_mcdi_exception(void *arg, efx_mcdi_exception_t eme) (eme == EFX_MCDI_EXCEPTION_MC_REBOOT) ? "REBOOT" : (eme == EFX_MCDI_EXCEPTION_MC_BADASSERT) ? "BADASSERT" : "UNKNOWN"); - sfc_panic(sa, "MCDI exceptions handling is not implemented\n"); + sfc_schedule_restart(sa); } #define SFC_MCDI_LOG_BUF_SIZE 128