All of lore.kernel.org
 help / color / mirror / Atom feed
* [rt-tests v1 0/6] Move common code to helper libraries
@ 2020-11-13 21:09 Daniel Wagner
  2020-11-13 21:09 ` [rt-tests v1 1/6] rt-utils: Introduce parse_mem_string() Daniel Wagner
                   ` (5 more replies)
  0 siblings, 6 replies; 17+ messages in thread
From: Daniel Wagner @ 2020-11-13 21:09 UTC (permalink / raw)
  To: Clark Williams, John Kacur; +Cc: linux-rt-users, Daniel Wagner

Hi,

These patches are left over from the last cleanup series[1]. The first
two move the parse_mem_string() to rt-utils.h. The rest move the NUMA
bits into a new helper library and udpate the existing code to use the
new helpers.

Thanks,
Daniel

[1] https://lore.kernel.org/linux-rt-users/20201007085653.11961-1-dwagner@suse.de/

Daniel Wagner (6):
  rt-utils: Introduce parse_mem_string()
  oslat: Use string parser utilies
  cyclictest: Remove deadcode checking for NUMA
  rt-numa: Introduce NUMA helpers
  cyclictest: Use parse_cpumask() from rt-numa.h
  oslat: Use parse_cpumask() from rt-numa.h

 Makefile                    |  18 +++---
 src/cyclictest/cyclictest.c |  75 +++++-----------------
 src/include/rt-numa.h       |   9 +++
 src/include/rt-utils.h      |   1 +
 src/lib/rt-numa.c           |  56 +++++++++++++++++
 src/lib/rt-utils.c          |  30 +++++++++
 src/oslat/oslat.c           | 122 ++++++------------------------------
 7 files changed, 138 insertions(+), 173 deletions(-)
 create mode 100644 src/include/rt-numa.h
 create mode 100644 src/lib/rt-numa.c

-- 
2.29.2


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

* [rt-tests v1 1/6] rt-utils: Introduce parse_mem_string()
  2020-11-13 21:09 [rt-tests v1 0/6] Move common code to helper libraries Daniel Wagner
@ 2020-11-13 21:09 ` Daniel Wagner
  2020-11-18 20:59   ` John Kacur
  2020-11-13 21:09 ` [rt-tests v1 2/6] oslat: Use string parser utilies Daniel Wagner
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Daniel Wagner @ 2020-11-13 21:09 UTC (permalink / raw)
  To: Clark Williams, John Kacur; +Cc: linux-rt-users, Daniel Wagner

Add helper to parse common memory prefixes on strings.

Signed-off-by: Daniel Wagner <dwagner@suse.de>
---
 src/include/rt-utils.h |  1 +
 src/lib/rt-utils.c     | 30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/src/include/rt-utils.h b/src/include/rt-utils.h
index c6fb220cdb0a..39ddbd9eae29 100644
--- a/src/include/rt-utils.h
+++ b/src/include/rt-utils.h
@@ -28,6 +28,7 @@ uint32_t string_to_policy(const char *str);
 pid_t gettid(void);
 
 int parse_time_string(char *val);
+int parse_mem_string(char *str, uint64_t *val);
 
 void enable_trace_mark(void);
 void tracemark(char *fmt, ...) __attribute__((format(printf, 1, 2)));
diff --git a/src/lib/rt-utils.c b/src/lib/rt-utils.c
index a30e1e4ce436..2d68d62cd875 100644
--- a/src/lib/rt-utils.c
+++ b/src/lib/rt-utils.c
@@ -362,6 +362,36 @@ int parse_time_string(char *val)
 	return t;
 }
 
+int parse_mem_string(char *str, uint64_t *val)
+{
+	char *endptr;
+	int v = strtol(str, &endptr, 10);
+
+	if (!*endptr)
+		return v;
+
+	switch (*endptr) {
+	case 'g':
+	case 'G':
+		v *= 1024;
+	case 'm':
+	case 'M':
+		v *= 1024;
+	case 'k':
+	case 'K':
+		v *= 1024;
+	case 'b':
+	case 'B':
+		break;
+	default:
+		return -1;
+	}
+
+	*val = v;
+
+	return 0;
+}
+
 static void open_tracemark_fd(void)
 {
 	char path[MAX_PATH];
-- 
2.29.2


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

* [rt-tests v1 2/6] oslat: Use string parser utilies
  2020-11-13 21:09 [rt-tests v1 0/6] Move common code to helper libraries Daniel Wagner
  2020-11-13 21:09 ` [rt-tests v1 1/6] rt-utils: Introduce parse_mem_string() Daniel Wagner
@ 2020-11-13 21:09 ` Daniel Wagner
  2020-11-18 21:00   ` John Kacur
  2020-11-13 21:09 ` [rt-tests v1 3/6] cyclictest: Remove deadcode checking for NUMA Daniel Wagner
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Daniel Wagner @ 2020-11-13 21:09 UTC (permalink / raw)
  To: Clark Williams, John Kacur; +Cc: linux-rt-users, Daniel Wagner

Use available parse_time_string() instead locally implemented
version. While at it move the mem parser helper to the global utility
header.

Signed-off-by: Daniel Wagner <dwagner@suse.de>
---
 src/oslat/oslat.c | 67 ++---------------------------------------------
 1 file changed, 2 insertions(+), 65 deletions(-)

diff --git a/src/oslat/oslat.c b/src/oslat/oslat.c
index 0018c472e0c1..b2aa15001be2 100644
--- a/src/oslat/oslat.c
+++ b/src/oslat/oslat.c
@@ -572,69 +572,6 @@ static int parse_cpu_list(char *cpu_list, cpu_set_t *cpu_set)
 	return n_cores;
 }
 
-static int parse_runtime(const char *str)
-{
-	char *endptr;
-	int v = strtol(str, &endptr, 10);
-
-	if (!*endptr)
-		return v;
-
-	switch (*endptr) {
-	case 'd':
-	case 'D':
-		/* Days */
-		v *= 24;
-	case 'h':
-	case 'H':
-		/* Hours */
-		v *= 60;
-	case 'm':
-	case 'M':
-		/* Minutes */
-		v *= 60;
-	case 's':
-	case 'S':
-		/* Seconds */
-		break;
-	default:
-		printf("Unknown runtime suffix: %s\n", endptr);
-		v = 0;
-		break;
-	}
-
-	return v;
-}
-
-static int parse_mem_size(char *str, uint64_t *val)
-{
-	char *endptr;
-	int v = strtol(str, &endptr, 10);
-
-	if (!*endptr)
-		return v;
-
-	switch (*endptr) {
-	case 'g':
-	case 'G':
-		v *= 1024;
-	case 'm':
-	case 'M':
-		v *= 1024;
-	case 'k':
-	case 'K':
-		v *= 1024;
-	case 'b':
-	case 'B':
-		break;
-	default:
-		return -1;
-	}
-
-	*val = v;
-
-	return 0;
-}
 
 static int workload_select(char *name)
 {
@@ -702,7 +639,7 @@ static void parse_options(int argc, char *argv[])
 			}
 			break;
 		case 'D':
-			g.runtime = parse_runtime(optarg);
+			g.runtime = parse_time_string(optarg);
 			if (!g.runtime) {
 				printf("Illegal runtime: %s\n", optarg);
 				exit(1);
@@ -736,7 +673,7 @@ static void parse_options(int argc, char *argv[])
 			}
 			break;
 		case 'm':
-			if (parse_mem_size(optarg, &g.workload_mem_size)) {
+			if (parse_mem_string(optarg, &g.workload_mem_size)) {
 				printf("Unknown workload memory size '%s'.\n\n", optarg);
 				exit(1);
 			}
-- 
2.29.2


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

* [rt-tests v1 3/6] cyclictest: Remove deadcode checking for NUMA
  2020-11-13 21:09 [rt-tests v1 0/6] Move common code to helper libraries Daniel Wagner
  2020-11-13 21:09 ` [rt-tests v1 1/6] rt-utils: Introduce parse_mem_string() Daniel Wagner
  2020-11-13 21:09 ` [rt-tests v1 2/6] oslat: Use string parser utilies Daniel Wagner
@ 2020-11-13 21:09 ` Daniel Wagner
  2020-11-18 21:01   ` John Kacur
  2020-11-13 21:09 ` [rt-tests v1 4/6] rt-numa: Introduce NUMA helpers Daniel Wagner
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Daniel Wagner @ 2020-11-13 21:09 UTC (permalink / raw)
  To: Clark Williams, John Kacur; +Cc: linux-rt-users, Daniel Wagner

