All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] rte_delay_us can be replaced with user function
@ 2016-07-20 12:10 jozmarti
  2016-09-13 20:04 ` Thomas Monjalon
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: jozmarti @ 2016-07-20 12:10 UTC (permalink / raw)
  To: dev; +Cc: Jozef Martiniak

From: Jozef Martiniak <jozmarti@cisco.com>

When running single-core, some drivers tend to call rte_delay_us for a
long time, and that is causing packet drops.
To avoid this, rte_delay_us can be replaced with user-defined delay
function with:

void rte_delay_us_callback_register(void(*userfunc)(unsigned));

When userfunc==NULL, build-in blocking delay function is restored.

Signed-off-by: Jozef Martiniak <jozmarti@cisco.com>
---
 app/test/test_cycles.c                             | 45 ++++++++++++++++++++++
 lib/librte_eal/bsdapp/eal/rte_eal_version.map      |  7 ++++
 lib/librte_eal/common/eal_common_timer.c           | 22 ++++++++++-
 lib/librte_eal/common/include/generic/rte_cycles.h | 15 +++++++-
 lib/librte_eal/linuxapp/eal/rte_eal_version.map    |  7 ++++
 5 files changed, 93 insertions(+), 3 deletions(-)

diff --git a/app/test/test_cycles.c b/app/test/test_cycles.c
index f6c043a..7415ac8 100644
--- a/app/test/test_cycles.c
+++ b/app/test/test_cycles.c
@@ -90,3 +90,48 @@ test_cycles(void)
 }
 
 REGISTER_TEST_COMMAND(cycles_autotest, test_cycles);
+
+/*
+ * rte_delay_us_callback test
+ *
+ * - check if callback is correctly registered/unregistered
+ *
+ */
+
+static int pattern;
+static void my_rte_delay_us(unsigned us)
+{
+    pattern += us;
+}
+
+static int
+test_user_delay_us(void)
+{
+    pattern = 0;
+
+    rte_delay_us(2);
+    if (pattern != 0)
+        return -1;
+
+    /* register custom delay function */
+    rte_delay_us_callback_register(my_rte_delay_us);
+
+    rte_delay_us(2);
+    if (pattern != 2)
+        return -1;
+
+    rte_delay_us(3);
+    if (pattern != 5)
+        return -1;
+
+    /* restore original delay function */
+    rte_delay_us_callback_register(NULL);
+
+    rte_delay_us(3);
+    if (pattern != 5)
+        return -1;
+
+    return 0;
+}
+
+REGISTER_TEST_COMMAND(user_delay_us, test_user_delay_us);
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index a335e04..2f83ed0 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -162,3 +162,10 @@ DPDK_16.07 {
 	rte_thread_setname;
 
 } DPDK_16.04;
+
+DPDK_16.11 {
+	global:
+
+	rte_delay_us_callback_register;
+
+} DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_timer.c b/lib/librte_eal/common/eal_common_timer.c
index c4227cd..ddfa9d1 100644
--- a/lib/librte_eal/common/eal_common_timer.c
+++ b/lib/librte_eal/common/eal_common_timer.c
@@ -47,8 +47,11 @@
 /* The frequency of the RDTSC timer resolution */
 static uint64_t eal_tsc_resolution_hz;
 
-void
-rte_delay_us(unsigned us)
+/* Pointer to user delay function */
+void (*rte_delay_us)(unsigned) = NULL;
+
+static void
+rte_delay_us_block(unsigned us)
 {
 	const uint64_t start = rte_get_timer_cycles();
 	const uint64_t ticks = (uint64_t)us * rte_get_timer_hz() / 1E6;
@@ -84,3 +87,18 @@ set_tsc_freq(void)
 	RTE_LOG(DEBUG, EAL, "TSC frequency is ~%" PRIu64 " KHz\n", freq / 1000);
 	eal_tsc_resolution_hz = freq;
 }
+
+void rte_delay_us_callback_register(void (*userfunc)(unsigned))
+{
+    if (userfunc == NULL)
+        rte_delay_us = rte_delay_us_block;
+    else
+        rte_delay_us = userfunc;
+}
+
+static void __attribute__((constructor))
+rte_timer_init(void)
+{
+    /* set rte_delay_us_block as a delay function */
+    rte_delay_us_callback_register(NULL);
+}
diff --git a/lib/librte_eal/common/include/generic/rte_cycles.h b/lib/librte_eal/common/include/generic/rte_cycles.h
index 8cc21f2..7a45b58 100644
--- a/lib/librte_eal/common/include/generic/rte_cycles.h
+++ b/lib/librte_eal/common/include/generic/rte_cycles.h
@@ -182,13 +182,16 @@ rte_get_timer_hz(void)
 }
 
 /**
+ *
  * Wait at least us microseconds.
+ * This function can be replaced with user-defined function using
+ * rte_delay_us_callback_register
  *
  * @param us
  *   The number of microseconds to wait.
  */
 void
-rte_delay_us(unsigned us);
+(*rte_delay_us)(unsigned us);
 
 /**
  * Wait at least ms milliseconds.
@@ -202,4 +205,14 @@ rte_delay_ms(unsigned ms)
 	rte_delay_us(ms * 1000);
 }
 
+/**
+ * Replace rte_delay_us with user defined function.
+ *
+ * @param userfunc
+ *   User function which replaces rte_delay_us. NULL restores
+ *   buildin block delay function.
+ */
+void rte_delay_us_callback_register(void(*userfunc)(unsigned));
+
+
 #endif /* _RTE_CYCLES_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index db8c984..4ba30ed 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -166,3 +166,10 @@ DPDK_16.07 {
 	rte_thread_setname;
 
 } DPDK_16.04;
+
+DPDK_16.11 {
+	global:
+
+	rte_delay_us_callback_register;
+
+} DPDK_16.07;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread
* [PATCH] rte_delay_us can be replaced with user function
@ 2016-07-19 12:42 jozmarti
  2016-07-19 13:17 ` Wiles, Keith
  2016-07-19 13:21 ` Thomas Monjalon
  0 siblings, 2 replies; 13+ messages in thread
From: jozmarti @ 2016-07-19 12:42 UTC (permalink / raw)
  To: dev; +Cc: Jozef Martiniak

From: Jozef Martiniak <jozmarti@cisco.com>

when running single-core, some drivers tend to call rte_delay_us for a
long time, and that is causing packet drops.
Attached patch introduces 2 new functions:

void rte_delay_us_callback_register(void(*userfunc)(unsigned));
void rte_delay_us_callback_unregister(void);

First one replaces rte_delay_us with userfunc and second one restores
original rte_delay_us.
Test user_delay_us is included.

Signed-off-by: Jozef Martiniak <jozmarti@cisco.com>
---
 app/test/test_cycles.c                             | 39 ++++++++++++++++++++++
 lib/librte_eal/common/eal_common_timer.c           | 19 +++++++++++
 lib/librte_eal/common/include/generic/rte_cycles.h | 13 ++++++++
 3 files changed, 71 insertions(+)

diff --git a/app/test/test_cycles.c b/app/test/test_cycles.c
index f6c043a..2b44a53 100644
--- a/app/test/test_cycles.c
+++ b/app/test/test_cycles.c
@@ -90,3 +90,42 @@ test_cycles(void)
 }
 
 REGISTER_TEST_COMMAND(cycles_autotest, test_cycles);
+
+/*
+ * rte_delay_us_callback test
+ *
+ * - check if callback is correctly registered/unregistered
+ *
+ */
+
+static int pattern;
+static void my_rte_delay_us(unsigned us)
+{
+    pattern += us;
+}
+
+static int
+test_user_delay_us(void)
+{
+    pattern = 0;
+
+    rte_delay_us_callback_register(my_rte_delay_us);
+
+    rte_delay_us(2);
+    if (pattern != 2)
+        return -1;
+
+    rte_delay_us(3);
+    if (pattern != 5)
+        return -1;
+
+    rte_delay_us_callback_unregister();
+
+    rte_delay_us(3);
+    if (pattern != 5)
+        return -1;
+
+    return 0;
+}
+
+REGISTER_TEST_COMMAND(user_delay_us, test_user_delay_us);
diff --git a/lib/librte_eal/common/eal_common_timer.c b/lib/librte_eal/common/eal_common_timer.c
index c4227cd..a982562 100644
--- a/lib/librte_eal/common/eal_common_timer.c
+++ b/lib/librte_eal/common/eal_common_timer.c
@@ -47,9 +47,18 @@
 /* The frequency of the RDTSC timer resolution */
 static uint64_t eal_tsc_resolution_hz;
 
+/* User function which replaces rte_delay_us function */
+static void (*rte_delay_us_override)(unsigned) = NULL;
+
 void
 rte_delay_us(unsigned us)
 {
+	if (unlikely(rte_delay_us_override != NULL))
+	{
+	    rte_delay_us_override(us);
+	    return;
+	}
+
 	const uint64_t start = rte_get_timer_cycles();
 	const uint64_t ticks = (uint64_t)us * rte_get_timer_hz() / 1E6;
 	while ((rte_get_timer_cycles() - start) < ticks)
@@ -84,3 +93,13 @@ set_tsc_freq(void)
 	RTE_LOG(DEBUG, EAL, "TSC frequency is ~%" PRIu64 " KHz\n", freq / 1000);
 	eal_tsc_resolution_hz = freq;
 }
+
+void rte_delay_us_callback_register(void (*userfunc)(unsigned))
+{
+    rte_delay_us_override = userfunc;
+}
+
+void rte_delay_us_callback_unregister(void)
+{
+    rte_delay_us_override = NULL;
+}
diff --git a/lib/librte_eal/common/include/generic/rte_cycles.h b/lib/librte_eal/common/include/generic/rte_cycles.h
index 8cc21f2..274f798 100644
--- a/lib/librte_eal/common/include/generic/rte_cycles.h
+++ b/lib/librte_eal/common/include/generic/rte_cycles.h
@@ -202,4 +202,17 @@ rte_delay_ms(unsigned ms)
 	rte_delay_us(ms * 1000);
 }
 
+/**
+ * Replace rte_delay_us with user defined function.
+ *
+ * @param userfunc
+ *   User function which replaces rte_delay_us.
+ */
+void rte_delay_us_callback_register(void(*userfunc)(unsigned));
+
+/**
+ * Unregister user callback function. Restores original rte_delay_us.
+ */
+void rte_delay_us_callback_unregister(void);
+
 #endif /* _RTE_CYCLES_H_ */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2016-09-26 12:48 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-20 12:10 [PATCH] rte_delay_us can be replaced with user function jozmarti
2016-09-13 20:04 ` Thomas Monjalon
2016-09-21 13:12   ` Thomas Monjalon
2016-09-22  8:37     ` Jozef Martiniak -X (jozmarti - PANTHEON TECHNOLOGIES at Cisco)
2016-09-22 15:08       ` Thomas Monjalon
2016-09-23  6:39 ` [PATCH v3] " jozmarti
2016-09-23 14:03   ` Thomas Monjalon
2016-09-26  8:35 ` jozmarti
2016-09-26 12:48   ` Thomas Monjalon
  -- strict thread matches above, loose matches on Subject: below --
2016-07-19 12:42 [PATCH] " jozmarti
2016-07-19 13:17 ` Wiles, Keith
2016-07-19 13:21 ` Thomas Monjalon
2016-07-19 13:52   ` Jozef Martiniak -X (jozmarti - PANTHEON TECHNOLOGIES at Cisco)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.