[dpdk-dev,41/56] net/sfc: periodic management EVQ polling using alarm

Message ID 1479740470-6723-42-git-send-email-arybchenko@solarflare.com (mailing list archive)
State Changes Requested, archived
Delegated to: Ferruh Yigit
Headers

Checks

Context Check Description
checkpatch/checkpatch success coding style OK

Commit Message

Andrew Rybchenko Nov. 21, 2016, 3 p.m. UTC
  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@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/efx/sfc_ev.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
  

Patch

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) {