The NUMA library is always present for cyclictest, thus NUMA config is
always defined. Remove deadcode.

Signed-off-by: Daniel Wagner <dwagner@suse.de>
---
 src/cyclictest/cyclictest.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c
index 3282ab1b856b..46d88ed155c5 100644
--- a/src/cyclictest/cyclictest.c
+++ b/src/cyclictest/cyclictest.c
@@ -1327,14 +1327,9 @@ static void process_options(int argc, char *argv[], int max_cpus)
 
 	/* if smp wasn't requested, test for numa automatically */
 	if (!smp) {
-#ifdef NUMA
 		numa_initialize();
 		if (setaffinity == AFFINITY_UNSPECIFIED)
 			setaffinity = AFFINITY_USEALL;
-#else
-		warn("cyclictest was not built with the numa option\n");
-		numa = 0;
-#endif
 	}
 
 	if (option_affinity) {
-- 
2.29.2


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

* [rt-tests v1 4/6] rt-numa: Introduce NUMA helpers
  2020-11-13 21:09 [rt-tests v1 0/6] Move common code to helper libraries Daniel Wagner
                   ` (2 preceding siblings ...)
  2020-11-13 21:09 ` [rt-tests v1 3/6] cyclictest: Remove deadcode checking for NUMA Daniel Wagner
@ 2020-11-13 21:09 ` Daniel Wagner
  2020-11-18 21:09   ` John Kacur
  2020-11-13 21:09 ` [rt-tests v1 5/6] cyclictest: Use parse_cpumask() from rt-numa.h Daniel Wagner
  2020-11-13 21:09 ` [rt-tests v1 6/6] oslat: " Daniel Wagner
  5 siblings, 1 reply; 17+ messages in thread
From: Daniel Wagner @ 2020-11-13 21:09 UTC (permalink / raw)
  To: Clark Williams, John Kacur; +Cc: linux-rt-users, Daniel Wagner

A common task is to parse the provided cpumask from the command
line. Add a helper which uses libnuma. Since we don't want to add
unnecessary dependencies for tests which don't need this helper create
a new library containing the NUMA bits.

Signed-off-by: Daniel Wagner <dwagner@suse.de>
---
 Makefile              | 18 +++++++-------
 src/include/rt-numa.h |  9 +++++++
 src/lib/rt-numa.c     | 56 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+), 9 deletions(-)
 create mode 100644 src/include/rt-numa.h
 create mode 100644 src/lib/rt-numa.c

diff --git a/Makefile b/Makefile
index 24895b7f9697..3afdfd4d53a7 100644
--- a/Makefile
+++ b/Makefile
@@ -24,6 +24,7 @@ TARGETS = $(sources:.c=)
 LIBS	= -lrt -lpthread
 RTTESTLIB = -lrttest -L$(OBJDIR)
 EXTRA_LIBS ?= -ldl	# for get_cpu
+RTTESTNUMA = -lrttestnuma -lnuma
 DESTDIR	?=
 prefix  ?= /usr/local
 bindir  ?= $(prefix)/bin
@@ -84,11 +85,6 @@ ostype := $(lastword $(subst -, ,$(dumpmachine)))
 machinetype := $(shell echo $(dumpmachine)| \
     sed -e 's/-.*//' -e 's/i.86/i386/' -e 's/mips.*/mips/' -e 's/ppc.*/powerpc/')
 
-# You have to have libnuma installed, which is fine to do even if you are
-# running on non-numa machines
-CFLAGS += -DNUMA
-NUMA_LIBS = -lnuma
-
 include src/arch/android/Makefile
 
 VPATH	= src/cyclictest:
@@ -122,8 +118,8 @@ all: $(TARGETS) hwlatdetect get_cyclictest_snapshot | $(OBJDIR)
 # Include dependency files, automatically generate them if needed.
 -include $(addprefix $(OBJDIR)/,$(sources:.c=.d))
 
-cyclictest: $(OBJDIR)/cyclictest.o $(OBJDIR)/librttest.a
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB) $(NUMA_LIBS)
+cyclictest: $(OBJDIR)/cyclictest.o $(OBJDIR)/librttest.a $(OBJDIR)/librttestnuma.a
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB) $(RTTESTNUMA)
 
 cyclicdeadline: $(OBJDIR)/cyclicdeadline.o $(OBJDIR)/librttest.a
 	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB)
@@ -172,8 +168,8 @@ queuelat: $(OBJDIR)/queuelat.o $(OBJDIR)/librttest.a
 ssdd: $(OBJDIR)/ssdd.o $(OBJDIR)/librttest.a
 	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB)
 
-oslat: $(OBJDIR)/oslat.o $(OBJDIR)/librttest.a
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB) $(NUMA_LIBS)
+oslat: $(OBJDIR)/oslat.o $(OBJDIR)/librttest.a $(OBJDIR)/librttestnuma.a
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB) $(RTTESTNUMA)
 
 %.8.gz: %.8
 	gzip -nc $< > $@
@@ -185,6 +181,10 @@ LIBOBJS =$(addprefix $(OBJDIR)/,error.o rt-get_cpu.o rt-sched.o rt-utils.o)
 $(OBJDIR)/librttest.a: $(LIBOBJS)
 	$(AR) rcs $@ $^
 
+LIBNUMAOBJS =$(addprefix $(OBJDIR)/,rt-numa.o)
+$(OBJDIR)/librttestnuma.a: $(LIBNUMAOBJS)
+	$(AR) rcs $@ $^
+
 CLEANUP  = $(TARGETS) *.o .depend *.*~ *.orig *.rej *.d *.a *.8.gz *.8.bz2
 CLEANUP += $(if $(wildcard .git), ChangeLog)
 
diff --git a/src/include/rt-numa.h b/src/include/rt-numa.h
new file mode 100644
index 000000000000..047c8b6257cc
--- /dev/null
+++ b/src/include/rt-numa.h
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#ifndef __RT_NUMA_H
+#define __RT_NUMA_H
+
+#include <numa.h>
+
+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
new file mode 100644
index 000000000000..a52a56e8aadd
--- /dev/null
+++ b/src/lib/rt-numa.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2020 Daniel Wagner <dwagner@suse.de>
+ */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "rt-numa.h"
+
+/*
+ * After this function is called, affinity_mask is the intersection of
+ * the user supplied affinity mask and the affinity mask from the run
+ * time environment
+ */
+static void use_current_cpuset(int max_cpus, struct bitmask *cpumask)
+{
+	struct bitmask *curmask;
+	int i;
+
+	curmask = numa_allocate_cpumask();
+	numa_sched_getaffinity(getpid(), curmask);
+
+	/*
+	 * Clear bits that are not set in both the cpuset from the
+	 * environment, and in the user specified affinity.
+	 */
+	for (i = 0; i < max_cpus; i++) {
+		if ((!numa_bitmask_isbitset(cpumask, i)) ||
+		    (!numa_bitmask_isbitset(curmask, i)))
+			numa_bitmask_clearbit(cpumask, i);
+	}
+
+	numa_bitmask_free(curmask);
+}
+
+int parse_cpumask(char *str, int max_cpus, struct bitmask **cpumask)
+{
+	struct bitmask *mask;
+
+	mask = numa_parse_cpustring_all(str);
+	if (!mask)
+		return -ENOMEM;
+
+	if (numa_bitmask_weight(mask) == 0) {
+		numa_bitmask_free(mask);
+		*cpumask = NULL;
+		return 0;
+	}
+
+	use_current_cpuset(max_cpus, mask);
+	*cpumask = mask;
+
+	return 0;
+}
-- 
2.29.2


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

