2019-09-03 13:28:06

by Viktor Rosendahl

[permalink] [raw]
Subject: [PATCH v5 2/4] preemptirq_delay_test: Add the burst feature and a sysfs trigger

This burst feature enables the user to generate a burst of
preempt/irqsoff latencies. This makes it possible to test whether we
are able to detect latencies that systematically occur very close to
each other.

The maximum burst size is 10. We also create 10 identical test
functions, so that we get 10 different backtraces; this is useful
when we want to test whether we can detect all the latencies in a
burst. Otherwise, there would be no easy way of differentiating
between which latency in a burst was captured by the tracer.

In addition, there is a sysfs trigger, so that it's not necessary to
reload the module to repeat the test. The trigger will appear as
/sys/kernel/preemptirq_delay_test/trigger in sysfs.

Signed-off-by: Viktor Rosendahl <[email protected]>
---
kernel/trace/Kconfig | 6 +-
kernel/trace/preemptirq_delay_test.c | 145 +++++++++++++++++++++++----
2 files changed, 129 insertions(+), 22 deletions(-)

diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 98da8998c25c..5ff573d844e4 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -751,9 +751,9 @@ config PREEMPTIRQ_DELAY_TEST
configurable delay. The module busy waits for the duration of the
critical section.

- For example, the following invocation forces a one-time irq-disabled
- critical section for 500us:
- modprobe preemptirq_delay_test test_mode=irq delay=500000
+ For example, the following invocation generates a burst of three
+ irq-disabled critical sections for 500us:
+ modprobe preemptirq_delay_test test_mode=irq delay=500 burst_size=3

If unsure, say N

diff --git a/kernel/trace/preemptirq_delay_test.c b/kernel/trace/preemptirq_delay_test.c
index d8765c952fab..dc281fa75198 100644
--- a/kernel/trace/preemptirq_delay_test.c
+++ b/kernel/trace/preemptirq_delay_test.c
@@ -3,6 +3,7 @@
* Preempt / IRQ disable delay thread to test latency tracers
*
* Copyright (C) 2018 Joel Fernandes (Google) <[email protected]>
+ * Copyright (C) 2018, 2019 BMW Car IT GmbH
*/

#include <linux/trace_clock.h>
@@ -10,18 +11,25 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel.h>
+#include <linux/kobject.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/string.h>
+#include <linux/sysfs.h>

static ulong delay = 100;
-static char test_mode[10] = "irq";
+static char test_mode[12] = "irq";
+static uint burst_size = 1;

-module_param_named(delay, delay, ulong, S_IRUGO);
-module_param_string(test_mode, test_mode, 10, S_IRUGO);
-MODULE_PARM_DESC(delay, "Period in microseconds (100 uS default)");
-MODULE_PARM_DESC(test_mode, "Mode of the test such as preempt or irq (default irq)");
+module_param_named(delay, delay, ulong, 0444);
+module_param_string(test_mode, test_mode, 12, 0444);
+module_param_named(burst_size, burst_size, uint, 0444);
+MODULE_PARM_DESC(delay, "Period in microseconds (100 us default)");
+MODULE_PARM_DESC(test_mode, "Mode of the test such as preempt, irq, or alternate (default irq)");
+MODULE_PARM_DESC(burst_size, "The size of a burst (default 1)");
+
+#define MIN(x, y) ((x) < (y) ? (x) : (y))

static void busy_wait(ulong time)
{
@@ -34,37 +42,136 @@ static void busy_wait(ulong time)
} while ((end - start) < (time * 1000));
}

-static int preemptirq_delay_run(void *data)
+static __always_inline void irqoff_test(void)
{
unsigned long flags;
+ local_irq_save(flags);
+ busy_wait(delay);
+ local_irq_restore(flags);
+}

