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@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 > > 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@xxxxxxxxxx> Also, wondering if we should combine the two rt-numa.h files into one?