* [rt-tests v1 5/6] cyclictest: Use parse_cpumask() from rt-numa.h
  2020-11-13 21:09 [rt-tests v1 0/6] Move common code to helper libraries Daniel Wagner
                   ` (3 preceding siblings ...)
  2020-11-13 21:09 ` [rt-tests v1 4/6] rt-numa: Introduce NUMA helpers Daniel Wagner
@ 2020-11-13 21:09 ` Daniel Wagner
  2020-11-18 21:10   ` John Kacur
  2020-11-18 21:17   ` John Kacur
  2020-11-13 21:09 ` [rt-tests v1 6/6] oslat: " Daniel Wagner
  5 siblings, 2 replies; 17+ messages in thread
From: Daniel Wagner @ 2020-11-13 21:09 UTC (permalink / raw)
  To: Clark Williams, John Kacur; +Cc: linux-rt-users, Daniel Wagner

Use the helper funtion from rt-numa.h to parse the cpumask from the
command line.

Signed-off-by: Daniel Wagner <dwagner@suse.de>
---
 src/cyclictest/cyclictest.c | 70 ++++++++-----------------------------
 1 file changed, 14 insertions(+), 56 deletions(-)

diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c
index 46d88ed155c5..f10f064f7a8e 100644
--- a/src/cyclictest/cyclictest.c
+++ b/src/cyclictest/cyclictest.c
@@ -36,6 +36,7 @@
 #include "rt_numa.h"
 
 #include "rt-utils.h"
+#include "rt-numa.h"
 
 #include <bionic.h>
 
@@ -905,11 +906,6 @@ static int clocksources[] = {
 	CLOCK_REALTIME,
 };
 