- if (!strcmp(test_mode, "irq")) {
- local_irq_save(flags);
- busy_wait(delay);
- local_irq_restore(flags);
- } else if (!strcmp(test_mode, "preempt")) {
- preempt_disable();
- busy_wait(delay);
- preempt_enable();
+static __always_inline void preemptoff_test(void)
+{
+ preempt_disable();
+ busy_wait(delay);
+ preempt_enable();
+}
+
+static void execute_preemptirqtest(int idx)
+{
+ if (!strcmp(test_mode, "irq"))
+ irqoff_test();
+ else if (!strcmp(test_mode, "preempt"))
+ preemptoff_test();
+ else if (!strcmp(test_mode, "alternate")) {
+ if (idx % 2 == 0)
+ irqoff_test();
+ else
+ preemptoff_test();
}
+}
+
+#define DECLARE_TESTFN(POSTFIX) \
+ static void preemptirqtest_##POSTFIX(int idx) \
+ { \
+ execute_preemptirqtest(idx); \
+ } \

+/*
+ * We create 10 different functions, so that we can get 10 different
+ * backtraces.
+ */
+DECLARE_TESTFN(0)
+DECLARE_TESTFN(1)
+DECLARE_TESTFN(2)
+DECLARE_TESTFN(3)
+DECLARE_TESTFN(4)
+DECLARE_TESTFN(5)
+DECLARE_TESTFN(6)
+DECLARE_TESTFN(7)
+DECLARE_TESTFN(8)
+DECLARE_TESTFN(9)
+
+static void (*testfuncs[])(int) = {
+ preemptirqtest_0,
+ preemptirqtest_1,
+ preemptirqtest_2,
+ preemptirqtest_3,
+ preemptirqtest_4,
+ preemptirqtest_5,
+ preemptirqtest_6,
+ preemptirqtest_7,
+ preemptirqtest_8,
+ preemptirqtest_9,
+};
+
+#define NR_TEST_FUNCS ARRAY_SIZE(testfuncs)
+
+static int preemptirq_delay_run(void *data)
+{
+ int i;
+ int s = MIN(burst_size, NR_TEST_FUNCS);
+
+ for (i = 0; i < s; i++)
+ (testfuncs[i])(i);
return 0;
}

-static int __init preemptirq_delay_init(void)
+static struct task_struct *preemptirq_start_test(void)
{
char task_name[50];
- struct task_struct *test_task;

snprintf(task_name, sizeof(task_name), "%s_test", test_mode);
+ return kthread_run(preemptirq_delay_run, NULL, task_name);
+}
+
+
+static ssize_t trigger_store(struct kobject *kobj, struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ preemptirq_start_test();
+ return count;
+}
+
+static struct kobj_attribute trigger_attribute =
+ __ATTR(trigger, 0200, NULL, trigger_store);
+
+static struct attribute *attrs[] = {
+ &trigger_attribute.attr,
+ NULL,
+};
+
+static struct attribute_group attr_group = {
+ .attrs = attrs,
+};
+
+static struct kobject *preemptirq_delay_kobj;
+
+static int __init preemptirq_delay_init(void)
+{
+ struct task_struct *test_task;
+ int retval;
+
+ test_task = preemptirq_start_test();
+ retval = PTR_ERR_OR_ZERO(test_task);
+ if (retval != 0)
+ return retval;
+
+ preemptirq_delay_kobj = kobject_create_and_add("preemptirq_delay_test",
+ kernel_kobj);
+ if (!preemptirq_delay_kobj)
+ return -ENOMEM;
+
+ retval = sysfs_create_group(preemptirq_delay_kobj, &attr_group);
+ if (retval)
+ kobject_put(preemptirq_delay_kobj);

- test_task = kthread_run(preemptirq_delay_run, NULL, task_name);
- return PTR_ERR_OR_ZERO(test_task);
+ return retval;
}

static void __exit preemptirq_delay_exit(void)
{
- return;
+ kobject_put(preemptirq_delay_kobj);
}

module_init(preemptirq_delay_init)
--
2.17.1


2019-09-04 11:43:50

by Steven Rostedt

[permalink] [raw]
Subject: Re: [PATCH v5 2/4] preemptirq_delay_test: Add the burst feature and a sysfs trigger

On Tue, 3 Sep 2019 15:26:00 +0200
Viktor Rosendahl <[email protected]> wrote:
> diff --git a/kernel/trace/preemptirq_delay_test.c b/kernel/trace/preemptirq_delay_test.c
> index d8765c952fab..dc281fa75198 100644
> --- a/kernel/trace/preemptirq_delay_test.c
> +++ b/kernel/trace/preemptirq_delay_test.c
> @@ -3,6 +3,7 @@
> * Preempt / IRQ disable delay thread to test latency tracers
> *
> * Copyright (C) 2018 Joel Fernandes (Google) <[email protected]>
> + * Copyright (C) 2018, 2019 BMW Car IT GmbH

A name and what you did should also be attached here. Ideally, we leave
these out as git history is usually enough.

-- Steve

> */
>
> #include <linux/trace_clock.h>
> @@ -10,18 +11,25 @@
> #include <linux/interrupt.h>
> #include <linux/irq.h>
> #include <linux/kernel.h>
> +#include <linux/kobject.h>
> #include <linux/kthread.h>
> #include <linux/module.h>
> #include <linux/printk.h>
> #include <linux/string.h>
> +#include <linux/sysfs.h>
>
>

2019-09-04 19:11:53

by Viktor Rosendahl

[permalink] [raw]
Subject: Re: [PATCH v5 2/4] preemptirq_delay_test: Add the burst feature and a sysfs trigger

On 9/4/19 1:42 PM, Steven Rostedt wrote:
> On Tue, 3 Sep 2019 15:26:00 +0200
> Viktor Rosendahl <[email protected]> wrote:
>> diff --git a/kernel/trace/preemptirq_delay_test.c b/kernel/trace/preemptirq_delay_test.c
>> index d8765c952fab..dc281fa75198 100644
>> --- a/kernel/trace/preemptirq_delay_test.c
>> +++ b/kernel/trace/preemptirq_delay_test.c
>> @@ -3,6 +3,7 @@
>> * Preempt / IRQ disable delay thread to test latency tracers
>> *
>> * Copyright (C) 2018 Joel Fernandes (Google) <[email protected]>
>> + * Copyright (C) 2018, 2019 BMW Car IT GmbH
>
> A name and what you did should also be attached here. Ideally, we leave
> these out as git history is usually enough.

I am not so keen to clutter source files with a new copyright message.
My problem is that git-send-email doesn't work well with my work email
address, so I am forced to use my private gmail, which may create a
false impression that I as a private individual would be the copyright
holder.

best regards,

Viktor

2019-09-06 00:06:53

by Steven Rostedt

[permalink] [raw]
Subject: Re: [PATCH v5 2/4] preemptirq_delay_test: Add the burst feature and a sysfs trigger

On Wed, 4 Sep 2019 21:10:38 +0200
Viktor Rosendahl <[email protected]> wrote:

> On 9/4/19 1:42 PM, Steven Rostedt wrote:
> > On Tue, 3 Sep 2019 15:26:00 +0200
> > Viktor Rosendahl <[email protected]> wrote:
> >> diff --git a/kernel/trace/preemptirq_delay_test.c b/kernel/trace/preemptirq_delay_test.c
> >> index d8765c952fab..dc281fa75198 100644
> >> --- a/kernel/trace/preemptirq_delay_test.c
> >> +++ b/kernel/trace/preemptirq_delay_test.c
> >> @@ -3,6 +3,7 @@
> >> * Preempt / IRQ disable delay thread to test latency tracers
> >> *
> >> * Copyright (C) 2018 Joel Fernandes (Google) <[email protected]>
> >> + * Copyright (C) 2018, 2019 BMW Car IT GmbH
> >
> > A name and what you did should also be attached here. Ideally, we leave
> > these out as git history is usually enough.
>
> I am not so keen to clutter source files with a new copyright message.
> My problem is that git-send-email doesn't work well with my work email
> address, so I am forced to use my private gmail, which may create a
> false impression that I as a private individual would be the copyright
> holder.
>

Then do what I do:

Steven Rostedt (VMware) <[email protected]>

I did "(Red Hat)" when I worked for Red Hat.

-- Steve

2019-09-06 02:21:08

by Viktor Rosendahl

[permalink] [raw]
Subject: Re: [PATCH v5 2/4] preemptirq_delay_test: Add the burst feature and a sysfs trigger

On 9/5/19 6:52 PM, Steven Rostedt wrote:
> On Wed, 4 Sep 2019 21:10:38 +0200
> Viktor Rosendahl <[email protected]> wrote:
>
>> On 9/4/19 1:42 PM, Steven Rostedt wrote:
>>
>> I am not so keen to clutter source files with a new copyright message.
>> My problem is that git-send-email doesn't work well with my work email
>> address, so I am forced to use my private gmail, which may create a
>> false impression that I as a private individual would be the copyright
>> holder.
>>
>
> Then do what I do:
>
> Steven Rostedt (VMware) <[email protected]>
>
> I did "(Red Hat)" when I worked for Red Hat.
>
> -- Steve
>

Ok, that seems simple and effective. I will update accordingly for v7 of
the patches.

best regards,

Viktor