Re: [PATCH v2 1/3] percpu: add test module for various percpu operations

2013-11-07 Thread Greg Thelen
On Mon, Nov 04 2013, Andrew Morton wrote:

> On Sun, 27 Oct 2013 10:30:15 -0700 Greg Thelen  wrote:
>
>> Tests various percpu operations.
>
> Could you please take a look at the 32-bit build (this is i386):
>
> lib/percpu_test.c: In function 'percpu_test_init':
> lib/percpu_test.c:61: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:61: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:61: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:61: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:61: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:61: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:70: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:70: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:70: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:70: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:70: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:70: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:89: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:89: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:89: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:89: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:89: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:89: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:97: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:97: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:97: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:97: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:97: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:97: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:112: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:112: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:112: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:112: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:112: warning: integer constant is too large for 'long' type
> lib/percpu_test.c:112: warning: integer constant is too large for 'long' type

I was using gcc 4.6 which apparently adds LL suffix as needed.  Though
there were some other code problems with 32 bit beyond missing suffixes.
Fixed version below tested with both gcc 4.4 and gcc 4.6 on 32 and 64
bit x86.

---8<---

>From a95bb1ce42b4492644fa10c7c80fd9bbd7bf23b9 Mon Sep 17 00:00:00 2001
In-Reply-To: <20131104160918.0c571b410cf165e9c4b4a...@linux-foundation.org>
References: <20131104160918.0c571b410cf165e9c4b4a...@linux-foundation.org>
From: Greg Thelen 
Date: Sun, 27 Oct 2013 10:30:15 -0700
Subject: [PATCH v2] percpu: add test module for various percpu operations

Tests various percpu operations.

Enable with CONFIG_PERCPU_TEST=m.

Signed-off-by: Greg Thelen 
Acked-by: Tejun Heo 
---
Changelog since v1:
- use %lld/x which allows for less casting
- fix 32 bit build by casting large constants

 lib/Kconfig.debug |   9 
 lib/Makefile  |   2 +
 lib/percpu_test.c | 138 ++
 3 files changed, 149 insertions(+)
 create mode 100644 lib/percpu_test.c

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 094f3152ec2b..1891eb271adf 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1472,6 +1472,15 @@ config INTERVAL_TREE_TEST
help
  A benchmark measuring the performance of the interval tree library
 
+config PERCPU_TEST
+   tristate "Per cpu operations test"
+   depends on m && DEBUG_KERNEL
+   help
+ Enable this option to build test module which validates per-cpu
+ operations.
+
+ If unsure, say N.
+
 config ATOMIC64_SELFTEST
bool "Perform an atomic64_t self-test at boot"
help
diff --git a/lib/Makefile b/lib/Makefile
index f3bb2cb98adf..bb016e116ba4 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -157,6 +157,8 @@ obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
 
 interval_tree_test-objs := interval_tree_test_main.o interval_tree.o
 
+obj-$(CONFIG_PERCPU_TEST) += percpu_test.o
+
 obj-$(CONFIG_ASN1) += asn1_decoder.o
 
 obj-$(CONFIG_FONT_SUPPORT) += fonts/
diff --git a/lib/percpu_test.c b/lib/percpu_test.c
new file mode 100644
index ..0b5d14dadd1a
--- /dev/null
+++ b/lib/percpu_test.c
@@ -0,0 +1,138 @@
+#include 
+
+/* validate @native and @pcp counter values match @expected */
+#define CHECK(native, pcp, expected)\
+

Re: [PATCH v2 1/3] percpu: add test module for various percpu operations

2013-11-04 Thread Andrew Morton
On Sun, 27 Oct 2013 10:30:15 -0700 Greg Thelen  wrote:

> Tests various percpu operations.

Could you please take a look at the 32-bit build (this is i386):

