All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] cyclictest: avoid using libnuma cpumask parsing functions
@ 2016-04-13 20:37 Clark Williams
  2016-04-14 14:30 ` Luiz Capitulino
  2016-04-19 13:14 ` John Kacur
  0 siblings, 2 replies; 5+ messages in thread
From: Clark Williams @ 2016-04-13 20:37 UTC (permalink / raw)
  To: John Kacur; +Cc: RT, LKML

[-- Attachment #1: Type: text/plain, Size: 4621 bytes --]

John,

I ran into issues with parsing cpu masks when trying to run this command:

sudo ./cyclictest -i100 -qmu -h 2000 -p95 -t1 -a3

I had previously booted a 4-core system with these boot options:

	isolcpus=3 nohz_full=3 rcu_nocbs=3

The intent was to run loads on cpus 0-2 while running cyclictest on the isolated cpu 3. 

Unfortunately, the libnuma function numa_parse_cpumask() (which we use when it's available) seems to check the current affinity mask and fails the parse if any of the cpus in the input string are not in the current affinity mask. I find this "unhelpful" when trying to place a measurement thread on an isolated cpu. 

This patch removes the wrapper function which uses libnuma cpumask parsing functions and instead uses the parser function we wrote for when libnuma is not available. 

Signed-off-by: Clark Williams <williams@redhat.com>
---
 src/cyclictest/rt_numa.h | 82 ++++++++++++++++++++++--------------------------
 1 file changed, 38 insertions(+), 44 deletions(-)

diff --git a/src/cyclictest/rt_numa.h b/src/cyclictest/rt_numa.h
index ec2994314e80..d65cd421863b 100644
--- a/src/cyclictest/rt_numa.h
+++ b/src/cyclictest/rt_numa.h
@@ -32,6 +32,12 @@ static int numa = 0;
 #define LIBNUMA_API_VERSION 1
 #endif
 
+#ifndef BITS_PER_LONG
+#define BITS_PER_LONG    (8*sizeof(long))
+#endif
+
+
+
 static void *
 threadalloc(size_t size, int node)
 {
@@ -89,22 +95,6 @@ static inline unsigned int rt_numa_bitmask_isbitset( const struct bitmask *mask,
 	return numa_bitmask_isbitset(mask,i);
 }
 
-static inline struct bitmask* rt_numa_parse_cpustring(const char* s,
-	int max_cpus)
-{
-#ifdef HAVE_PARSE_CPUSTRING_ALL		/* Currently not defined anywhere.  No
-					   autotools build. */
-	return numa_parse_cpustring_all(s);
-#else
-	/* We really need numa_parse_cpustring_all(), so we can assign threads
-	 * to cores which are part of an isolcpus set, but early 2.x versions of
-	 * libnuma do not have this function.  A work around should be to run
-	 * your command with e.g. taskset -c 9-15 <command>
-	 */
-	return numa_parse_cpustring((char *)s);
-#endif
-}
-
 static inline void rt_bitmask_free(struct bitmask *mask)
 {
 	numa_bitmask_free(mask);
@@ -157,32 +147,6 @@ static inline unsigned int rt_numa_bitmask_isbitset( const struct bitmask *mask,
 	return (bit != 0);
 }
 
-static inline struct bitmask* rt_numa_parse_cpustring(const char* s,
-	int max_cpus)
-{
-	int cpu;
-	struct bitmask *mask = NULL;
-	cpu = atoi(s);
-	if (0 <= cpu && cpu < max_cpus) {
-		mask = malloc(sizeof(*mask));
-		if (mask) {
-			/* Round up to integral number of longs to contain
-			 * max_cpus bits */
-			int nlongs = (max_cpus+BITS_PER_LONG-1)/BITS_PER_LONG;
-
-			mask->maskp = calloc(nlongs, sizeof(long));
-			if (mask->maskp) {
-				mask->maskp[cpu/BITS_PER_LONG] |=
-					(1UL << (cpu % BITS_PER_LONG));
-				mask->size = max_cpus;
-			} else {
-				free(mask);
-				mask = NULL;
-			}
-		}
-	}
-	return mask;
-}
 
 static inline void rt_bitmask_free(struct bitmask *mask)
 {
@@ -204,8 +168,6 @@ struct bitmask {
     unsigned long size; /* number of bits in the map */
     unsigned long *maskp;
 };
-#define BITS_PER_LONG    (8*sizeof(long))
-
 static inline void *threadalloc(size_t size, int n) { return malloc(size); }
 static inline void threadfree(void *ptr, size_t s, int n) { free(ptr); }
 static inline void rt_numa_set_numa_run_on_node(int n, int c) { }
@@ -280,4 +242,36 @@ static inline unsigned int rt_numa_bitmask_count(const struct bitmask *mask)
 	return num_bits;
 }
 
+/*
+ * Use this instead of a wrapper for libnuma functions.
+ * The libnuma function numa_parse_cpustring() checks the affinity mask
+ * and fails if an input cpu is not in the mask. This of course sucks when
+ * trying to place a thread on an isolated cpu. Avoid libnuma parsing functions
+ */
+static inline struct bitmask* rt_numa_parse_cpustring(const char* s,
+	int max_cpus)
+{
+	int cpu;
+	struct bitmask *mask = NULL;
+	cpu = atoi(s);
+	if (0 <= cpu && cpu < max_cpus) {
+		mask = malloc(sizeof(*mask));
+		if (mask) {
+			/* Round up to integral number of longs to contain
+			 * max_cpus bits */
+			int nlongs = (max_cpus+BITS_PER_LONG-1)/BITS_PER_LONG;
+
+			mask->maskp = calloc(nlongs, sizeof(long));
+			if (mask->maskp) {
+				mask->maskp[cpu/BITS_PER_LONG] |=
+					(1UL << (cpu % BITS_PER_LONG));
+				mask->size = max_cpus;
+			} else {
+				free(mask);
+				mask = NULL;
+			}
+		}
+	}
+	return mask;
+}
 #endif	/* _RT_NUMA_H */
-- 
2.5.5


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

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

* Re: [PATCH] cyclictest: avoid using libnuma cpumask parsing functions
  2016-04-13 20:37 [PATCH] cyclictest: avoid using libnuma cpumask parsing functions Clark Williams
@ 2016-04-14 14:30 ` Luiz Capitulino
  2016-04-19 13:17   ` John Kacur
  2016-04-19 13:14 ` John Kacur
  1 sibling, 1 reply; 5+ messages in thread
From: Luiz Capitulino @ 2016-04-14 14:30 UTC (permalink / raw)
  To: Clark Williams; +Cc: John Kacur, RT, LKML

On Wed, 13 Apr 2016 15:37:00 -0500
Clark Williams <williams@redhat.com> wrote:

> John,
> 
> I ran into issues with parsing cpu masks when trying to run this command:
> 
> sudo ./cyclictest -i100 -qmu -h 2000 -p95 -t1 -a3
> 
> I had previously booted a 4-core system with these boot options:
> 
> 	isolcpus=3 nohz_full=3 rcu_nocbs=3
> 
> The intent was to run loads on cpus 0-2 while running cyclictest on the isolated cpu 3. 
> 
> Unfortunately, the libnuma function numa_parse_cpumask() (which we use when it's available) seems to check the current affinity mask and fails the parse if any of the cpus in the input string are not in the current affinity mask. I find this "unhelpful" when trying to place a measurement thread on an isolated cpu. 
> 
> This patch removes the wrapper function which uses libnuma cpumask parsing functions and instead uses the parser function we wrote for when libnuma is not available. 

There's an alternative solution that I was working on some time ago,
which is having a simple configure script. This is usually done
by simple projects that don't need a full blown autoconf machinery.

The patch below adds such a script. It detects librt, libpthread and
libnuma. It solves the problem you mention and it removes hardcoded
lib details from the Makefile.

If there's interest for this solution I can finish it and post for
inclusion.

>From 4228140e9dbb7fbb1bb495663ae3d896fc447f8f Mon Sep 17 00:00:00 2001
From: Luiz Capitulino <lcapitulino@redhat.com>
Date: Tue, 23 Feb 2016 15:53:43 -0500
Subject: [PATCH] add configure script

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 .gitignore |   1 +
 Makefile   |  22 ++----------
 configure  | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 120 insertions(+), 19 deletions(-)
 create mode 100755 configure

diff --git a/.gitignore b/.gitignore
index ceee8bf..5b3e4cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,3 +34,4 @@ SRPMS
 rt-tests.spec
 tags
 TAGS
+config.mk
diff --git a/Makefile b/Makefile
index 280fd3b..dad0175 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,5 @@
+include config.mk
+
 VERSION = 0.97
 CC?=$(CROSS_COMPILE)gcc
 AR?=$(CROSS_COMPILE)ar
@@ -17,7 +19,6 @@ sources = cyclictest.c \
 	  svsematest.c
 
 TARGETS = $(sources:.c=)
-LIBS	= -lrt -lpthread
 RTTESTLIB = -lrttest -L$(OBJDIR)
 EXTRA_LIBS ?= -ldl	# for get_cpu
 DESTDIR	?=
@@ -48,26 +49,9 @@ ostype := $(lastword $(subst -, ,$(dumpmachine)))
 machinetype := $(shell echo $(dumpmachine)| \
     sed -e 's/-.*//' -e 's/i.86/i386/' -e 's/mips.*/mips/' -e 's/ppc.*/powerpc/')
 
-# The default is to assume you have libnuma installed, which is fine to do
-# even on non-numa machines. If you don't want to install the numa libs, for
-# example, they might not be available in an embedded environment, then
-# compile with
-# make NUMA=0
-ifneq ($(filter x86_64 i386 ia64 mips powerpc,$(machinetype)),)
-NUMA 	:= 1
-endif
-
-# The default is to assume that you only have numa_parse_cpustring
-# If you are sure you have a version of libnuma with numa_parse_cpustring_all
-# then compile with
-# make HAVE_PARSE_CPUSTRING_ALL=1
-ifeq ($(NUMA),1)
-	CFLAGS += -DNUMA
-	NUMA_LIBS = -lnuma
 ifdef HAVE_PARSE_CPUSTRING_ALL
 	CFLAGS += -DHAVE_PARSE_CPUSTRING_ALL
 endif
-endif
 
 include src/arch/android/Makefile
 
@@ -100,7 +84,7 @@ $(OBJDIR):
 -include $(addprefix $(OBJDIR)/,$(sources:.c=.d))
 
 cyclictest: $(OBJDIR)/cyclictest.o $(OBJDIR)/librttest.a
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB) $(NUMA_LIBS)
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB)
 
 signaltest: $(OBJDIR)/signaltest.o $(OBJDIR)/librttest.a
 	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB)
diff --git a/configure b/configure
new file mode 100755
index 0000000..1d17ef9
--- /dev/null
+++ b/configure
@@ -0,0 +1,116 @@
+#!/bin/sh
+
+build_config=config.mk
+temp_dir=$(mktemp -d)
+temp_file=$temp_dir/file.c
+
+LIBS=
+NUMA_LIBS=
+EXTRA_CFLAGS=
+has_numa=n
+has_numa_cpustring_all=n
+
+build_test()
+{
+	local libs=$*
+	local ret=
+
+	cd $temp_dir
+	cc -o prog $temp_file $libs 2> /dev/null
+	ret=$?
+	cd - > /dev/null
+	return $ret
+}
+
+#
+# -lpthread
+#
+pthread_lib=-lpthread
+
+cat > $temp_file << EOF
+#include <pthread.h>
+static void *func(void *p) { return NULL; }
+int main(void) {
+	pthread_t thread;
+	pthread_create(&thread, 0, func, 0);
+	return 0;
+}
+EOF
+
+if ! build_test $pthread_lib; then
+	echo ERROR: missing pthread library
+	exit 1
+else
+	LIBS="$LIBS $pthread_lib"
+fi
+
+#
+# -lrt
+#
+rt_lib=-lrt
+
+cat > $temp_file << EOF
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+int main(void) {
+	shm_open("", 0, 0);
+	return 0;
+}
+EOF
+
+if ! build_test $rt_lib; then
+	echo ERROR: missing rt library
+	exit 1
+else
+	LIBS="$LIBS $rt_lib"
+fi
+
+#
+# -lnuma
+#
+numa_lib=-lnuma
+
+cat > $temp_file << EOF
+#include <numa.h>
+int main(void) {
+	numa_available();
+	return 0;
+}
+EOF
+
+if build_test $numa_lib; then
+	LIBS="$LIBS $numa_lib"
+	EXTRA_CFLAGS="$EXTRA_CFLAGS -DNUMA"
+	has_numa=y
+fi
+
+#
+# numa_parse_cpustring_all
+#
+if [ $has_numa = "y" ]; then
+
+	cat > $temp_file << EOF
+#include <numa.h>
+int main(void) {
+	numa_parse_cpustring_all("");
+	return 0;
+}
+EOF
+
+	if build_test $numa_lib; then
+		has_numa_cpustring_all=y;
+	fi
+fi
+
+#
+# Write $build_config
+#
+echo "LIBS = $LIBS" > $build_config
+echo "EXTRA_CFLAGS = $EXTRA_CFLAGS" >> $build_config
+
+if [ "$has_numa_cpustring_all" = "y" ]; then
+	echo "HAVE_PARSE_CPUSTRING_ALL := 1" >> $build_config
+fi
+
+rm -rf $temp_dir
-- 
2.5.5

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

* Re: [PATCH] cyclictest: avoid using libnuma cpumask parsing functions
  2016-04-13 20:37 [PATCH] cyclictest: avoid using libnuma cpumask parsing functions Clark Williams
  2016-04-14 14:30 ` Luiz Capitulino
@ 2016-04-19 13:14 ` John Kacur
  1 sibling, 0 replies; 5+ messages in thread
From: John Kacur @ 2016-04-19 13:14 UTC (permalink / raw)
  To: Clark Williams; +Cc: RT, LKML



On Wed, 13 Apr 2016, Clark Williams wrote:

> John,
> 
> I ran into issues with parsing cpu masks when trying to run this command:
> 
> sudo ./cyclictest -i100 -qmu -h 2000 -p95 -t1 -a3
> 
> I had previously booted a 4-core system with these boot options:
> 
> 	isolcpus=3 nohz_full=3 rcu_nocbs=3
> 
> The intent was to run loads on cpus 0-2 while running cyclictest on the isolated cpu 3. 
> 
> Unfortunately, the libnuma function numa_parse_cpumask() (which we use when it's available) seems to check the current affinity mask and fails the parse if any of the cpus in the input string are not in the current affinity mask. I find this "unhelpful" when trying to place a measurement thread on an isolated cpu. 
> 
> This patch removes the wrapper function which uses libnuma cpumask parsing functions and instead uses the parser function we wrote for when libnuma is not available. 
> 
> Signed-off-by: Clark Williams <williams@redhat.com>

For the record, I tested isolating cpus using two methods.
1. Using tuna after booting.
2. Using the isolcpus kernel parameter

The default way of compiling rt-tests (and cyclictest) uses 
numa_parse_cpustring() which fails if the cpu is not in the current cpuset 
as you described above.

Distributions that have libnuma versions with
numa_parse_cpustring_all() that can parse all possible cpus, can compile 
like this

make HAVE_PARSE_CPUSTRING_ALL=1

When I did this, cyclictest is able to run your test scenario without 
returning an error.

The default compile is the ultra safe method, but it could be that we are 
maintaining backwards compatibility for an old libnuma version that nobody 
really cares about anymore.

I'm a bit reluctant to replace the libnuma version with our own version 
right before we'd like to freeze a stable version, when you can simply 
compile this correctly for your system to get the desired results. Perhaps 
we can do this for the devel version? On the otherhand, if we don't care 
about maintaining backwards compatability with a library that no-one cares 
about anymore, we can just drop the the old version and use 
numa_parse_cpustring_all(). Maybe that's what we can do going forward.

For this version, we could also swap the default to assume that 
numa_parse_cpustring_all() is available, and make people compile with 
NO_PARSE_CPUSTRING_ALL or something like that if they care about backwards 
compatibility.

Thanks

John


> ---
>  src/cyclictest/rt_numa.h | 82 ++++++++++++++++++++++--------------------------
>  1 file changed, 38 insertions(+), 44 deletions(-)
> 
> diff --git a/src/cyclictest/rt_numa.h b/src/cyclictest/rt_numa.h
> index ec2994314e80..d65cd421863b 100644
> --- a/src/cyclictest/rt_numa.h
> +++ b/src/cyclictest/rt_numa.h
> @@ -32,6 +32,12 @@ static int numa = 0;
>  #define LIBNUMA_API_VERSION 1
>  #endif
>  
> +#ifndef BITS_PER_LONG
> +#define BITS_PER_LONG    (8*sizeof(long))
> +#endif
> +
> +
> +
>  static void *
>  threadalloc(size_t size, int node)
>  {
> @@ -89,22 +95,6 @@ static inline unsigned int rt_numa_bitmask_isbitset( const struct bitmask *mask,
>  	return numa_bitmask_isbitset(mask,i);
>  }
>  
> -static inline struct bitmask* rt_numa_parse_cpustring(const char* s,
> -	int max_cpus)
> -{
> -#ifdef HAVE_PARSE_CPUSTRING_ALL		/* Currently not defined anywhere.  No
> -					   autotools build. */
> -	return numa_parse_cpustring_all(s);
> -#else
> -	/* We really need numa_parse_cpustring_all(), so we can assign threads
> -	 * to cores which are part of an isolcpus set, but early 2.x versions of
> -	 * libnuma do not have this function.  A work around should be to run
> -	 * your command with e.g. taskset -c 9-15 <command>
> -	 */
> -	return numa_parse_cpustring((char *)s);
> -#endif
> -}
> -
>  static inline void rt_bitmask_free(struct bitmask *mask)
>  {
>  	numa_bitmask_free(mask);
> @@ -157,32 +147,6 @@ static inline unsigned int rt_numa_bitmask_isbitset( const struct bitmask *mask,
>  	return (bit != 0);
>  }
>  
> -static inline struct bitmask* rt_numa_parse_cpustring(const char* s,
> -	int max_cpus)
> -{
> -	int cpu;
> -	struct bitmask *mask = NULL;
> -	cpu = atoi(s);
> -	if (0 <= cpu && cpu < max_cpus) {
> -		mask = malloc(sizeof(*mask));
> -		if (mask) {
> -			/* Round up to integral number of longs to contain
> -			 * max_cpus bits */
> -			int nlongs = (max_cpus+BITS_PER_LONG-1)/BITS_PER_LONG;
> -
> -			mask->maskp = calloc(nlongs, sizeof(long));
> -			if (mask->maskp) {
> -				mask->maskp[cpu/BITS_PER_LONG] |=
> -					(1UL << (cpu % BITS_PER_LONG));
> -				mask->size = max_cpus;
> -			} else {
> -				free(mask);
> -				mask = NULL;
> -			}
> -		}
> -	}
> -	return mask;
> -}
>  
>  static inline void rt_bitmask_free(struct bitmask *mask)
>  {
> @@ -204,8 +168,6 @@ struct bitmask {
>      unsigned long size; /* number of bits in the map */
>      unsigned long *maskp;
>  };
> -#define BITS_PER_LONG    (8*sizeof(long))
> -
>  static inline void *threadalloc(size_t size, int n) { return malloc(size); }
>  static inline void threadfree(void *ptr, size_t s, int n) { free(ptr); }
>  static inline void rt_numa_set_numa_run_on_node(int n, int c) { }
> @@ -280,4 +242,36 @@ static inline unsigned int rt_numa_bitmask_count(const struct bitmask *mask)
>  	return num_bits;
>  }
>  
> +/*
> + * Use this instead of a wrapper for libnuma functions.
> + * The libnuma function numa_parse_cpustring() checks the affinity mask
> + * and fails if an input cpu is not in the mask. This of course sucks when
> + * trying to place a thread on an isolated cpu. Avoid libnuma parsing functions
> + */
> +static inline struct bitmask* rt_numa_parse_cpustring(const char* s,
> +	int max_cpus)
> +{
> +	int cpu;
> +	struct bitmask *mask = NULL;
> +	cpu = atoi(s);
> +	if (0 <= cpu && cpu < max_cpus) {
> +		mask = malloc(sizeof(*mask));
> +		if (mask) {
> +			/* Round up to integral number of longs to contain
> +			 * max_cpus bits */
> +			int nlongs = (max_cpus+BITS_PER_LONG-1)/BITS_PER_LONG;
> +
> +			mask->maskp = calloc(nlongs, sizeof(long));
> +			if (mask->maskp) {
> +				mask->maskp[cpu/BITS_PER_LONG] |=
> +					(1UL << (cpu % BITS_PER_LONG));
> +				mask->size = max_cpus;
> +			} else {
> +				free(mask);
> +				mask = NULL;
> +			}
> +		}
> +	}
> +	return mask;
> +}
>  #endif	/* _RT_NUMA_H */
> -- 
> 2.5.5
> 
> 

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

* Re: [PATCH] cyclictest: avoid using libnuma cpumask parsing functions
  2016-04-14 14:30 ` Luiz Capitulino
@ 2016-04-19 13:17   ` John Kacur
  2016-04-19 13:30     ` Luiz Capitulino
  0 siblings, 1 reply; 5+ messages in thread
From: John Kacur @ 2016-04-19 13:17 UTC (permalink / raw)
  To: Luiz Capitulino; +Cc: Clark Williams, RT, LKML



On Thu, 14 Apr 2016, Luiz Capitulino wrote:

> On Wed, 13 Apr 2016 15:37:00 -0500
> Clark Williams <williams@redhat.com> wrote:
> 
> > John,
> > 
> > I ran into issues with parsing cpu masks when trying to run this command:
> > 
> > sudo ./cyclictest -i100 -qmu -h 2000 -p95 -t1 -a3
> > 
> > I had previously booted a 4-core system with these boot options:
> > 
> > 	isolcpus=3 nohz_full=3 rcu_nocbs=3
> > 
> > The intent was to run loads on cpus 0-2 while running cyclictest on the isolated cpu 3. 
> > 
> > Unfortunately, the libnuma function numa_parse_cpumask() (which we use when it's available) seems to check the current affinity mask and fails the parse if any of the cpus in the input string are not in the current affinity mask. I find this "unhelpful" when trying to place a measurement thread on an isolated cpu. 
> > 
> > This patch removes the wrapper function which uses libnuma cpumask parsing functions and instead uses the parser function we wrote for when libnuma is not available. 
> 
> There's an alternative solution that I was working on some time ago,
> which is having a simple configure script. This is usually done
> by simple projects that don't need a full blown autoconf machinery.
> 
> The patch below adds such a script. It detects librt, libpthread and
> libnuma. It solves the problem you mention and it removes hardcoded
> lib details from the Makefile.
> 
> If there's interest for this solution I can finish it and post for
> inclusion.

I find this interesting, maybe for the coming new devel system, I wouldn't 
want to stick it in now right before a stable release though. Also, I 
like this much better than full blown auto-tools, but I don't want to lose control over 
the compiling process either. In otherwords, there should be some way to 
override what the script detects.

Thanks

John

> 
> From 4228140e9dbb7fbb1bb495663ae3d896fc447f8f Mon Sep 17 00:00:00 2001
> From: Luiz Capitulino <lcapitulino@redhat.com>
> Date: Tue, 23 Feb 2016 15:53:43 -0500
> Subject: [PATCH] add configure script
> 
> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
> ---
>  .gitignore |   1 +
>  Makefile   |  22 ++----------
>  configure  | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 120 insertions(+), 19 deletions(-)
>  create mode 100755 configure
> 
> diff --git a/.gitignore b/.gitignore
> index ceee8bf..5b3e4cc 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -34,3 +34,4 @@ SRPMS
>  rt-tests.spec
>  tags
>  TAGS
> +config.mk
> diff --git a/Makefile b/Makefile
> index 280fd3b..dad0175 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1,3 +1,5 @@
> +include config.mk
> +
>  VERSION = 0.97
>  CC?=$(CROSS_COMPILE)gcc
>  AR?=$(CROSS_COMPILE)ar
> @@ -17,7 +19,6 @@ sources = cyclictest.c \
>  	  svsematest.c
>  
>  TARGETS = $(sources:.c=)
> -LIBS	= -lrt -lpthread
>  RTTESTLIB = -lrttest -L$(OBJDIR)
>  EXTRA_LIBS ?= -ldl	# for get_cpu
>  DESTDIR	?=
> @@ -48,26 +49,9 @@ ostype := $(lastword $(subst -, ,$(dumpmachine)))
>  machinetype := $(shell echo $(dumpmachine)| \
>      sed -e 's/-.*//' -e 's/i.86/i386/' -e 's/mips.*/mips/' -e 's/ppc.*/powerpc/')
>  
> -# The default is to assume you have libnuma installed, which is fine to do
> -# even on non-numa machines. If you don't want to install the numa libs, for
> -# example, they might not be available in an embedded environment, then
> -# compile with
> -# make NUMA=0
> -ifneq ($(filter x86_64 i386 ia64 mips powerpc,$(machinetype)),)
> -NUMA 	:= 1
> -endif
> -
> -# The default is to assume that you only have numa_parse_cpustring
> -# If you are sure you have a version of libnuma with numa_parse_cpustring_all
> -# then compile with
> -# make HAVE_PARSE_CPUSTRING_ALL=1
> -ifeq ($(NUMA),1)
> -	CFLAGS += -DNUMA
> -	NUMA_LIBS = -lnuma
>  ifdef HAVE_PARSE_CPUSTRING_ALL
>  	CFLAGS += -DHAVE_PARSE_CPUSTRING_ALL
>  endif
> -endif
>  
>  include src/arch/android/Makefile
>  
> @@ -100,7 +84,7 @@ $(OBJDIR):
>  -include $(addprefix $(OBJDIR)/,$(sources:.c=.d))
>  
>  cyclictest: $(OBJDIR)/cyclictest.o $(OBJDIR)/librttest.a
> -	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB) $(NUMA_LIBS)
> +	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB)
>  
>  signaltest: $(OBJDIR)/signaltest.o $(OBJDIR)/librttest.a
>  	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(RTTESTLIB)
> diff --git a/configure b/configure
> new file mode 100755
> index 0000000..1d17ef9
> --- /dev/null
> +++ b/configure
> @@ -0,0 +1,116 @@
> +#!/bin/sh
> +
> +build_config=config.mk
> +temp_dir=$(mktemp -d)
> +temp_file=$temp_dir/file.c
> +
> +LIBS=
> +NUMA_LIBS=
> +EXTRA_CFLAGS=
> +has_numa=n
> +has_numa_cpustring_all=n
> +
> +build_test()
> +{
> +	local libs=$*
> +	local ret=
> +
> +	cd $temp_dir
> +	cc -o prog $temp_file $libs 2> /dev/null
> +	ret=$?
> +	cd - > /dev/null
> +	return $ret
> +}
> +
> +#
> +# -lpthread
> +#
> +pthread_lib=-lpthread
> +
> +cat > $temp_file << EOF
> +#include <pthread.h>
> +static void *func(void *p) { return NULL; }
> +int main(void) {
> +	pthread_t thread;
> +	pthread_create(&thread, 0, func, 0);
> +	return 0;
> +}
> +EOF
> +
> +if ! build_test $pthread_lib; then
> +	echo ERROR: missing pthread library
> +	exit 1
> +else
> +	LIBS="$LIBS $pthread_lib"
> +fi
> +
> +#
> +# -lrt
> +#
> +rt_lib=-lrt
> +
> +cat > $temp_file << EOF
> +#include <sys/mman.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +int main(void) {
> +	shm_open("", 0, 0);
> +	return 0;
> +}
> +EOF
> +
> +if ! build_test $rt_lib; then
> +	echo ERROR: missing rt library
> +	exit 1
> +else
> +	LIBS="$LIBS $rt_lib"
> +fi
> +
> +#
> +# -lnuma
> +#
> +numa_lib=-lnuma
> +
> +cat > $temp_file << EOF
> +#include <numa.h>
> +int main(void) {
> +	numa_available();
> +	return 0;
> +}
> +EOF
> +
> +if build_test $numa_lib; then
> +	LIBS="$LIBS $numa_lib"
> +	EXTRA_CFLAGS="$EXTRA_CFLAGS -DNUMA"
> +	has_numa=y
> +fi
> +
> +#
> +# numa_parse_cpustring_all
> +#
> +if [ $has_numa = "y" ]; then
> +
> +	cat > $temp_file << EOF
> +#include <numa.h>
> +int main(void) {
> +	numa_parse_cpustring_all("");
> +	return 0;
> +}
> +EOF
> +
> +	if build_test $numa_lib; then
> +		has_numa_cpustring_all=y;
> +	fi
> +fi
> +
> +#
> +# Write $build_config
> +#
> +echo "LIBS = $LIBS" > $build_config
> +echo "EXTRA_CFLAGS = $EXTRA_CFLAGS" >> $build_config
> +
> +if [ "$has_numa_cpustring_all" = "y" ]; then
> +	echo "HAVE_PARSE_CPUSTRING_ALL := 1" >> $build_config
> +fi
> +
> +rm -rf $temp_dir
> -- 
> 2.5.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

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

* Re: [PATCH] cyclictest: avoid using libnuma cpumask parsing functions
  2016-04-19 13:17   ` John Kacur
@ 2016-04-19 13:30     ` Luiz Capitulino
  0 siblings, 0 replies; 5+ messages in thread
From: Luiz Capitulino @ 2016-04-19 13:30 UTC (permalink / raw)
  To: John Kacur; +Cc: Clark Williams, RT, LKML

On Tue, 19 Apr 2016 15:17:33 +0200 (CEST)
John Kacur <jkacur@redhat.com> wrote:

> On Thu, 14 Apr 2016, Luiz Capitulino wrote:
> 
> > On Wed, 13 Apr 2016 15:37:00 -0500
> > Clark Williams <williams@redhat.com> wrote:
> >   
> > > John,
> > > 
> > > I ran into issues with parsing cpu masks when trying to run this command:
> > > 
> > > sudo ./cyclictest -i100 -qmu -h 2000 -p95 -t1 -a3
> > > 
> > > I had previously booted a 4-core system with these boot options:
> > > 
> > > 	isolcpus=3 nohz_full=3 rcu_nocbs=3
> > > 
> > > The intent was to run loads on cpus 0-2 while running cyclictest on the isolated cpu 3. 
> > > 
> > > Unfortunately, the libnuma function numa_parse_cpumask() (which we use when it's available) seems to check the current affinity mask and fails the parse if any of the cpus in the input string are not in the current affinity mask. I find this "unhelpful" when trying to place a measurement thread on an isolated cpu. 
> > > 
> > > This patch removes the wrapper function which uses libnuma cpumask parsing functions and instead uses the parser function we wrote for when libnuma is not available.   
> > 
> > There's an alternative solution that I was working on some time ago,
> > which is having a simple configure script. This is usually done
> > by simple projects that don't need a full blown autoconf machinery.
> > 
> > The patch below adds such a script. It detects librt, libpthread and
> > libnuma. It solves the problem you mention and it removes hardcoded
> > lib details from the Makefile.
> > 
> > If there's interest for this solution I can finish it and post for
> > inclusion.  
> 
> I find this interesting, maybe for the coming new devel system, I wouldn't 
> want to stick it in now right before a stable release though.

Makes sense.

> Also, I 
> like this much better than full blown auto-tools, but I don't want to lose control over 
> the compiling process either. In otherwords, there should be some way to 
> override what the script detects.

We could implement command-line options.

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

end of thread, other threads:[~2016-04-19 13:30 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-13 20:37 [PATCH] cyclictest: avoid using libnuma cpumask parsing functions Clark Williams
2016-04-14 14:30 ` Luiz Capitulino
2016-04-19 13:17   ` John Kacur
2016-04-19 13:30     ` Luiz Capitulino
2016-04-19 13:14 ` John Kacur

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.