-static unsigned int is_cpumask_zero(const struct bitmask *mask)
-{
-	return (rt_numa_bitmask_count(mask) == 0);
-}
-
 /* 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
@@ -976,53 +972,6 @@ static int cpu_for_thread_ua(int thread_num, int max_cpus)
 	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 time environment
- */
-static void use_current_cpuset(const int max_cpus)
-{
-	int i;
-	pid_t pid;
-	struct bitmask *curmask;
-
-	pid = getpid();
-
-	curmask = numa_allocate_cpumask();
-	numa_sched_getaffinity(pid, curmask);
-
-	/* Clear bits that are not set in both the cpuset from the environment,
-	 * and in the user specified affinity for cyclictest
-	 */
-	for (i=0; i < max_cpus; i++) {
-		if ((!rt_numa_bitmask_isbitset(affinity_mask, i)) || (!rt_numa_bitmask_isbitset(curmask, i)))
-			numa_bitmask_clearbit(affinity_mask, i);
-	}
-
-	numa_bitmask_free(curmask);
-}
-
-static void parse_cpumask(const char *option, const int max_cpus)
-{
-	affinity_mask = rt_numa_parse_cpustring(option, max_cpus);
-	if (affinity_mask) {
-		if (is_cpumask_zero(affinity_mask)) {
-			rt_bitmask_free(affinity_mask);
-			affinity_mask = NULL;
-		} else {
-			use_current_cpuset(max_cpus);
-		}
-
-	}
-	if (!affinity_mask)
-		display_help(1);
-
-	if (verbose) {
-		printf("%s: Using %u cpus.\n", __func__,
-			rt_numa_bitmask_count(affinity_mask));
-	}
-}
-
 static void handlepolicy(char *polname)
 {
 	if (strncasecmp(polname, "other", 5) == 0)
@@ -1156,15 +1105,24 @@ static void process_options(int argc, char *argv[], int max_cpus)
 			if (smp)
 				break;
 			numa_initialize();
-			if (optarg != NULL) {
-				parse_cpumask(optarg, max_cpus);
+			if (optarg) {
+				parse_cpumask(optarg, max_cpus, &affinity_mask);
 				setaffinity = AFFINITY_SPECIFIED;
-			} else if (optind < argc && (atoi(argv[optind]) || argv[optind][0] == '0' || argv[optind][0] == '!')) {
-				parse_cpumask(argv[optind], max_cpus);
+			} else if (optind < argc &&
+				   (atoi(argv[optind]) ||
+				    argv[optind][0] == '0' ||
+				    argv[optind][0] == '!')) {
+				parse_cpumask(argv[optind], max_cpus, &affinity_mask);
 				setaffinity = AFFINITY_SPECIFIED;
 			} else {
 				setaffinity = AFFINITY_USEALL;
 			}
+
+			if (setaffinity == AFFINITY_SPECIFIED && !affinity_mask)
+				display_help(1);
+			if (verbose)
+				printf("Using %u cpus.\n",
+					numa_bitmask_weight(affinity_mask));
 			break;
 		case 'A':
 		case OPT_ALIGNED:
-- 
2.29.2


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

* [rt-tests v1 6/6] oslat: Use parse_cpumask() from rt-numa.h
  2020-11-13 21:09 [rt-tests v1 0/6] Move common code to helper libraries Daniel Wagner
                   ` (4 preceding siblings ...)
  2020-11-13 21:09 ` [rt-tests v1 5/6] cyclictest: Use parse_cpumask() from rt-numa.h Daniel Wagner
@ 2020-11-13 21:09 ` Daniel Wagner
  2020-11-18 21:18   ` John Kacur
  2021-02-10 16:07   ` Peter Xu
  5 siblings, 2 replies; 17+ messages in thread
From: Daniel Wagner @ 2020-11-13 21:09 UTC (permalink / raw)
  To: Clark Williams, John Kacur; +Cc: linux-rt-users, Daniel Wagner

Use the common parse_cpumask() helper and use struct bitmask directly
instead transforming it into a CPU_SET first.

Signed-off-by: Daniel Wagner <dwagner@suse.de>
---
 src/oslat/oslat.c | 55 +++++++++++++++--------------------------------
 1 file changed, 17 insertions(+), 38 deletions(-)

diff --git a/src/oslat/oslat.c b/src/oslat/oslat.c
index b2aa15001be2..5b7e0d5b5d5c 100644
--- a/src/oslat/oslat.c
+++ b/src/oslat/oslat.c
@@ -42,6 +42,7 @@
 #include <sys/syscall.h>
 
 #include "rt-utils.h"
+#include "rt-numa.h"
 #include "error.h"
 
 #ifdef __GNUC__
@@ -542,37 +543,6 @@ static void usage(int error)
 	exit(error);
 }
 
-/* TODO: use libnuma? */
-static int parse_cpu_list(char *cpu_list, cpu_set_t *cpu_set)
-{
-	struct bitmask *cpu_mask;
-	int i, n_cores;
-
-	n_cores = sysconf(_SC_NPROCESSORS_CONF);
-
-	if (!cpu_list) {
-		for (i = 0; i < n_cores; i++)
-			CPU_SET(i, cpu_set);
-		return n_cores;
-	}
-
-	cpu_mask = numa_parse_cpustring_all(cpu_list);
-	if (cpu_mask) {
-		for (i = 0; i < n_cores; i++) {
-			if (numa_bitmask_isbitset(cpu_mask, i))
-				CPU_SET(i, cpu_set);
-		}
-		numa_bitmask_free(cpu_mask);
-	} else {
-		warn("Unknown cpu-list: %s, using all available cpus\n", cpu_list);
-		for (i = 0; i < n_cores; i++)
-			CPU_SET(i, cpu_set);
-	}
-
-	return n_cores;
-}
-
-
 static int workload_select(char *name)
 {
 	int i = 0;
@@ -745,15 +715,18 @@ int main(int argc, char *argv[])
 {
 	struct thread *threads;
 	int i, n_cores;
-	cpu_set_t cpu_set;
+	struct bitmask *cpu_set = NULL;
+	int max_cpus = sysconf(_SC_NPROCESSORS_ONLN);
 
 #ifdef FRC_MISSING
 	printf("This architecture is not yet supported. "
 	       "Please implement frc() function first for %s.\n", argv[0]);
 	return 0;
 #endif
-
-	CPU_ZERO(&cpu_set);
+	if (numa_available() == -1) {
+		printf("ERROR: Could not initialize libnuma\n");
+		exit(1);
+	}
 
 	g.app_name = argv[0];
 	g.rtprio = 0;
@@ -768,16 +741,22 @@ int main(int argc, char *argv[])
 
 	TEST(mlockall(MCL_CURRENT | MCL_FUTURE) == 0);
 
-	n_cores = parse_cpu_list(g.cpu_list, &cpu_set);
+	if (!g.cpu_list)
+		g.cpu_list = strdup("all");
+	if (parse_cpumask(g.cpu_list, max_cpus, &cpu_set))
+		exit(1);
+	n_cores = numa_bitmask_weight(cpu_set);
 
-	TEST(threads = calloc(1, CPU_COUNT(&cpu_set) * sizeof(threads[0])));
+	TEST(threads = calloc(1, n_cores * sizeof(threads[0])));
 	for (i = 0; i < n_cores; ++i)
-		if (CPU_ISSET(i, &cpu_set) && move_to_core(i) == 0)
+		if (numa_bitmask_isbitset(cpu_set, i) && move_to_core(i) == 0)
 			threads[g.n_threads_total++].core_i = i;
 
-	if (CPU_ISSET(0, &cpu_set) && g.rtprio)
+	if (numa_bitmask_isbitset(cpu_set, 0) && g.rtprio)
 		printf("WARNING: Running SCHED_FIFO workload on CPU 0 may hang the thread\n");
 
+	numa_bitmask_free(cpu_set);
+
 	TEST(move_to_core(g.cpu_main_thread) == 0);
 
 	signal(SIGALRM, handle_alarm);
-- 
2.29.2


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

* Re: [rt-tests v1 1/6] rt-utils: Introduce parse_mem_string()
  2020-11-13 21:09 ` [rt-tests v1 1/6] rt-utils: Introduce parse_mem_string() Daniel Wagner
@ 2020-11-18 20:59   ` John Kacur
  0 siblings, 0 replies; 17+ messages in thread
From: John Kacur @ 2020-11-18 20:59 UTC (permalink / raw)
  To: Daniel Wagner; +Cc: Clark Williams, linux-rt-users



On Fri, 13 Nov 2020, Daniel Wagner wrote:

> Add helper to parse common memory prefixes on strings.
> 
> Signed-off-by: Daniel Wagner <dwagner@suse.de>
> ---
>  src/include/rt-utils.h |  1 +
>  src/lib/rt-utils.c     | 30 ++++++++++++++++++++++++++++++
>  2 files changed, 31 insertions(+)
> 
> diff --git a/src/include/rt-utils.h b/src/include/rt-utils.h
> index c6fb220cdb0a..39ddbd9eae29 100644
> --- a/src/include/rt-utils.h
> +++ b/src/include/rt-utils.h
> @@ -28,6 +28,7 @@ uint32_t string_to_policy(const char *str);
>  pid_t gettid(void);
>  
>  int parse_time_string(char *val);
> +int parse_mem_string(char *str, uint64_t *val);
>  
>  void enable_trace_mark(void);
>  void tracemark(char *fmt, ...) __attribute__((format(printf, 1, 2)));
> diff --git a/src/lib/rt-utils.c b/src/lib/rt-utils.c
> index a30e1e4ce436..2d68d62cd875 100644
> --- a/src/lib/rt-utils.c
> +++ b/src/lib/rt-utils.c
> @@ -362,6 +362,36 @@ int parse_time_string(char *val)
>  	return t;
>  }
>  
> +int parse_mem_string(char *str, uint64_t *val)
> +{
> +	char *endptr;
> +	int v = strtol(str, &endptr, 10);
> +
> +	if (!*endptr)
> +		return v;
> +
> +	switch (*endptr) {
> +	case 'g':
> +	case 'G':
> +		v *= 1024;
> +	case 'm':
> +	case 'M':
> +		v *= 1024;
> +	case 'k':
> +	case 'K':
> +		v *= 1024;
> +	case 'b':
> +	case 'B':
> +		break;
> +	default:
> +		return -1;
> +	}
> +
> +	*val = v;
> +
> +	return 0;
> +}
> +
>  static void open_tracemark_fd(void)
>  {
>  	char path[MAX_PATH];
> -- 
> 2.29.2
> 
> 

Signed-off-by: John Kacur <jkacur@redhat.com>

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

* Re: [rt-tests v1 2/6] oslat: Use string parser utilies
  2020-11-13 21:09 ` [rt-tests v1 2/6] oslat: Use string parser utilies Daniel Wagner
@ 2020-11-18 21:00   ` John Kacur
  0 siblings, 0 replies; 17+ messages in thread
From: John Kacur @ 2020-11-18 21:00 UTC (permalink / raw)
  To: Daniel Wagner; +Cc: Clark Williams, linux-rt-users



On Fri, 13 Nov 2020, Daniel Wagner wrote:

> Use available parse_time_string() instead locally implemented
> version. While at it move the mem parser helper to the global utility
> header.
> 
> Signed-off-by: Daniel Wagner <dwagner@suse.de>
> ---
>  src/oslat/oslat.c | 67 ++---------------------------------------------
>  1 file changed, 2 insertions(+), 65 deletions(-)
> 
> diff --git a/src/oslat/oslat.c b/src/oslat/oslat.c
> index 0018c472e0c1..b2aa15001be2 100644
> --- a/src/oslat/oslat.c
> +++ b/src/oslat/oslat.c
> @@ -572,69 +572,6 @@ static int parse_cpu_list(char *cpu_list, cpu_set_t *cpu_set)
>  	return n_cores;
>  }
>  
> -static int parse_runtime(const char *str)
> -{
> -	char *endptr;
> -	int v = strtol(str, &endptr, 10);
> -
> -	if (!*endptr)
> -		return v;
> -
> -	switch (*endptr) {
> -	case 'd':
> -	case 'D':
> -		/* Days */
> -		v *= 24;
> -	case 'h':
> -	case 'H':
> -		/* Hours */
> -		v *= 60;
> -	case 'm':
> -	case 'M':
> -		/* Minutes */
> -		v *= 60;
> -	case 's':
> -	case 'S':
> -		/* Seconds */
> -		break;
> -	default:
> -		printf("Unknown runtime suffix: %s\n", endptr);
> -		v = 0;
> -		break;
> -	}
> -
> -	return v;
> -}
> -
> -static int parse_mem_size(char *str, uint64_t *val)
> -{
> -	char *endptr;
> -	int v = strtol(str, &endptr, 10);
> -
> -	if (!*endptr)
> -		return v;
> -
> -	switch (*endptr) {
> -	case 'g':
> -	case 'G':
> -		v *= 1024;
> -	case 'm':
> -	case 'M':
> -		v *= 1024;
> -	case 'k':
> -	case 'K':
> -		v *= 1024;
> -	case 'b':
> -	case 'B':
> -		break;
> -	default:
> -		return -1;
> -	}
> -
> -	*val = v;
> -
> -	return 0;
> -}
>  
>  static int workload_select(char *name)
>  {
> @@ -702,7 +639,7 @@ static void parse_options(int argc, char *argv[])
>  			}
>  			break;
>  		case 'D':
> -			g.runtime = parse_runtime(optarg);
> +			g.runtime = parse_time_string(optarg);
>  			if (!g.runtime) {
>  				printf("Illegal runtime: %s\n", optarg);
>  				exit(1);
> @@ -736,7 +673,7 @@ static void parse_options(int argc, char *argv[])
>  			}
>  			break;
>  		case 'm':
> -			if (parse_mem_size(optarg, &g.workload_mem_size)) {
> +			if (parse_mem_string(optarg, &g.workload_mem_size)) {
>  				printf("Unknown workload memory size '%s'.\n\n", optarg);
>  				exit(1);
>  			}
> -- 
> 2.29.2
> 
> 
Signed-off-by: John Kacur <jkacur@redhat.com>

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

* Re: [rt-tests v1 3/6] cyclictest: Remove deadcode checking for NUMA
  2020-11-13 21:09 ` [rt-tests v1 3/6] cyclictest: Remove deadcode checking for NUMA Daniel Wagner
@ 2020-11-18 21:01   ` John Kacur
  0 siblings, 0 replies; 17+ messages in thread
From: John Kacur @ 2020-11-18 21:01 UTC (permalink / raw)
  To: Daniel Wagner; +Cc: Clark Williams, linux-rt-users



On Fri, 13 Nov 2020, Daniel Wagner wrote:

> The NUMA library is always present for cyclictest, thus NUMA config is
> always defined. Remove deadcode.
> 
> Signed-off-by: Daniel Wagner <dwagner@suse.de>
> ---
>  src/cyclictest/cyclictest.c | 5 -----
>  1 file changed, 5 deletions(-)
> 
> diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c
> index 3282ab1b856b..46d88ed155c5 100644
> --- a/src/cyclictest/cyclictest.c
> +++ b/src/cyclictest/cyclictest.c
> @@ -1327,14 +1327,9 @@ static void process_options(int argc, char *argv[], int max_cpus)
>  
>  	/* if smp wasn't requested, test for numa automatically */
>  	if (!smp) {
> -#ifdef NUMA
>  		numa_initialize();
>  		if (setaffinity == AFFINITY_UNSPECIFIED)
>  			setaffinity = AFFINITY_USEALL;
> -#else
> -		warn("cyclictest was not built with the numa option\n");
> -		numa = 0;
> -#endif
>  	}
>  
>  	if (option_affinity) {
> -- 
> 2.29.2
> 
> 
Signed-off-by: John Kacur <jkacur@redhat.com>

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

* Re: [rt-tests v1 4/6] rt-numa: Introduce NUMA helpers
  2020-11-13 21:09 ` [rt-tests v1 4/6] rt-numa: Introduce NUMA helpers Daniel Wagner
@ 2020-11-18 21:09   ` John Kacur
  2020-11-19  8:21     ` Daniel Wagner
  0 siblings, 1 reply; 17+ messages in thread
From: John Kacur @ 2020-11-18 21:09 UTC (permalink / raw)
  To: Daniel Wagner; +Cc: Clark Williams, linux-rt-users



On Fri, 13 Nov 2020, Daniel Wagner wrote:

> A common task is to parse the provided cpumask from the command
> line. Add a helper which uses libnuma. Since we don't want to add
> unnecessary dependencies for tests which don't need this helper create
> a new library containing the NUMA bits.
> 
> Signed-off-by: Daniel Wagner <dwagner@suse.de>
> ---
>  Makefile              | 18 +++++++-------
>  src/include/rt-numa.h |  9 +++++++
>  src/lib/rt-numa.c     | 56 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 74 insertions(+), 9 deletions(-)
>  create mode 100644 src/include/rt-numa.h
>  create mode 100644 src/lib/rt-numa.c
> 
> diff --git a/Makefile b/Makefile
> index 24895b7f9697..3afdfd4d53a7 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -24,6 +24,7 @@ TARGETS = $(sources:.c=)
>  LIBS	= -lrt -lpthread
>  RTTESTLIB = -lrttest -L$(OBJDIR)
>  EXTRA_LIBS ?= -ldl	# for get_cpu
> +RTTESTNUMA = -lrttestnuma -lnuma
>  DESTDIR	?=
>  prefix  ?= /usr/local
>  bindir  ?= $(prefix)/bin
> @@ -84,11 +85,6 @@ ostype := $(lastword $(subst -, ,$(dumpmachine)))
>  machinetype := $(shell echo $(dumpmachine)| \
>      sed -e 's/-.*//' -e 's/i.86/i386/' -e 's/mips.*/mips/' -e 's/ppc.*/powerpc/')
>  
> -# You have to have libnuma installed, which is fine to do even if you are
> -# running on non-numa machines
> -CFLAGS += -DNUMA
> -NUMA_LIBS = -lnuma
> -
>  include src/arch/android/Makefile
>  
>  VPATH	= src/cyclictest:
> @@ -122,8 +118,8 @@ all: $(TARGETS) hwlatdetect get_cyclictest_snapshot | $(OBJDIR)
>  # Include dependency files, automatically generate them if needed.
>  -include $(addprefix $(OBJDIR)/,$(sources:.c=.d))
>  
> -cyclictest: $(OBJDIR)/cyclictest.o $(OBJDIR)/librttest.a
> -	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB) $(NUMA_LIBS)
> +cyclictest: $(OBJDIR)/cyclictest.o $(OBJDIR)/librttest.a $(OBJDIR)/librttestnuma.a
> +	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB) $(RTTESTNUMA)
>  
>  cyclicdeadline: $(OBJDIR)/cyclicdeadline.o $(OBJDIR)/librttest.a
>  	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB)
> @@ -172,8 +168,8 @@ queuelat: $(OBJDIR)/queuelat.o $(OBJDIR)/librttest.a
>  ssdd: $(OBJDIR)/ssdd.o $(OBJDIR)/librttest.a
>  	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB)
>  
> -oslat: $(OBJDIR)/oslat.o $(OBJDIR)/librttest.a
> -	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB) $(NUMA_LIBS)
> +oslat: $(OBJDIR)/oslat.o $(OBJDIR)/librttest.a $(OBJDIR)/librttestnuma.a
> +	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB) $(RTTESTNUMA)
>  
>  %.8.gz: %.8
>  	gzip -nc $< > $@
> @@ -185,6 +181,10 @@ LIBOBJS =$(addprefix $(OBJDIR)/,error.o rt-get_cpu.o rt-sched.o rt-utils.o)
>  $(OBJDIR)/librttest.a: $(LIBOBJS)
>  	$(AR) rcs $@ $^
>  
> +LIBNUMAOBJS =$(addprefix $(OBJDIR)/,rt-numa.o)
> +$(OBJDIR)/librttestnuma.a: $(LIBNUMAOBJS)
> +	$(AR) rcs $@ $^
> +
>  CLEANUP  = $(TARGETS) *.o .depend *.*~ *.orig *.rej *.d *.a *.8.gz *.8.bz2
>  CLEANUP += $(if $(wildcard .git), ChangeLog)
>  
> diff --git a/src/include/rt-numa.h b/src/include/rt-numa.h
> new file mode 100644
> index 000000000000..047c8b6257cc
> --- /dev/null
> +++ b/src/include/rt-numa.h
> @@ -0,0 +1,9 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +#ifndef __RT_NUMA_H
> +#define __RT_NUMA_H
> +
> +#include <numa.h>
> +
> +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
> new file mode 100644
> index 000000000000..a52a56e8aadd
> --- /dev/null
> +++ b/src/lib/rt-numa.c
> @@ -0,0 +1,56 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright 2020 Daniel Wagner <dwagner@suse.de>
> + */
> +
> +#include <sys/types.h>
> +#include <unistd.h>
> +#include <errno.h>
> +
> +#include "rt-numa.h"
> +
> +/*
> + * After this function is called, affinity_mask is the intersection of
> + * the user supplied affinity mask and the affinity mask from the run
> + * time environment
> + */
> +static void use_current_cpuset(int max_cpus, struct bitmask *cpumask)
> +{
> +	struct bitmask *curmask;
> +	int i;
> +
> +	curmask = numa_allocate_cpumask();
> +	numa_sched_getaffinity(getpid(), curmask);
> +
> +	/*
> +	 * Clear bits that are not set in both the cpuset from the
> +	 * environment, and in the user specified affinity.
> +	 */
> +	for (i = 0; i < max_cpus; i++) {
> +		if ((!numa_bitmask_isbitset(cpumask, i)) ||
> +		    (!numa_bitmask_isbitset(curmask, i)))
> +			numa_bitmask_clearbit(cpumask, i);
> +	}
> +
> +	numa_bitmask_free(curmask);
> +}
> +
> +int parse_cpumask(char *str, int max_cpus, struct bitmask **cpumask)
> +{
> +	struct bitmask *mask;
> +
> +	mask = numa_parse_cpustring_all(str);
> +	if (!mask)
> +		return -ENOMEM;
> +
> +	if (numa_bitmask_weight(mask) == 0) {
> +		numa_bitmask_free(mask);
> +		*cpumask = NULL;
> +		return 0;
> +	}
> +
> +	use_current_cpuset(max_cpus, mask);
> +	*cpumask = mask;
> +
> +	return 0;
> +}
> -- 
> 2.29.2
> 
> 
    Adding my name to the copyright in the new file src/lib/rt-numa.c
    as some of the functions moved here are ones that I've written or
    modified / maintained etc.
    Signed-off-by: John Kacur <jkacur@redhat.com>

