net/sfc: periodic management EVQ polling using alarm

Timers cannot be used to implement periodic polling, since it implies
requirement on application to process timers in the main loop.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@solarflare.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
This commit is contained in:
Andrew Rybchenko 2016-11-29 16:19:12 +00:00 committed by Ferruh Yigit
parent 9a75f75cb1
commit 2de39f4e13

View File

@ -29,6 +29,7 @@
#include <rte_debug.h>
#include <rte_cycles.h>
#include <rte_alarm.h>
#include "efx.h"
@ -45,6 +46,9 @@
/* Event queue init approx timeout */
#define SFC_EVQ_INIT_TIMEOUT_US (2 * US_PER_S)
/* Management event queue polling period in microseconds */
#define SFC_MGMT_EV_QPOLL_PERIOD_US (US_PER_S)
static boolean_t
sfc_ev_initialized(void *arg)
@ -328,6 +332,34 @@ sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index)
efx_ev_qdestroy(evq->common);
}
static void
sfc_ev_mgmt_periodic_qpoll(void *arg)
{
struct sfc_adapter *sa = arg;
int rc;
sfc_ev_mgmt_qpoll(sa);
rc = rte_eal_alarm_set(SFC_MGMT_EV_QPOLL_PERIOD_US,
sfc_ev_mgmt_periodic_qpoll, sa);
if (rc != 0)
sfc_panic(sa,
"cannot rearm management EVQ polling alarm (rc=%d)",
rc);
}
static void
sfc_ev_mgmt_periodic_qpoll_start(struct sfc_adapter *sa)
{
sfc_ev_mgmt_periodic_qpoll(sa);
}
static void
sfc_ev_mgmt_periodic_qpoll_stop(struct sfc_adapter *sa)
{
rte_eal_alarm_cancel(sfc_ev_mgmt_periodic_qpoll, sa);
}
int
sfc_ev_start(struct sfc_adapter *sa)
{
@ -348,6 +380,14 @@ sfc_ev_start(struct sfc_adapter *sa)
rte_spinlock_unlock(&sa->mgmt_evq_lock);
/*
* Start management EVQ polling. If interrupts are disabled
* (not used), it is required to process link status change
* and other device level events to avoid unrecoverable
* error because the event queue overflow.
*/
sfc_ev_mgmt_periodic_qpoll_start(sa);
/*
* Rx/Tx event queues are started/stopped when corresponding
* Rx/Tx queue is started/stopped.
@ -371,6 +411,8 @@ sfc_ev_stop(struct sfc_adapter *sa)
sfc_log_init(sa, "entry");
sfc_ev_mgmt_periodic_qpoll_stop(sa);
/* Make sure that all event queues are stopped */
sw_index = sa->evq_count;
while (sw_index-- > 0) {