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

Reviewed-by: Andy Moreton <amoreton at solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko at solarflare.com>
---
 drivers/net/sfc/efx/sfc_ev.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/drivers/net/sfc/efx/sfc_ev.c b/drivers/net/sfc/efx/sfc_ev.c
index 1734b1e..1cb9771 100644
--- a/drivers/net/sfc/efx/sfc_ev.c
+++ b/drivers/net/sfc/efx/sfc_ev.c
@@ -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)
@@ -326,6 +330,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)
 {
@@ -347,6 +379,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.
         */
@@ -369,6 +409,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) {
-- 
2.5.5

Reply via email to