Also, wondering if we should combine the two rt-numa.h files into one?

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

* Re: [rt-tests v1 5/6] cyclictest: Use parse_cpumask() from rt-numa.h
  2020-11-13 21:09 ` [rt-tests v1 5/6] cyclictest: Use parse_cpumask() from rt-numa.h Daniel Wagner
@ 2020-11-18 21:10   ` John Kacur
  2020-11-18 21:17   ` John Kacur
  1 sibling, 0 replies; 17+ messages in thread
From: John Kacur @ 2020-11-18 21:10 UTC (permalink / raw)
  To: Daniel Wagner; +Cc: Clark Williams, linux-rt-users



On Fri, 13 Nov 2020, Daniel Wagner wrote:

> Use the helper funtion from rt-numa.h to parse the cpumask from the
> command line.
> 
> Signed-off-by: Daniel Wagner <dwagner@suse.de>
> ---
>  src/cyclictest/cyclictest.c | 70 ++++++++-----------------------------
>  1 file changed, 14 insertions(+), 56 deletions(-)
> 
> diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c
> index 46d88ed155c5..f10f064f7a8e 100644
> --- a/src/cyclictest/cyclictest.c
> +++ b/src/cyclictest/cyclictest.c
> @@ -36,6 +36,7 @@
>  #include "rt_numa.h"
>  
>  #include "rt-utils.h"
> +#include "rt-numa.h"
>  
>  #include <bionic.h>
>  
> @@ -905,11 +906,6 @@ static int clocksources[] = {
>  	CLOCK_REALTIME,
>  };
>  
> -static unsigned int is_cpumask_zero(const struct bitmask *mask)
> -{
> -	return (rt_numa_bitmask_count(mask) == 0);
> -}
> -
>  /* 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
> @@ -976,53 +972,6 @@ static int cpu_for_thread_ua(int thread_num, int max_cpus)
>  	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 time environment
> - */
> -static void use_current_cpuset(const int max_cpus)
> -{
> -	int i;
> -	pid_t pid;
> -	struct bitmask *curmask;
> -
> -	pid = getpid();
> -
> -	curmask = numa_allocate_cpumask();
> -	numa_sched_getaffinity(pid, curmask);
> -
> -	/* Clear bits that are not set in both the cpuset from the environment,
> -	 * and in the user specified affinity for cyclictest
> -	 */
> -	for (i=0; i < max_cpus; i++) {
> -		if ((!rt_numa_bitmask_isbitset(affinity_mask, i)) || (!rt_numa_bitmask_isbitset(curmask, i)))
> -			numa_bitmask_clearbit(affinity_mask, i);
> -	}
> -
> -	numa_bitmask_free(curmask);
> -}
> -
> -static void parse_cpumask(const char *option, const int max_cpus)
> -{
> -	affinity_mask = rt_numa_parse_cpustring(option, max_cpus);
> -	if (affinity_mask) {
> -		if (is_cpumask_zero(affinity_mask)) {
> -			rt_bitmask_free(affinity_mask);
> -			affinity_mask = NULL;
> -		} else {
> -			use_current_cpuset(max_cpus);
> -		}
> -
> -	}
> -	if (!affinity_mask)
> -		display_help(1);
> -
> -	if (verbose) {
> -		printf("%s: Using %u cpus.\n", __func__,
> -			rt_numa_bitmask_count(affinity_mask));
> -	}
> -}
> -
>  static void handlepolicy(char *polname)
>  {
>  	if (strncasecmp(polname, "other", 5) == 0)
> @@ -1156,15 +1105,24 @@ static void process_options(int argc, char *argv[], int max_cpus)
>  			if (smp)
>  				break;
>  			numa_initialize();
> -			if (optarg != NULL) {
> -				parse_cpumask(optarg, max_cpus);
> +			if (optarg) {
> +				parse_cpumask(optarg, max_cpus, &affinity_mask);
>  				setaffinity = AFFINITY_SPECIFIED;
> -			} else if (optind < argc && (atoi(argv[optind]) || argv[optind][0] == '0' || argv[optind][0] == '!')) {
> -				parse_cpumask(argv[optind], max_cpus);
> +			} else if (optind < argc &&
> +				   (atoi(argv[optind]) ||
> +				    argv[optind][0] == '0' ||
> +				    argv[optind][0] == '!')) {
> +				parse_cpumask(argv[optind], max_cpus, &affinity_mask);
>  				setaffinity = AFFINITY_SPECIFIED;
>  			} else {
>  				setaffinity = AFFINITY_USEALL;
>  			}
> +
> +			if (setaffinity == AFFINITY_SPECIFIED && !affinity_mask)
> +				display_help(1);
> +			if (verbose)
> +				printf("Using %u cpus.\n",
> +					numa_bitmask_weight(affinity_mask));
>  			break;
>  		case 'A':
>  		case OPT_ALIGNED:
> -- 
> 2.29.2
> 
> 
Signed-off-by: John Kacur <jkacur@redhat.com>

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

* Re: [rt-tests v1 5/6] cyclictest: Use parse_cpumask() from rt-numa.h
  2020-11-13 21:09 ` [rt-tests v1 5/6] cyclictest: Use parse_cpumask() from rt-numa.h Daniel Wagner
  2020-11-18 21:10   ` John Kacur
@ 2020-11-18 21:17   ` John Kacur
  1 sibling, 0 replies; 17+ messages in thread
