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@xxxxxxx> --- 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@xxxxxxx> + */ + +#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