lib/percpu_test.c: In function 'percpu_test_init':
lib/percpu_test.c:61: warning: integer constant is too large for 'long' type
lib/percpu_test.c:61: warning: integer constant is too large for 'long' type
lib/percpu_test.c:61: warning: integer constant is too large for 'long' type
lib/percpu_test.c:61: warning: integer constant is too large for 'long' type
lib/percpu_test.c:61: warning: integer constant is too large for 'long' type
lib/percpu_test.c:61: warning: integer constant is too large for 'long' type
lib/percpu_test.c:70: warning: integer constant is too large for 'long' type
lib/percpu_test.c:70: warning: integer constant is too large for 'long' type
lib/percpu_test.c:70: warning: integer constant is too large for 'long' type
lib/percpu_test.c:70: warning: integer constant is too large for 'long' type
lib/percpu_test.c:70: warning: integer constant is too large for 'long' type
lib/percpu_test.c:70: warning: integer constant is too large for 'long' type
lib/percpu_test.c:89: warning: integer constant is too large for 'long' type
lib/percpu_test.c:89: warning: integer constant is too large for 'long' type
lib/percpu_test.c:89: warning: integer constant is too large for 'long' type
lib/percpu_test.c:89: warning: integer constant is too large for 'long' type
lib/percpu_test.c:89: warning: integer constant is too large for 'long' type
lib/percpu_test.c:89: warning: integer constant is too large for 'long' type
lib/percpu_test.c:97: warning: integer constant is too large for 'long' type
lib/percpu_test.c:97: warning: integer constant is too large for 'long' type
lib/percpu_test.c:97: warning: integer constant is too large for 'long' type
lib/percpu_test.c:97: warning: integer constant is too large for 'long' type
lib/percpu_test.c:97: warning: integer constant is too large for 'long' type
lib/percpu_test.c:97: warning: integer constant is too large for 'long' type
lib/percpu_test.c:112: warning: integer constant is too large for 'long' type
lib/percpu_test.c:112: warning: integer constant is too large for 'long' type
lib/percpu_test.c:112: warning: integer constant is too large for 'long' type
lib/percpu_test.c:112: warning: integer constant is too large for 'long' type
lib/percpu_test.c:112: warning: integer constant is too large for 'long' type
lib/percpu_test.c:112: warning: integer constant is too large for 'long' type
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 1/3] percpu: add test module for various percpu operations

2013-10-27 Thread Greg Thelen
Tests various percpu operations.

Enable with CONFIG_PERCPU_TEST=m.

Signed-off-by: Greg Thelen 
Acked-by: Tejun Heo 
---
 lib/Kconfig.debug |   9 
 lib/Makefile  |   2 +
 lib/percpu_test.c | 138 ++
 3 files changed, 149 insertions(+)
 create mode 100644 lib/percpu_test.c

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 06344d9..9fdb452 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1472,6 +1472,15 @@ config INTERVAL_TREE_TEST
help
  A benchmark measuring the performance of the interval tree library
 
+config PERCPU_TEST
+   tristate "Per cpu operations test"
+   depends on m && DEBUG_KERNEL
+   help
+ Enable this option to build test module which validates per-cpu
+ operations.
+
+ If unsure, say N.
+
 config ATOMIC64_SELFTEST
bool "Perform an atomic64_t self-test at boot"
help
diff --git a/lib/Makefile b/lib/Makefile
index f3bb2cb..bb016e1 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -157,6 +157,8 @@ obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
 
 interval_tree_test-objs := interval_tree_test_main.o interval_tree.o
 
+obj-$(CONFIG_PERCPU_TEST) += percpu_test.o
+
 obj-$(CONFIG_ASN1) += asn1_decoder.o
 
 obj-$(CONFIG_FONT_SUPPORT) += fonts/
