[dpdk-dev] [PATCH v2 19/55] net/sfc: import libefx event prefetch support

Andrew Rybchenko arybchenko at solarflare.com
Tue Nov 29 17:18:51 CET 2016


EFSYS_OPT_EV_PREFECT allows to enable event prefetching
when event queue is polled.

>From Solarflare Communications Inc.

Signed-off-by: Andrew Rybchenko <arybchenko at solarflare.com>
---
 drivers/net/sfc/base/efx.h       |  9 +++++++++
 drivers/net/sfc/base/efx_check.h |  7 +++++++
 drivers/net/sfc/base/efx_ev.c    | 38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+)

diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index abd264a..389fe41 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -1317,6 +1317,15 @@ efx_ev_qpending(
 	__in		efx_evq_t *eep,
 	__in		unsigned int count);
 
+#if EFSYS_OPT_EV_PREFETCH
+
+extern			void
+efx_ev_qprefetch(
+	__in		efx_evq_t *eep,
+	__in		unsigned int count);
+
+#endif	/* EFSYS_OPT_EV_PREFETCH */
+
 extern			void
 efx_ev_qpoll(
 	__in		efx_evq_t *eep,
diff --git a/drivers/net/sfc/base/efx_check.h b/drivers/net/sfc/base/efx_check.h
index 5956052..df46410 100644
--- a/drivers/net/sfc/base/efx_check.h
+++ b/drivers/net/sfc/base/efx_check.h
@@ -66,6 +66,13 @@
 # endif
 #endif /* EFSYS_OPT_DIAG */
 
+#if EFSYS_OPT_EV_PREFETCH
+/* Support optimized EVQ data access */
+# if !(EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)
+#  error "EV_PREFETCH requires SIENA or HUNTINGTON or MEDFORD"
+# endif
+#endif /* EFSYS_OPT_EV_PREFETCH */
+
 #ifdef EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE
 # error "FALCON_NIC_CFG_OVERRIDE is obsolete and is not supported."
 #endif
diff --git a/drivers/net/sfc/base/efx_ev.c b/drivers/net/sfc/base/efx_ev.c
index 74d146e..c172a06 100644
--- a/drivers/net/sfc/base/efx_ev.c
+++ b/drivers/net/sfc/base/efx_ev.c
@@ -351,6 +351,23 @@ efx_ev_qpending(
 	return (EFX_EV_PRESENT(qword));
 }
 
+#if EFSYS_OPT_EV_PREFETCH
+
+			void
+efx_ev_qprefetch(
+	__in		efx_evq_t *eep,
+	__in		unsigned int count)
+{
+	unsigned int offset;
+
+	EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+	offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
+	EFSYS_MEM_PREFETCH(eep->ee_esmp, offset);
+}
+
+#endif	/* EFSYS_OPT_EV_PREFETCH */
+
 #define	EFX_EV_BATCH	8
 
 			void
@@ -403,11 +420,32 @@ efx_ev_qpoll(
 			offset += sizeof (efx_qword_t);
 		}
 
+#if EFSYS_OPT_EV_PREFETCH && (EFSYS_OPT_EV_PREFETCH_PERIOD > 1)
+		/*
+		 * Prefetch the next batch when we get within PREFETCH_PERIOD
+		 * of a completed batch. If the batch is smaller, then prefetch
+		 * immediately.
+		 */
+		if (total == batch && total < EFSYS_OPT_EV_PREFETCH_PERIOD)
+			EFSYS_MEM_PREFETCH(eep->ee_esmp, offset);
+#endif	/* EFSYS_OPT_EV_PREFETCH */
+
 		/* Process the batch of events */
 		for (index = 0; index < total; ++index) {
 			boolean_t should_abort;
 			uint32_t code;
 
+#if EFSYS_OPT_EV_PREFETCH
+			/* Prefetch if we've now reached the batch period */
+			if (total == batch &&
+			    index + EFSYS_OPT_EV_PREFETCH_PERIOD == total) {
+				offset = (count + batch) & eep->ee_mask;
+				offset *= sizeof (efx_qword_t);
+
+				EFSYS_MEM_PREFETCH(eep->ee_esmp, offset);
+			}
+#endif	/* EFSYS_OPT_EV_PREFETCH */
+
 			EFX_EV_QSTAT_INCR(eep, EV_ALL);
 
 			code = EFX_QWORD_FIELD(ev[index], FSF_AZ_EV_CODE);
-- 
2.5.5



More information about the dev mailing list