All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Baron <jbaron@akamai.com>
To: Peter Zijlstra <peterz@infradead.org>,
	linux-kernel@vger.kernel.org, mingo@kernel.org
Cc: bp@alien8.de, luto@amacapital.net, tglx@linutronix.de,
	rostedt@goodmis.org, will.deacon@arm.com, liuj97@gmail.com,
	rabin@rab.in, ralf@linux-mips.org, ddaney@caviumnetworks.com,
	benh@kernel.crashing.org, michael@ellerman.id.au,
	heiko.carstens@de.ibm.com, davem@davemloft.net, vbabka@suse.cz
Subject: Re: [PATCH -v2 7/8] jump_label: Add selftest
Date: Tue, 28 Jul 2015 17:46:40 -0400	[thread overview]
Message-ID: <55B7F840.3050805@akamai.com> (raw)
In-Reply-To: <20150728132313.272942631@infradead.org>

On 07/28/2015 09:21 AM, Peter Zijlstra wrote:

Hi,

Funny-so I did something similar but its a modules self test
so I think its complementary. I can re-post with a changelog
and some more comments if you think its worthwhile. I have
two modules in order to test actually updating the key
during module load of the second module. It also covers
the 'legacy' interface.

In order to get the !CONFIG_JUMP_LABEL to work I needed,
the following:

diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index c033595..27b335a 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -183,10 +183,10 @@ static inline int jump_label_apply_nops(struct module *mod)
     return 0;
 }
 
-#define STATIC_KEY_INIT_TRUE ((struct static_key) \
-        { .enabled = ATOMIC_INIT(1) })
-#define STATIC_KEY_INIT_FALSE ((struct static_key) \
-        { .enabled = ATOMIC_INIT(0) })
+#define STATIC_KEY_INIT_TRUE    \
+        { .enabled = ATOMIC_INIT(1) }
+#define STATIC_KEY_INIT_FALSE    \
+        { .enabled = ATOMIC_INIT(0) }
 
 #endif    /* HAVE_JUMP_LABEL */
 

Other than that, everything seems to be working fine for me
with -v2.

We probably should also update Documentation/static-keys.txt.
I can take a stab at that, if needed.

Module selftest is below.

Thanks,

-Jason

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index b908048..d87d7b6 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1835,6 +1835,15 @@ config MEMTEST
             memtest=17, mean do 17 test patterns.
       If you are unsure how to answer this question, answer N.
 
+config TEST_JUMP_LABEL
+    tristate "Test jump label"
+    default n
+    depends on m
+    help
+      Test jump labels.
+
+      If unsure, say N.
+
 source "samples/Kconfig"
 
 source "lib/Kconfig.kgdb"
diff --git a/lib/Makefile b/lib/Makefile
index ff37c8c..ea20293 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -39,6 +39,8 @@ obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o
 obj-$(CONFIG_TEST_LKM) += test_module.o
 obj-$(CONFIG_TEST_RHASHTABLE) += test_rhashtable.o
 obj-$(CONFIG_TEST_USER_COPY) += test_user_copy.o
