From: Thomas Monjalon <thomas@monjalon.net>
To: dev@dpdk.org
Cc: "David Marchand" <david.marchand@redhat.com>,
stable@dpdk.org, "Morten Brørup" <mb@smartsharesystems.com>,
"Anatoly Burakov" <anatoly.burakov@intel.com>,
"Tyler Retzlaff" <roretzla@linux.microsoft.com>,
"Narcisa Vasile" <navasile@linux.microsoft.com>,
"Stephen Hemminger" <stephen@networkplumber.org>,
"Dmitry Kozlyuk" <dmitry.kozliuk@gmail.com>,
"Konstantin Ananyev" <konstantin.v.ananyev@yandex.ru>,
"Andrew Rybchenko" <andrew.rybchenko@oktetlabs.ru>
Subject: [PATCH v6 1/1] eal/unix: allow creating thread with real-time priority
Date: Fri, 27 Oct 2023 10:08:52 +0200 [thread overview]
Message-ID: <20231027081158.1358064-1-thomas@monjalon.net> (raw)
In-Reply-To: <20231024125416.798897-1-thomas@monjalon.net>
When adding an API for creating threads,
the real-time priority has been forbidden on Unix.
There is a known issue with ring behaviour,
but it should not be completely forbidden.
Real-time thread can block some kernel threads on the same core,
making the system unstable.
That's why a sleep is added in the test thread,
and a warning is logged when using real-time priority.
Fixes: ca04c78b6262 ("eal: get/set thread priority per thread identifier")
Fixes: ce6e911d20f6 ("eal: add thread lifetime API")
Fixes: a7ba40b2b1bf ("drivers: convert to internal control threads")
Cc: stable@dpdk.org
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Acked-by: Morten Brørup <mb@smartsharesystems.com>
---
v1: no yield at all
v2: more comments, sched_yield() and Sleep(0) on Windows
v3: 2 yield functions with sleep in realtime version
v4: runtime warning, longer sleep on Unix and lighter yield on Windows
v5: fix build and increase Unix sleep to 1 ms
v6: no yield helper, use a big sleep for testing purpose
It is not clear how to implement helpers which would work
on all systems (different configuration, arch and OS).
So the first patch adding yield functions is dropped for now.
---
app/test/test_threads.c | 12 ++--------
.../prog_guide/env_abstraction_layer.rst | 4 +++-
lib/eal/include/rte_thread.h | 8 +++++--
lib/eal/unix/rte_thread.c | 22 +++++++++++--------
4 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/app/test/test_threads.c b/app/test/test_threads.c
index 4ac3f2671a..a863214137 100644
--- a/app/test/test_threads.c
+++ b/app/test/test_threads.c
@@ -5,6 +5,7 @@
#include <string.h>
#include <rte_thread.h>
+#include <rte_cycles.h>
#include <rte_debug.h>
#include "test.h"
@@ -22,7 +23,7 @@ thread_main(void *arg)
__atomic_store_n(&thread_id_ready, 1, __ATOMIC_RELEASE);
while (__atomic_load_n(&thread_id_ready, __ATOMIC_ACQUIRE) == 1)
- ;
+ rte_delay_us_sleep(1000); /* required for RT priority */
return 0;
}
@@ -97,21 +98,12 @@ test_thread_priority(void)
"Priority set mismatches priority get");
priority = RTE_THREAD_PRIORITY_REALTIME_CRITICAL;
-#ifndef RTE_EXEC_ENV_WINDOWS
- RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == ENOTSUP,
- "Priority set to critical should fail");
- RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
- "Failed to get thread priority");
- RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_NORMAL,
- "Failed set to critical should have retained normal");
-#else
RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == 0,
"Priority set to critical should succeed");
RTE_TEST_ASSERT(rte_thread_get_priority(thread_id, &priority) == 0,
"Failed to get thread priority");
RTE_TEST_ASSERT(priority == RTE_THREAD_PRIORITY_REALTIME_CRITICAL,
"Priority set mismatches priority get");
-#endif
priority = RTE_THREAD_PRIORITY_NORMAL;
RTE_TEST_ASSERT(rte_thread_set_priority(thread_id, priority) == 0,
diff --git a/doc/guides/prog_guide/env_abstraction_layer.rst b/doc/guides/prog_guide/env_abstraction_layer.rst
index 6debf54efb..d1f7cae7cd 100644
--- a/doc/guides/prog_guide/env_abstraction_layer.rst
+++ b/doc/guides/prog_guide/env_abstraction_layer.rst
@@ -815,7 +815,9 @@ Known Issues
4. It MAY be used by preemptible multi-producer and/or preemptible multi-consumer pthreads whose scheduling policy are all SCHED_OTHER(cfs), SCHED_IDLE or SCHED_BATCH. User SHOULD be aware of the performance penalty before using it.
- 5. It MUST not be used by multi-producer/consumer pthreads, whose scheduling policies are SCHED_FIFO or SCHED_RR.
+ 5. It MUST not be used by multi-producer/consumer pthreads
+ whose scheduling policies are ``SCHED_FIFO``
+ or ``SCHED_RR`` (``RTE_THREAD_PRIORITY_REALTIME_CRITICAL``).
Alternatively, applications can use the lock-free stack mempool handler. When
considering this handler, note that:
diff --git a/lib/eal/include/rte_thread.h b/lib/eal/include/rte_thread.h
index f2581fe152..7ff031e1b2 100644
--- a/lib/eal/include/rte_thread.h
+++ b/lib/eal/include/rte_thread.h
@@ -56,10 +56,14 @@ typedef uint32_t (*rte_thread_func) (void *arg);
* Thread priority values.
*/
enum rte_thread_priority {
+ /** Normal thread priority, the default. */
RTE_THREAD_PRIORITY_NORMAL = 0,
- /**< normal thread priority, the default */
+ /**
+ * Highest thread priority, use with caution.
+ * WARNING: System may be unstable because of a real-time busy loop.
+ * @see rte_thread_yield_realtime().
+ */
RTE_THREAD_PRIORITY_REALTIME_CRITICAL = 1,
- /**< highest thread priority allowed */
};
/**
diff --git a/lib/eal/unix/rte_thread.c b/lib/eal/unix/rte_thread.c
index 278d8d342d..17ffb86c17 100644
--- a/lib/eal/unix/rte_thread.c
+++ b/lib/eal/unix/rte_thread.c
@@ -33,6 +33,8 @@ static int
thread_map_priority_to_os_value(enum rte_thread_priority eal_pri, int *os_pri,
int *pol)
{
+ static bool warned;
+
/* Clear the output parameters. */
*os_pri = sched_get_priority_min(SCHED_OTHER) - 1;
*pol = -1;
@@ -51,6 +53,17 @@ thread_map_priority_to_os_value(enum rte_thread_priority eal_pri, int *os_pri,
sched_get_priority_max(SCHED_OTHER)) / 2;
break;
case RTE_THREAD_PRIORITY_REALTIME_CRITICAL:
+ /*
+ * WARNING: Real-time busy loop takes priority on kernel threads,
+ * making the system unstable.
+ * There is also a known issue when using rte_ring.
+ */
+ if (!warned) {
+ RTE_LOG(NOTICE, EAL,
+ "Real-time thread is unstable if polling without sleep.\n");
+ warned = true;
+ }
+
*pol = SCHED_RR;
*os_pri = sched_get_priority_max(SCHED_RR);
break;
@@ -155,11 +168,6 @@ rte_thread_create(rte_thread_t *thread_id,
goto cleanup;
}
- if (thread_attr->priority ==
- RTE_THREAD_PRIORITY_REALTIME_CRITICAL) {
- ret = ENOTSUP;
- goto cleanup;
- }
ret = thread_map_priority_to_os_value(thread_attr->priority,
¶m.sched_priority, &policy);
if (ret != 0)
@@ -291,10 +299,6 @@ rte_thread_set_priority(rte_thread_t thread_id,
int policy;
int ret;
- /* Realtime priority can cause crashes on non-Windows platforms. */
- if (priority == RTE_THREAD_PRIORITY_REALTIME_CRITICAL)
- return ENOTSUP;
-
ret = thread_map_priority_to_os_value(priority, ¶m.sched_priority,
&policy);
if (ret != 0)
--
2.42.0
next prev parent reply other threads:[~2023-10-27 8:12 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-24 12:54 [PATCH] " Thomas Monjalon
2023-10-24 13:55 ` Morten Brørup
2023-10-24 16:04 ` Stephen Hemminger
2023-10-25 13:15 ` Thomas Monjalon
2023-10-25 13:34 ` Bruce Richardson
2023-10-25 13:44 ` Thomas Monjalon
2023-10-25 15:08 ` Stephen Hemminger
2023-10-25 15:14 ` Bruce Richardson
2023-10-25 15:18 ` Thomas Monjalon
2023-10-25 15:32 ` Thomas Monjalon
2023-10-25 15:13 ` [PATCH v2] " Thomas Monjalon
2023-10-25 15:37 ` Stephen Hemminger
2023-10-25 16:46 ` Thomas Monjalon
2023-10-25 17:54 ` Morten Brørup
2023-10-25 21:33 ` Stephen Hemminger
2023-10-26 7:33 ` Morten Brørup
2023-10-26 16:32 ` Stephen Hemminger
2023-10-26 17:07 ` Morten Brørup
2023-10-26 0:00 ` Stephen Hemminger
[not found] ` <20231025163352.1076755-1-thomas@monjalon.net>
2023-10-25 16:31 ` [PATCH v3 2/2] " Thomas Monjalon
[not found] ` <20231026134313.1165954-1-thomas@monjalon.net>
2023-10-26 13:37 ` [PATCH v4 " Thomas Monjalon
[not found] ` <20231026142749.1174372-1-thomas@monjalon.net>
2023-10-26 14:19 ` [PATCH v5 " Thomas Monjalon
2023-10-27 8:08 ` Thomas Monjalon [this message]
2023-10-27 8:45 ` [PATCH v6 1/1] " Morten Brørup
2023-10-27 9:11 ` Thomas Monjalon
2023-10-27 18:15 ` Stephen Hemminger
2024-10-07 19:27 ` Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231027081158.1358064-1-thomas@monjalon.net \
--to=thomas@monjalon.net \
--cc=anatoly.burakov@intel.com \
--cc=andrew.rybchenko@oktetlabs.ru \
--cc=david.marchand@redhat.com \
--cc=dev@dpdk.org \
--cc=dmitry.kozliuk@gmail.com \
--cc=konstantin.v.ananyev@yandex.ru \
--cc=mb@smartsharesystems.com \
--cc=navasile@linux.microsoft.com \
--cc=roretzla@linux.microsoft.com \
--cc=stable@dpdk.org \
--cc=stephen@networkplumber.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).