From: John Kacur @ 2020-11-18 21:17 UTC (permalink / raw)
  To: Daniel Wagner; +Cc: Clark Williams, linux-rt-users



On Fri, 13 Nov 2020, Daniel Wagner wrote:

> Use the helper funtion from rt-numa.h to parse the cpumask from the
> command line.
> 
> Signed-off-by: Daniel Wagner <dwagner@suse.de>
> ---
>  src/cyclictest/cyclictest.c | 70 ++++++++-----------------------------
>  1 file changed, 14 insertions(+), 56 deletions(-)
> 
> diff --git a/src/cyclictest/cyclictest.c b/src/cyclictest/cyclictest.c
> index 46d88ed155c5..f10f064f7a8e 100644
> --- a/src/cyclictest/cyclictest.c
> +++ b/src/cyclictest/cyclictest.c
> @@ -36,6 +36,7 @@
>  #include "rt_numa.h"
>  
>  #include "rt-utils.h"
> +#include "rt-numa.h"
>  
>  #include <bionic.h>
>  
> @@ -905,11 +906,6 @@ static int clocksources[] = {
>  	CLOCK_REALTIME,
>  };
>  
> -static unsigned int is_cpumask_zero(const struct bitmask *mask)
> -{
> -	return (rt_numa_bitmask_count(mask) == 0);
> -}
> -
>  /* 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
> @@ -976,53 +972,6 @@ static int cpu_for_thread_ua(int thread_num, int max_cpus)
>  	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 time environment
> - */
> -static void use_current_cpuset(const int max_cpus)
> -{
> -	int i;
> -	pid_t pid;
> -	struct bitmask *curmask;
> -
> -	pid = getpid();
> -
> -	curmask = numa_allocate_cpumask();
> -	numa_sched_getaffinity(pid, curmask);
> -
> -	/* Clear bits that are not set in both the cpuset from the environment,
> -	 * and in the user specified affinity for cyclictest
> -	 */
> -	for (i=0; i < max_cpus; i++) {
> -		if ((!rt_numa_bitmask_isbitset(affinity_mask, i)) || (!rt_numa_bitmask_isbitset(curmask, i)))
> -			numa_bitmask_clearbit(affinity_mask, i);
> -	}
> -
> -	numa_bitmask_free(curmask);
> -}
> -
> -static void parse_cpumask(const char *option, const int max_cpus)
> -{
> -	affinity_mask = rt_numa_parse_cpustring(option, max_cpus);
> -	if (affinity_mask) {
> -		if (is_cpumask_zero(affinity_mask)) {
> -			rt_bitmask_free(affinity_mask);
> -			affinity_mask = NULL;
> -		} else {
> -			use_current_cpuset(max_cpus);
> -		}
> -
> -	}
> -	if (!affinity_mask)
> -		display_help(1);
> -
> -	if (verbose) {
> -		printf("%s: Using %u cpus.\n", __func__,
> -			rt_numa_bitmask_count(affinity_mask));
> -	}
> -}
> -
>  static void handlepolicy(char *polname)
>  {
>  	if (strncasecmp(polname, "other", 5) == 0)
> @@ -1156,15 +1105,24 @@ static void process_options(int argc, char *argv[], int max_cpus)
>  			if (smp)
>  				break;
>  			numa_initialize();
> -			if (optarg != NULL) {
> -				parse_cpumask(optarg, max_cpus);
> +			if (optarg) {
> +				parse_cpumask(optarg, max_cpus, &affinity_mask);
>  				setaffinity = AFFINITY_SPECIFIED;
> -			} else if (optind < argc && (atoi(argv[optind]) || argv[optind][0] == '0' || argv[optind][0] == '!')) {
> -				parse_cpumask(argv[optind], max_cpus);
> +			} else if (optind < argc &&
> +				   (atoi(argv[optind]) ||
> +				    argv[optind][0] == '0' ||
> +				    argv[optind][0] == '!')) {
> +				parse_cpumask(argv[optind], max_cpus, &affinity_mask);
>  				setaffinity = AFFINITY_SPECIFIED;
>  			} else {
>  				setaffinity = AFFINITY_USEALL;
>  			}
> +
> +			if (setaffinity == AFFINITY_SPECIFIED && !affinity_mask)
> +				display_help(1);
> +			if (verbose)
> +				printf("Using %u cpus.\n",
> +					numa_bitmask_weight(affinity_mask));
>  			break;
>  		case 'A':
>  		case OPT_ALIGNED:
> -- 
> 2.29.2
> 
> 
    Fixed a minor spelling mistake in the message.
    Signed-off-by: John Kacur <jkacur@redhat.com>


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

* Re: [rt-tests v1 6/6] oslat: Use parse_cpumask() from rt-numa.h
  2020-11-13 21:09 ` [rt-tests v1 6/6] oslat: " Daniel Wagner
@ 2020-11-18 21:18   ` John Kacur
  2021-02-10 16:07   ` Peter Xu
  1 sibling, 0 replies; 17+ messages in thread
From: John Kacur @ 2020-11-18 21:18 UTC (permalink / raw)
  To: Daniel Wagner; +Cc: Clark Williams, linux-rt-users



On Fri, 13 Nov 2020, Daniel Wagner wrote:

> Use the common parse_cpumask() helper and use struct bitmask directly
> instead transforming it into a CPU_SET first.
> 
> Signed-off-by: Daniel Wagner <dwagner@suse.de>
> ---
>  src/oslat/oslat.c | 55 +++++++++++++++--------------------------------
>  1 file changed, 17 insertions(+), 38 deletions(-)
> 
> diff --git a/src/oslat/oslat.c b/src/oslat/oslat.c
> index b2aa15001be2..5b7e0d5b5d5c 100644
> --- a/src/oslat/oslat.c
> +++ b/src/oslat/oslat.c
> @@ -42,6 +42,7 @@
>  #include <sys/syscall.h>
>  
>  #include "rt-utils.h"
> +#include "rt-numa.h"
>  #include "error.h"
>  
>  #ifdef __GNUC__
> @@ -542,37 +543,6 @@ static void usage(int error)
>  	exit(error);
>  }
>  
> -/* TODO: use libnuma? */
> -static int parse_cpu_list(char *cpu_list, cpu_set_t *cpu_set)
> -{
> -	struct bitmask *cpu_mask;
> -	int i, n_cores;
> -
> -	n_cores = sysconf(_SC_NPROCESSORS_CONF);
> -
> -	if (!cpu_list) {
> -		for (i = 0; i < n_cores; i++)
> -			CPU_SET(i, cpu_set);
> -		return n_cores;
> -	}
> -
> -	cpu_mask = numa_parse_cpustring_all(cpu_list);
> -	if (cpu_mask) {
> -		for (i = 0; i < n_cores; i++) {
> -			if (numa_bitmask_isbitset(cpu_mask, i))
> -				CPU_SET(i, cpu_set);
> -		}
> -		numa_bitmask_free(cpu_mask);
> -	} else {
> -		warn("Unknown cpu-list: %s, using all available cpus\n", cpu_list);
> -		for (i = 0; i < n_cores; i++)
> -			CPU_SET(i, cpu_set);
> -	}
> -
> -	return n_cores;
> -}
> -
> -
>  static int workload_select(char *name)
>  {
>  	int i = 0;
> @@ -745,15 +715,18 @@ int main(int argc, char *argv[])
>  {
>  	struct thread *threads;
>  	int i, n_cores;
> -	cpu_set_t cpu_set;
> +	struct bitmask *cpu_set = NULL;
> +	int max_cpus = sysconf(_SC_NPROCESSORS_ONLN);
>  
>  #ifdef FRC_MISSING
>  	printf("This architecture is not yet supported. "
>  	       "Please implement frc() function first for %s.\n", argv[0]);
>  	return 0;
>  #endif
> -
> -	CPU_ZERO(&cpu_set);
> +	if (numa_available() == -1) {
> +		printf("ERROR: Could not initialize libnuma\n");
> +		exit(1);
> +	}
>  
>  	g.app_name = argv[0];
>  	g.rtprio = 0;
> @@ -768,16 +741,22 @@ int main(int argc, char *argv[])
>  
>  	TEST(mlockall(MCL_CURRENT | MCL_FUTURE) == 0);
>  
> -	n_cores = parse_cpu_list(g.cpu_list, &cpu_set);
> +	if (!g.cpu_list)
> +		g.cpu_list = strdup("all");
> +	if (parse_cpumask(g.cpu_list, max_cpus, &cpu_set))
> +		exit(1);
> +	n_cores = numa_bitmask_weight(cpu_set);
>  
> -	TEST(threads = calloc(1, CPU_COUNT(&cpu_set) * sizeof(threads[0])));
> +	TEST(threads = calloc(1, n_cores * sizeof(threads[0])));
>  	for (i = 0; i < n_cores; ++i)
> -		if (CPU_ISSET(i, &cpu_set) && move_to_core(i) == 0)
> +		if (numa_bitmask_isbitset(cpu_set, i) && move_to_core(i) == 0)
>  			threads[g.n_threads_total++].core_i = i;
>  
> -	if (CPU_ISSET(0, &cpu_set) && g.rtprio)
> +	if (numa_bitmask_isbitset(cpu_set, 0) && g.rtprio)
>  		printf("WARNING: Running SCHED_FIFO workload on CPU 0 may hang the thread\n");
>  
> +	numa_bitmask_free(cpu_set);
> +
>  	TEST(move_to_core(g.cpu_main_thread) == 0);
>  
>  	signal(SIGALRM, handle_alarm);
> -- 
> 2.29.2
> 
> 
    minor edit to the message
    Signed-off-by: John Kacur <jkacur@redhat.com>


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

* Re: [rt-tests v1 4/6] rt-numa: Introduce NUMA helpers
  2020-11-18 21:09   ` John Kacur
@ 2020-11-19  8:21     ` Daniel Wagner
  0 siblings, 0 replies; 17+ messages in thread
From: Daniel Wagner @ 2020-11-19  8:21 UTC (permalink / raw)
  To: John Kacur; +Cc: Clark Williams, linux-rt-users

Hi John,

On Wed, Nov 18, 2020 at 04:09:18PM -0500, John Kacur wrote:
>     Adding my name to the copyright in the new file src/lib/rt-numa.c
>     as some of the functions moved here are ones that I've written or
>     modified / maintained etc.

Yes, please. I forgot to move the copyrights when I moved the code
around. Sorry about that. Was not intentionally.

>     Signed-off-by: John Kacur <jkacur@redhat.com>
> 
> Also, wondering if we should combine the two rt-numa.h files into one?

Yes, I think this makes sense.

Thanks,
Daniel

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

* Re: [rt-tests v1 6/6] oslat: Use parse_cpumask() from rt-numa.h
  2020-11-13 21:09 ` [rt-tests v1 6/6] oslat: " Daniel Wagner
  2020-11-18 21:18   ` John Kacur
@ 2021-02-10 16:07   ` Peter Xu
  2021-02-10 16:29     ` Daniel Wagner
  1 sibling, 1 reply; 17+ messages in thread
From: Peter Xu @ 2021-02-10 16:07 UTC (permalink / raw)
  To: Daniel Wagner; +Cc: Clark Williams, John Kacur, linux-rt-users, psahoo

On Fri, Nov 13, 2020 at 10:09:10PM +0100, Daniel Wagner wrote:
> Use the common parse_cpumask() helper and use struct bitmask directly
> instead transforming it into a CPU_SET first.
> 
> Signed-off-by: Daniel Wagner <dwagner@suse.de>

Hi, Daniel,

This seems to have broken oslat with --cpu-list...

xz-x1:rt-tests [master]$ sudo ./oslat -c 1-2
Total runtime:          1 seconds
Thread priority:        default
CPU list:               1-2
CPU for main thread:    0
Workload:               no
Workload mem:           0 (KiB)
Preheat cores:          1

Pre-heat for 1 seconds...
Test starts...
Test completed.

        Core:    1
    CPU Freq:    2114 (Mhz)
    001 (us):    49979990
    002 (us):    471
    003 (us):    53
    004 (us):    9
    005 (us):    16
    006 (us):    14
    007 (us):    4
    008 (us):    4
    009 (us):    1
    010 (us):    1
    011 (us):    0
    012 (us):    0
    013 (us):    2
    014 (us):    59
    015 (us):    11
    016 (us):    173
    017 (us):    12
    018 (us):    25
    019 (us):    112
    020 (us):    10
    021 (us):    66
    022 (us):    7
    023 (us):    13
    024 (us):    16
    025 (us):    7
    026 (us):    18
    027 (us):    13
    028 (us):    7
    029 (us):    3
    030 (us):    3
    031 (us):    0
    032 (us):    5 (including overflows)
     Minimum:    1 (us)
     Average:    1.000 (us)
     Maximum:    82 (us)
     Max-Min:    81 (us)
    Duration:    0.995 (sec)

Reported-by: Pradipta Kumar Sahoo <psahoo@redhat.com>

Thanks,

-- 
Peter Xu


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

* Re: [rt-tests v1 6/6] oslat: Use parse_cpumask() from rt-numa.h
  2021-02-10 16:07   ` Peter Xu
@ 2021-02-10 16:29     ` Daniel Wagner
  0 siblings, 0 replies; 17+ messages in thread
From: Daniel Wagner @ 2021-02-10 16:29 UTC (permalink / raw)
  To: Peter Xu; +Cc: Clark Williams, John Kacur, linux-rt-users, psahoo

Hi Peter,

On Wed, Feb 10, 2021 at 11:07:45AM -0500, Peter Xu wrote:
> This seems to have broken oslat with --cpu-list...
> 
> xz-x1:rt-tests [master]$ sudo ./oslat -c 1-2
> Total runtime:          1 seconds
> Thread priority:        default
> CPU list:               1-2
> CPU for main thread:    0
> Workload:               no
> Workload mem:           0 (KiB)
> Preheat cores:          1

$ ./oslat  -c 1-3
[...]
CPU list:               1-3
[...]
        Core:    1 2

looks like there is a off by one

Will look into it

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

end of thread, other threads:[~2021-02-10 16:31 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-13 21:09 [rt-tests v1 0/6] Move common code to helper libraries Daniel Wagner
2020-11-13 21:09 ` [rt-tests v1 1/6] rt-utils: Introduce parse_mem_string() Daniel Wagner
2020-11-18 20:59   ` John Kacur
2020-11-13 21:09 ` [rt-tests v1 2/6] oslat: Use string parser utilies Daniel Wagner
2020-11-18 21:00   ` John Kacur
2020-11-13 21:09 ` [rt-tests v1 3/6] cyclictest: Remove deadcode checking for NUMA Daniel Wagner
2020-11-18 21:01   ` John Kacur
2020-11-13 21:09 ` [rt-tests v1 4/6] rt-numa: Introduce NUMA helpers Daniel Wagner
2020-11-18 21:09   ` John Kacur
2020-11-19  8:21     ` Daniel Wagner
2020-11-13 21:09 ` [rt-tests v1 5/6] cyclictest: Use parse_cpumask() from rt-numa.h Daniel Wagner
2020-11-18 21:10   ` John Kacur
2020-11-18 21:17   ` John Kacur
2020-11-13 21:09 ` [rt-tests v1 6/6] oslat: " Daniel Wagner
2020-11-18 21:18   ` John Kacur
2021-02-10 16:07   ` Peter Xu
2021-02-10 16:29     ` Daniel Wagner

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.