+obj-$(CONFIG_TEST_JUMP_LABEL) += test_jump_label.o
+obj-$(CONFIG_TEST_JUMP_LABEL) += test_jump_label_base.o
 
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
diff --git a/lib/test_jump_label.c b/lib/test_jump_label.c
new file mode 100644
index 0000000..5a5eb86
--- /dev/null
+++ b/lib/test_jump_label.c
@@ -0,0 +1,225 @@
+/*
+ * Kernel module for testing jump labels.
+ *
+ * Copyright 2015 Akamai Technologies Inc. All Rights Reserved
+ *
+ * Authors:
+ *      Jason Baron       <jbaron@akamai.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/jump_label.h>
+
+/* old keys */
+struct static_key old_true_key = STATIC_KEY_INIT_TRUE;
+struct static_key old_false_key = STATIC_KEY_INIT_FALSE;
+
+/* new api */
+DEFINE_STATIC_KEY_TRUE(true_key);
+DEFINE_STATIC_KEY_FALSE(false_key);
+
+/* external */
+extern struct static_key base_old_true_key;
+extern struct static_key base_inv_old_true_key;
+extern struct static_key base_old_false_key;
+extern struct static_key base_inv_old_false_key;
+
+/* new api */
+extern struct static_key_true base_true_key;
+extern struct static_key_true base_inv_true_key;
+extern struct static_key_false base_false_key;
+extern struct static_key_false base_inv_false_key;
+
+
+struct test_branch {
+    bool init_state;
+    struct static_key *key;
+    bool (*test_key)(void);
+};
+
+#define test_key_func(key, branch)    \
+({bool func(void) { return branch(key); } func;    })
+
+static void invert_key(struct static_key *key)
+{
+    if (static_key_enabled(key))
+        static_key_disable(key);
+    else
+        static_key_enable(key);
+}
+
+static void invert_keys(struct test_branch *branches, int size)
+{
+    struct static_key *previous = NULL;
+    int i;
+   
+    for (i = 0; i < size; i++) {
+        if (previous != branches[i].key) {
+            invert_key(branches[i].key);
+            previous = branches[i].key;
+        }
+    }
+}
+
+int verify_branches(struct test_branch *branches, int size, bool invert)
+{
+    int i;
+    bool ret, init;
+
+    for (i = 0; i < size; i++) {
+        ret = static_key_enabled(branches[i].key);
+        init = branches[i].init_state;
+        if (ret != (invert ? !init : init))
+            return -EINVAL;
+        ret = branches[i].test_key();
+        if (static_key_enabled(branches[i].key)) {
+            if (!ret)
+                return -EINVAL;
+        } else {
+            if (ret)
+                return -EINVAL;
+        }
+    }
+    return 0;
+}
+
+static int __init test_jump_label_init(void)
+{
+    int ret;
+    int size;
+
+    struct test_branch jump_label_tests[] = {
+        /* internal keys - old keys */
+        {
+            .init_state = true,
+            .key = &old_true_key,
+            .test_key = test_key_func(&old_true_key, static_key_true),
+        },
+        {
+            .init_state = false,
+            .key = &old_false_key,
+            .test_key = test_key_func(&old_false_key, static_key_false),
+        },
+        /* internal keys - new keys */
+        {
+            .init_state = true,
+            .key = &true_key.key,
+            .test_key = test_key_func(&true_key, static_branch_likely),
+        },
+        {
+            .init_state = true,
+            .key = &true_key.key,
+            .test_key = test_key_func(&true_key, static_branch_unlikely),
+        },
+        {
+            .init_state = false,
+            .key = &false_key.key,
+            .test_key = test_key_func(&false_key, static_branch_likely),
+        },
+        {
+            .init_state = false,
+            .key = &false_key.key,
+            .test_key = test_key_func(&false_key, static_branch_unlikely),
+        },
+        /* external keys - old keys */
+        {
+            .init_state = true,
+            .key = &base_old_true_key,
+            .test_key = test_key_func(&base_old_true_key, static_key_true),
+        },
+        {
+            .init_state = false,
+            .key = &base_inv_old_true_key,
+            .test_key = test_key_func(&base_inv_old_true_key, static_key_true),
+        },
+        {
+            .init_state = false,
+            .key = &base_old_false_key,
+            .test_key = test_key_func(&base_old_false_key, static_key_false),
+        },
+        {
+            .init_state = true,
+            .key = &base_inv_old_false_key,
+            .test_key = test_key_func(&base_inv_old_false_key, static_key_false),
+        },
+        /* external keys - new keys */
+        {
+            .init_state = true,
+            .key = &base_true_key.key,
+            .test_key = test_key_func(&base_true_key, static_branch_likely),
+        },
+        {
+            .init_state = true,
+            .key = &base_true_key.key,
+            .test_key = test_key_func(&base_true_key, static_branch_unlikely),
+        },
+        {
+            .init_state = false,
+            .key = &base_inv_true_key.key,
+            .test_key = test_key_func(&base_inv_true_key, static_branch_likely),
+        },
+        {
+            .init_state = false,
+            .key = &base_inv_true_key.key,
+            .test_key = test_key_func(&base_inv_true_key, static_branch_unlikely),
+        },
+        {
+            .init_state = false,
+            .key = &base_false_key.key,
+            .test_key = test_key_func(&base_false_key, static_branch_likely),
+        },
+        {
+            .init_state = false,
+            .key = &base_false_key.key,
+            .test_key = test_key_func(&base_false_key, static_branch_unlikely),
+        },
+        {
+            .init_state = true,
+            .key = &base_inv_false_key.key,
+            .test_key = test_key_func(&base_inv_false_key, static_branch_likely),
+        },
+        {
+            .init_state = true,
+            .key = &base_inv_false_key.key,
+            .test_key = test_key_func(&base_inv_false_key, static_branch_unlikely),
+        },
+    };
+
+    size = ARRAY_SIZE(jump_label_tests);
+
+    ret = verify_branches(jump_label_tests, size, false);
+    if (ret)
+        goto out;
+
+    invert_keys(jump_label_tests, size);
+    ret = verify_branches(jump_label_tests, size, true);
+    if (ret)
+        goto out;
+
+    invert_keys(jump_label_tests, size);
+    ret = verify_branches(jump_label_tests, size, false);
+    if (ret)
+        goto out;
+    return 0;
+out:
+    return ret;
+}
+
+static void __exit test_jump_label_exit(void)
+{
+}
+
+module_init(test_jump_label_init);
+module_exit(test_jump_label_exit);
+
+MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>");
+MODULE_LICENSE("GPL");
diff --git a/lib/test_jump_label_base.c b/lib/test_jump_label_base.c
new file mode 100644
index 0000000..91aed8e
--- /dev/null
+++ b/lib/test_jump_label_base.c
@@ -0,0 +1,68 @@
+/*
+ * Kernel module for testing jump labels.
+ *
+ * Copyright 2015 Akamai Technologies Inc. All Rights Reserved
+ *
+ * Authors:
+ *      Jason Baron       <jbaron@akamai.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/jump_label.h>
+
+/* old keys */
+struct static_key base_old_true_key = STATIC_KEY_INIT_TRUE;
+EXPORT_SYMBOL_GPL(base_old_true_key);
+struct static_key base_inv_old_true_key = STATIC_KEY_INIT_TRUE;
+EXPORT_SYMBOL_GPL(base_inv_old_true_key);
+struct static_key base_old_false_key = STATIC_KEY_INIT_FALSE;
+EXPORT_SYMBOL_GPL(base_old_false_key);
+struct static_key base_inv_old_false_key = STATIC_KEY_INIT_FALSE;
+EXPORT_SYMBOL_GPL(base_inv_old_false_key);
+
+/* new keys */
+DEFINE_STATIC_KEY_TRUE(base_true_key);
+EXPORT_SYMBOL_GPL(base_true_key);
+DEFINE_STATIC_KEY_TRUE(base_inv_true_key);
+EXPORT_SYMBOL_GPL(base_inv_true_key);
+DEFINE_STATIC_KEY_FALSE(base_false_key);
+EXPORT_SYMBOL_GPL(base_false_key);
+DEFINE_STATIC_KEY_FALSE(base_inv_false_key);
+EXPORT_SYMBOL_GPL(base_inv_false_key);
+
+static void invert_key(struct static_key *key)
+{
+    if (static_key_enabled(key))
+        static_key_disable(key);
+    else
+        static_key_enable(key);
+}
+
+static int __init test_jump_label_base_init(void)
+{
+    invert_key(&base_inv_old_true_key);
+    invert_key(&base_inv_old_false_key);
+    invert_key(&base_inv_true_key.key);
+    invert_key(&base_inv_false_key.key);
+
+    return 0;
+}
+
+static void __exit test_jump_label_base_exit(void)
+{
+}
+
+module_init(test_jump_label_base_init);
+module_exit(test_jump_label_base_exit);
+
+MODULE_AUTHOR("Jason Baron <jbaron@akamai.com>");
+MODULE_LICENSE("GPL");
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 24ae9e8..b8f12e0 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -20,6 +20,7 @@ ifneq (1, $(quicktest))
 TARGETS += timers
 endif
 TARGETS += user
