From: tixy@yxit.co.uk (Tixy)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3] ARM: kprobes: Add some benchmarking to test module
Date: Sun, 18 Sep 2011 12:17:58 +0100 [thread overview]
Message-ID: <1316344678.2259.9.camel@computer2> (raw)
In-Reply-To: <alpine.LFD.2.00.1109112241310.20358@xanadu.home>
From: Jon Medhurst <tixy@yxit.co.uk>
These benchmarks show the basic speed of kprobes and verify the success
of optimisations done to the emulation of typical function entry
instructions (i.e. push/stmdb).
Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
Acked-by: Nicolas Pitre <nicolas.pitre@linaro.org>
---
Changes since v2:
- Modify benchmark() to use sched_clock() rather than do_gettimeofday()
as this has lower overheads and gives simpler code - as suggested by
Nicolas Pitre.
---
arch/arm/kernel/kprobes-test.c | 161 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 161 insertions(+), 0 deletions(-)
diff --git a/arch/arm/kernel/kprobes-test.c b/arch/arm/kernel/kprobes-test.c
index fe169e9..e5740c7 100644
--- a/arch/arm/kernel/kprobes-test.c
+++ b/arch/arm/kernel/kprobes-test.c
@@ -185,6 +185,9 @@
#include "kprobes-test.h"
+#define BENCHMARKING 1
+
+
/*
* Test basic API
*/
@@ -444,6 +447,157 @@ static int run_api_tests(long (*func)(long, long))
/*
+ * Benchmarking
+ */
+
+#if BENCHMARKING
+
+static void __naked benchmark_nop(void)
+{
+ __asm__ __volatile__ (
+ "nop \n\t"
+ "bx lr"
+ );
+}
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define wide ".w"
+#else
+#define wide
+#endif
+
+static void __naked benchmark_pushpop1(void)
+{
+ __asm__ __volatile__ (
+ "stmdb"wide" sp!, {r3-r11,lr} \n\t"
+ "ldmia"wide" sp!, {r3-r11,pc}"
+ );
+}
+
+static void __naked benchmark_pushpop2(void)
+{
+ __asm__ __volatile__ (
+ "stmdb"wide" sp!, {r0-r8,lr} \n\t"
+ "ldmia"wide" sp!, {r0-r8,pc}"
+ );
+}
+
+static void __naked benchmark_pushpop3(void)
+{
+ __asm__ __volatile__ (
+ "stmdb"wide" sp!, {r4,lr} \n\t"
+ "ldmia"wide" sp!, {r4,pc}"
+ );
+}
+
+static void __naked benchmark_pushpop4(void)
+{
+ __asm__ __volatile__ (
+ "stmdb"wide" sp!, {r0,lr} \n\t"
+ "ldmia"wide" sp!, {r0,pc}"
+ );
+}
+
+
+#ifdef CONFIG_THUMB2_KERNEL
+
+static void __naked benchmark_pushpop_thumb(void)
+{
+ __asm__ __volatile__ (
+ "push.n {r0-r7,lr} \n\t"
+ "pop.n {r0-r7,pc}"
+ );
+}
+
+#endif
+
+static int __kprobes
+benchmark_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ return 0;
+}
+
+static int benchmark(void(*fn)(void))
+{
+ unsigned n, i, t, t0;
+
+ for (n = 1000; ; n *= 2) {
+ t0 = sched_clock();
+ for (i = n; i > 0; --i)
+ fn();
+ t = sched_clock() - t0;
+ if (t >= 250000000)
+ break; /* Stop once we took more than 0.25 seconds */
+ }
+ return t / n; /* Time for one iteration in nanoseconds */
+};
+
+static int kprobe_benchmark(void(*fn)(void), unsigned offset)
+{
+ struct kprobe k = {
+ .addr = (kprobe_opcode_t *)((uintptr_t)fn + offset),
+ .pre_handler = benchmark_pre_handler,
+ };
+
+ int ret = register_kprobe(&k);
+ if (ret < 0) {
+ pr_err("FAIL: register_kprobe failed with %d\n", ret);
+ return ret;
+ }
+
+ ret = benchmark(fn);
+
+ unregister_kprobe(&k);
+ return ret;
+};
+
+struct benchmarks {
+ void (*fn)(void);
+ unsigned offset;
+ const char *title;
+};
+
+static int run_benchmarks(void)
+{
+ int ret;
+ struct benchmarks list[] = {
+ {&benchmark_nop, 0, "nop"},
+ /*
+ * benchmark_pushpop{1,3} will have the optimised
+ * instruction emulation, whilst benchmark_pushpop{2,4} will
+ * be the equivalent unoptimised instructions.
+ */
+ {&benchmark_pushpop1, 0, "stmdb sp!, {r3-r11,lr}"},
+ {&benchmark_pushpop1, 4, "ldmia sp!, {r3-r11,pc}"},
+ {&benchmark_pushpop2, 0, "stmdb sp!, {r0-r8,lr}"},
+ {&benchmark_pushpop2, 4, "ldmia sp!, {r0-r8,pc}"},
+ {&benchmark_pushpop3, 0, "stmdb sp!, {r4,lr}"},
+ {&benchmark_pushpop3, 4, "ldmia sp!, {r4,pc}"},
+ {&benchmark_pushpop4, 0, "stmdb sp!, {r0,lr}"},
+ {&benchmark_pushpop4, 4, "ldmia sp!, {r0,pc}"},
+#ifdef CONFIG_THUMB2_KERNEL
+ {&benchmark_pushpop_thumb, 0, "push.n {r0-r7,lr}"},
+ {&benchmark_pushpop_thumb, 2, "pop.n {r0-r7,pc}"},
+#endif
+ {0}
+ };
+
+ struct benchmarks *b;
+ for (b = list; b->fn; ++b) {
+ ret = kprobe_benchmark(b->fn, b->offset);
+ if (ret < 0)
+ return ret;
+ pr_info(" %dns for kprobe %s\n", ret, b->title);
+ }
+
+ pr_info("\n");
+ return 0;
+}
+
+#endif /* BENCHMARKING */
+
+
+/*
* Decoding table self-consistency tests
*/
@@ -1526,6 +1680,13 @@ static int __init run_all_tests(void)
goto out;
}
+#if BENCHMARKING
+ pr_info("Benchmarks\n");
+ ret = run_benchmarks();
+ if (ret)
+ goto out;
+#endif
+
#if __LINUX_ARM_ARCH__ >= 7
/* We are able to run all test cases so coverage should be complete */
if (coverage_fail) {
--
1.7.2.5
next prev parent reply other threads:[~2011-09-18 11:17 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-10 11:04 [PATCH v2 00/10] ARM: kprobes: Add test code to kernel tree Tixy
2011-09-10 11:04 ` [PATCH v2 01/10] ARM: kprobes: Add config option for selecting the ARM kprobes tests Tixy
2011-09-10 11:04 ` [PATCH v2 02/10] ARM: kprobes: Add basic API tests Tixy
2011-09-10 11:04 ` [PATCH v2 03/10] ARM: kprobes: Framework for instruction set test cases Tixy
2011-09-12 3:01 ` Nicolas Pitre
2011-09-10 11:05 ` [PATCH v2 04/10] ARM: kprobes: Add Thumb instruction simulation " Tixy
2011-09-10 11:05 ` [PATCH v2 05/10] ARM: kprobes: Add ARM " Tixy
2011-09-10 11:05 ` [PATCH v2 06/10] ARM: kprobes: Add exports for test code Tixy
2011-09-10 11:05 ` [PATCH v2 07/10] ARM: kprobes: Add decoding table self-consistency tests Tixy
2011-09-10 11:05 ` [PATCH v2 08/10] ARM: kprobes: Add decoding table test coverage analysis Tixy
2011-09-10 11:05 ` [PATCH v2 09/10] ARM: kprobes: Add some benchmarking to test module Tixy
2011-09-12 2:58 ` Nicolas Pitre
2011-09-12 7:09 ` Tixy
2011-09-12 7:41 ` Russell King - ARM Linux
2011-09-18 11:17 ` Tixy [this message]
2011-09-10 11:05 ` [PATCH v2 10/10] ARM: kprobes: Add introductory comment to test code Tixy
2011-09-12 3:10 ` [PATCH v2 00/10] ARM: kprobes: Add test code to kernel tree Nicolas Pitre
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=1316344678.2259.9.camel@computer2 \
--to=tixy@yxit.co.uk \
--cc=linux-arm-kernel@lists.infradead.org \
/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.