diff --git a/lib/percpu_test.c b/lib/percpu_test.c
new file mode 100644
index 000..fcca49e
--- /dev/null
+++ b/lib/percpu_test.c
@@ -0,0 +1,138 @@
+#include 
+
+/* validate @native and @pcp counter values match @expected */
+#define CHECK(native, pcp, expected)\
+   do {\
+   WARN((native) != (expected),\
+"raw %ld (0x%lx) != expected %ld (0x%lx)", \
+(long)(native), (long)(native),\
+(long)(expected), (long)(expected));   \
+   WARN(__this_cpu_read(pcp) != (expected),\
+"pcp %ld (0x%lx) != expected %ld (0x%lx)", \
+(long)__this_cpu_read(pcp), (long)__this_cpu_read(pcp), \
+(long)(expected), (long)(expected));   \
+   } while (0)
+
+static DEFINE_PER_CPU(long, long_counter);
+static DEFINE_PER_CPU(unsigned long, ulong_counter);
+
+static int __init percpu_test_init(void)
+{
+   /*
+* volatile prevents compiler from optimizing it uses, otherwise the
+* +ul_one and -ul_one below would replace with inc/dec instructions.
+*/
+   volatile unsigned int ui_one = 1;
+   long l = 0;
+   unsigned long ul = 0;
+
+   pr_info("percpu test start\n");
+
+   preempt_disable();
+
+   l += -1;
+   __this_cpu_add(long_counter, -1);
+   CHECK(l, long_counter, -1);
+
+   l += 1;
+   __this_cpu_add(long_counter, 1);
+   CHECK(l, long_counter, 0);
+
+   ul = 0;
+   __this_cpu_write(ulong_counter, 0);
+
+   ul += 1UL;
+   __this_cpu_add(ulong_counter, 1UL);
+   CHECK(ul, ulong_counter, 1);
+
+   ul += -1UL;
+   __this_cpu_add(ulong_counter, -1UL);
+   CHECK(ul, ulong_counter, 0);
+
+   ul += -(unsigned long)1;
+   __this_cpu_add(ulong_counter, -(unsigned long)1);
+   CHECK(ul, ulong_counter, -1);
+
+   ul = 0;
+   __this_cpu_write(ulong_counter, 0);
+
+   ul -= 1;
+   __this_cpu_dec(ulong_counter);
+   CHECK(ul, ulong_counter, 0x);
+   CHECK(ul, ulong_counter, -1);
+
+   l += -ui_one;
+   __this_cpu_add(long_counter, -ui_one);
+   CHECK(l, long_counter, 0x);
+
+   l += ui_one;
+   __this_cpu_add(long_counter, ui_one);
+   CHECK(l, long_counter, 0x1);
+
+
+   l = 0;
+   __this_cpu_write(long_counter, 0);
+
+   l -= ui_one;
+   __this_cpu_sub(long_counter, ui_one);
+   CHECK(l, long_counter, -1);
+
+   l = 0;
+   __this_cpu_write(long_counter, 0);
+
+   l += ui_one;
+   __this_cpu_add(long_counter, ui_one);
+   CHECK(l, long_counter, 1);
+
+   l += -ui_one;
+   __this_cpu_add(long_counter, -ui_one);
+   CHECK(l, long_counter, 0x1);
+
+   l = 0;
+   __this_cpu_write(long_counter, 0);
+
+   l -= ui_one;
+   this_cpu_sub(long_counter, ui_one);
+   CHECK(l, long_counter, -1);
+   CHECK(l, long_counter, 0x);
+
+   ul = 0;
+   __this_cpu_write(ulong_counter, 0);
+
+   ul += ui_one;
+   __this_cpu_add(ulong_counter, ui_one);
+   CHECK(ul, ulong_counter, 1);
+
+   ul = 0;
+   __this_cpu_write(ulong_counter, 0);
+
+   ul -= ui_one;
+   __this_cpu_sub(ulong_counter, ui_one);
+   CHECK(ul, ulong_counter, -1);
+   CHECK(ul, ulong_counter, 0x);
+
+   ul = 3;
+   __this_cpu_write(ulong_counter, 3);
+
+   ul = this_cpu_sub_return(ulong_cou