+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");
+}
+