From: Daniel Wagner <dwagner@suse.de>
To: Clark Williams <williams@redhat.com>, John Kacur <jkacur@redhat.com>
Cc: linux-rt-users@vger.kernel.org,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
Daniel Wagner <dwagner@suse.de>
Subject: [rt-tests v1 1/3] rt-numa: Move thread placement code to rt-numa library
Date: Sun, 15 Nov 2020 19:40:57 +0100 [thread overview]
Message-ID: <20201115184059.7286-2-dwagner@suse.de> (raw)
In-Reply-To: <20201115184059.7286-1-dwagner@suse.de>
cyclictest contains code for calculating where to place threads
accoring the cpumask. Let's move it the rt-numa library to be able to
reuse it.
Signed-off-by: Daniel Wagner <dwagner@suse.de>
---
src/cyclictest/cyclictest.c | 98 +++----------------------------------
src/include/rt-numa.h | 12 +++++
src/lib/rt-numa.c | 78 +++++++++++++++++++++++++++++
3 files changed, 98 insertions(+), 90 deletions(-)
diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c
index f10f064f7a8e..0a797c540531 100644
--- a/src/cyclictest/cyclictest.c
+++ b/src/cyclictest/cyclictest.c
@@ -893,12 +893,6 @@ static int interval = DEFAULT_INTERVAL;
static int distance = -1;
static struct bitmask *affinity_mask = NULL;
static int smp = 0;
-
-enum {
- AFFINITY_UNSPECIFIED,
- AFFINITY_SPECIFIED,
- AFFINITY_USEALL
-};
static int setaffinity = AFFINITY_UNSPECIFIED;
static int clocksources[] = {
@@ -906,72 +900,6 @@ static int clocksources[] = {
CLOCK_REALTIME,
};
-/* Get available cpus according to getaffinity or according to the
- * intersection of getaffinity and the user specified affinity
- * in the case of AFFINITY_SPECIFIED, the function has to be called
- * after the call to parse_cpumask made in process_options()
- */
-static int get_available_cpus(void)
-{
- if (affinity_mask)
- return numa_bitmask_weight(affinity_mask);
-
- return numa_num_task_cpus();
-}
-
-/* cpu_for_thread AFFINITY_SPECIFIED */
-static int cpu_for_thread_sp(int thread_num, int max_cpus)
-{
- unsigned int m, cpu, i, num_cpus;
-
- num_cpus = rt_numa_bitmask_count(affinity_mask);
-
- if (num_cpus == 0)
- fatal("No allowable cpus to run on\n");
-
- m = thread_num % num_cpus;
-
- /* there are num_cpus bits set, we want position of m'th one */
- for (i = 0, cpu = 0; i < max_cpus; i++) {
- if (rt_numa_bitmask_isbitset(affinity_mask, i)) {
- if (cpu == m)
- return i;
- cpu++;
- }
- }
- fprintf(stderr, "Bug in cpu mask handling code.\n");
- return 0;
-}
-
-/* cpu_for_thread AFFINITY_USEALL */
-static int cpu_for_thread_ua(int thread_num, int max_cpus)
-{
- int res, num_cpus, i, m, cpu;
- pthread_t thread;
- cpu_set_t cpuset;
-
- thread = pthread_self();
- CPU_ZERO(&cpuset);
-
- res = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
- if (res != 0)
- fatal("pthread_getaffinity_np failed: %s\n", strerror(res));
-
- num_cpus = CPU_COUNT(&cpuset);
- m = thread_num % num_cpus;
-
- for (i = 0, cpu = 0; i < max_cpus; i++) {
- if (CPU_ISSET(i, &cpuset)) {
- if (cpu == m)
- return i;
- cpu++;
- }
- }
-
- fprintf(stderr, "Bug in cpu mask handling code.\n");
- return 0;
-}
-
static void handlepolicy(char *polname)
{
if (strncasecmp(polname, "other", 5) == 0)
@@ -1027,20 +955,6 @@ enum option_values {
OPT_TRACEMARK, OPT_POSIX_TIMERS,
};
-/* numa_available() must be called before any other calls to the numa library */
-static void numa_initialize(void)
-{
- static int is_initialized;
-
- if (is_initialized == 1)
- return;
-
- if (numa_available() != -1)
- numa = 1;
-
- is_initialized = 1;
-}
-
/* Process commandline options */
static void process_options(int argc, char *argv[], int max_cpus)
{
@@ -1104,7 +1018,9 @@ static void process_options(int argc, char *argv[], int max_cpus)
/* smp sets AFFINITY_USEALL in OPT_SMP */
if (smp)
break;
- numa_initialize();
+ if (numa_initialize())
+ fatal("Couldn't initilize libnuma");
+ numa = 1;
if (optarg) {
parse_cpumask(optarg, max_cpus, &affinity_mask);
setaffinity = AFFINITY_SPECIFIED;
@@ -1285,7 +1201,9 @@ static void process_options(int argc, char *argv[], int max_cpus)
/* if smp wasn't requested, test for numa automatically */
if (!smp) {
- numa_initialize();
+ if (numa_initialize())
+ fatal("Couldn't initilize libnuma");
+ numa = 1;
if (setaffinity == AFFINITY_UNSPECIFIED)
setaffinity = AFFINITY_USEALL;
}
@@ -1330,7 +1248,7 @@ static void process_options(int argc, char *argv[], int max_cpus)
error = 1;
if (num_threads == -1)
- num_threads = get_available_cpus();
+ num_threads = get_available_cpus(affinity_mask);
if (priospread && priority == 0) {
fprintf(stderr, "defaulting realtime priority to %d\n",
@@ -1998,7 +1916,7 @@ int main(int argc, char **argv)
switch (setaffinity) {
case AFFINITY_UNSPECIFIED: cpu = -1; break;
case AFFINITY_SPECIFIED:
- cpu = cpu_for_thread_sp(i, max_cpus);
+ cpu = cpu_for_thread_sp(i, max_cpus, affinity_mask);
if (verbose)
printf("Thread %d using cpu %d.\n", i, cpu);
break;
diff --git a/src/include/rt-numa.h b/src/include/rt-numa.h
index 047c8b6257cc..ca86a45dab3a 100644
--- a/src/include/rt-numa.h
+++ b/src/include/rt-numa.h
@@ -4,6 +4,18 @@
#include <numa.h>
+enum {
+ AFFINITY_UNSPECIFIED,
+ AFFINITY_SPECIFIED,
+ AFFINITY_USEALL
+};
+
+int numa_initialize(void);
+
+int get_available_cpus(struct bitmask *cpumask);
+int cpu_for_thread_sp(int thread_num, int max_cpus, struct bitmask *cpumask);
+int cpu_for_thread_ua(int thread_num, int max_cpus);
+
int parse_cpumask(char *str, int max_cpus, struct bitmask **cpumask);
#endif
diff --git a/src/lib/rt-numa.c b/src/lib/rt-numa.c
index a52a56e8aadd..76f8bd2f0ebe 100644
--- a/src/lib/rt-numa.c
+++ b/src/lib/rt-numa.c
@@ -6,9 +6,87 @@
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
+#include <sched.h>
+#include <pthread.h>
+#include "error.h"
#include "rt-numa.h"
+/* numa_available() must be called before any other calls to the numa library */
+int numa_initialize(void)
+{
+ static int is_initialized;
+
+ if (is_initialized == 1)
+ return 0;
+
+ if (numa_available() == -1)
+ return -1;
+
+ is_initialized = 1;
+ return 0;
+}
+
+int get_available_cpus(struct bitmask *cpumask)
+{
+ if (cpumask)
+ return numa_bitmask_weight(cpumask);
+
+ return numa_num_task_cpus();
+}
+
+int cpu_for_thread_sp(int thread_num, int max_cpus, struct bitmask *cpumask)
+{
+ unsigned int m, cpu, i, num_cpus;
+
+ num_cpus = numa_bitmask_weight(cpumask);
+
+ if (num_cpus == 0)
+ fatal("No allowable cpus to run on\n");
+
+ m = thread_num % num_cpus;
+
+ /* there are num_cpus bits set, we want position of m'th one */
+ for (i = 0, cpu = 0; i < max_cpus; i++) {
+ if (numa_bitmask_isbitset(cpumask, i)) {
+ if (cpu == m)
+ return i;
+ cpu++;
+ }
+ }
+ fprintf(stderr, "Bug in cpu mask handling code.\n");
+ return 0;
+}
+
+/* cpu_for_thread AFFINITY_USEALL */
+int cpu_for_thread_ua(int thread_num, int max_cpus)
+{
+ int res, num_cpus, i, m, cpu;
+ pthread_t thread;
+ cpu_set_t cpuset;
+
+ thread = pthread_self();
+ CPU_ZERO(&cpuset);
+
+ res = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
+ if (res != 0)
+ fatal("pthread_getaffinity_np failed: %s\n", strerror(res));
+
+ num_cpus = CPU_COUNT(&cpuset);
+ m = thread_num % num_cpus;
+
+ for (i = 0, cpu = 0; i < max_cpus; i++) {
+ if (CPU_ISSET(i, &cpuset)) {
+ if (cpu == m)
+ return i;
+ cpu++;
+ }
+ }
+
+ fprintf(stderr, "Bug in cpu mask handling code.\n");
+ return 0;
+}
+
/*
* After this function is called, affinity_mask is the intersection of
* the user supplied affinity mask and the affinity mask from the run
--
2.29.2
next prev parent reply other threads:[~2020-11-15 18:41 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-15 18:40 [rt-tests v1 0/3] Teach signaltest affinity Daniel Wagner
2020-11-15 18:40 ` Daniel Wagner [this message]
2020-11-20 21:38 ` [rt-tests v1 1/3] rt-numa: Move thread placement code to rt-numa library John Kacur
2020-11-15 18:40 ` [rt-tests v1 2/3] signaltest: Implement thread placing Daniel Wagner
2020-11-20 21:44 ` John Kacur
2020-11-15 18:40 ` [rt-tests v1 3/3] signaltest: Set affintiy on default Daniel Wagner
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=20201115184059.7286-2-dwagner@suse.de \
--to=dwagner@suse.de \
--cc=bigeasy@linutronix.de \
--cc=jkacur@redhat.com \
--cc=linux-rt-users@vger.kernel.org \
--cc=williams@redhat.com \
/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