+TARGETS += jumplabel
 TARGETS += vm
 TARGETS += x86
 #Please keep the TARGETS list alphabetically sorted
diff --git a/tools/testing/selftests/jumplabel/Makefile b/tools/testing/selftests/jumplabel/Makefile
new file mode 100644
index 0000000..7526aa5
--- /dev/null
+++ b/tools/testing/selftests/jumplabel/Makefile
@@ -0,0 +1,8 @@
+# Makefile for jump label selftests
+
+# No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
+all:
+
+TEST_PROGS := test_jump_label.sh
+
+include ../lib.mk
diff --git a/tools/testing/selftests/jumplabel/test_jump_label.sh b/tools/testing/selftests/jumplabel/test_jump_label.sh
new file mode 100755
index 0000000..3457e8a
--- /dev/null
+++ b/tools/testing/selftests/jumplabel/test_jump_label.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+# Runs jump label kernel module tests
+
+if /sbin/modprobe -q test_jump_label_base; then
+    if /sbin/modprobe -q test_jump_label; then
+        echo "jump_label: ok"
+        /sbin/modprobe -q -r test_jump_label
+        /sbin/modprobe -q -r test_jump_label_base
+    else
+        echo "jump_label: [FAIL]"
+        /sbin/modprobe -q -r test_jump_label_base
+    fi
+else
+    echo "jump_label: [FAIL]"
+    exit 1
+fi
-- 
1.8.2.rc2



  reply	other threads:[~2015-07-28 21:55 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-28 13:20 [PATCH -v2 0/8] jump_label: Another (better) static_key interface Peter Zijlstra
2015-07-28 13:20 ` [PATCH -v2 1/8] jump_label: Rename JUMP_LABEL_{EN,DIS}ABLE Peter Zijlstra
2015-07-28 13:20 ` [PATCH -v2 2/8] jump_label: Rename JUMP_LABEL_TYPE_* Peter Zijlstra
2015-07-29 12:58   ` Borislav Petkov
2015-07-28 13:20 ` [PATCH -v2 3/8] jump_label: Add jump_entry_key() helper Peter Zijlstra
2015-07-28 13:20 ` [PATCH -v2 4/8] jump_label: Add static_key_{en,dis}able() helpers Peter Zijlstra
2015-07-28 13:21 ` [PATCH -v2 5/8] jump_label: Rework update logic Peter Zijlstra
2015-07-28 13:21 ` [PATCH -v2 6/8] jump_label: Add a new static_key interface Peter Zijlstra
2015-07-28 17:00   ` Rabin Vincent
2015-07-28 17:20     ` Peter Zijlstra
2015-07-29  6:43   ` Heiko Carstens
2015-07-29  7:19   ` Vlastimil Babka
2015-07-29  8:49     ` Peter Zijlstra
2015-08-03 19:03       ` Steven Rostedt
2015-08-03 19:18         ` Peter Zijlstra
2015-08-03 19:28           ` Steven Rostedt
2015-08-03 20:00             ` Peter Zijlstra
2015-08-03 21:57               ` Steven Rostedt
2015-08-04  3:37                 ` Borislav Petkov
2015-08-04  4:07                   ` Andy Lutomirski
2015-08-04  4:21                     ` Borislav Petkov
2015-08-04 12:06                   ` Steven Rostedt
2015-08-04 14:33                     ` Borislav Petkov
2015-08-04 14:41                       ` Steven Rostedt
2015-08-04 14:51                       ` Andy Lutomirski
2015-07-30 12:18   ` Michael Ellerman
2015-08-04  6:50   ` yalin wang
2015-08-04  9:15     ` Peter Zijlstra
2015-07-28 13:21 ` [PATCH -v2 7/8] jump_label: Add selftest Peter Zijlstra
2015-07-28 21:46   ` Jason Baron [this message]
2015-07-29  8:53     ` Peter Zijlstra
2015-07-28 13:21 ` [PATCH -v2 8/8] x86, tsc: Employ static_branch_likely() Peter Zijlstra
2015-07-29 14:07   ` Borislav Petkov
2015-07-29  6:46 ` [PATCH -v2 0/8] jump_label: Another (better) static_key interface Heiko Carstens
2015-07-29  8:58   ` Peter Zijlstra
2015-08-03 17:03   ` [tip:locking/core] s390/uaccess, locking/static_keys: employ static_branch_likely() tip-bot for Heiko Carstens

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=55B7F840.3050805@akamai.com \
    --to=jbaron@akamai.com \
    --cc=benh@kernel.crashing.org \
    --cc=bp@alien8.de \
    --cc=davem@davemloft.net \
    --cc=ddaney@caviumnetworks.com \
    --cc=heiko.carstens@de.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liuj97@gmail.com \
    --cc=luto@amacapital.net \
    --cc=michael@ellerman.id.au \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rabin@rab.in \
    --cc=ralf@linux-mips.org \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=vbabka@suse.cz \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.