Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp6499979yba; Wed, 1 May 2019 13:38:18 -0700 (PDT) X-Google-Smtp-Source: APXvYqxkb4heFT1q5MpJNDUWJSy6NcDh1/+VL1d/NKHib7gp95s/bbSihJ1NQ0DkvIBM0hk/MXMl X-Received: by 2002:a17:902:8e8b:: with SMTP id bg11mr14240875plb.281.1556743098789; Wed, 01 May 2019 13:38:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1556743098; cv=none; d=google.com; s=arc-20160816; b=0s0aU8AFg+KEc1jYHyw+U16tkBhzjOttT0BbI9eg4Y0bkdVqFCOQrzq2sDH6OzQiyy vrVxuZpvfYufYBitQed8yoULADBS7H973i88ibWswkF2bDg2Qqc2RVSb8qrbaXdlKP2D lL29XmJDYJvWD70JqyleVJycoJHK0sCvZr3xBoYxosTQyNVxvBCm01HLrrqLokmm0Ti+ qmRmg8JgI/200HqXJzR4fkqL8aosBuIwhVRHVbVj/jPnrbInbFp2zqcWPBwnlUdg3lM3 jW30PoO5HNQbORGcsmK/WzwiSvNM989SSoa2NJdxGMjczPWlF27F5q3GlMbInGQEvZue kGcQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=3zIAKpFfXPkXqRz5OrRs3k5HritCnvTMh+/IiInNaVk=; b=OEff+z/Vuyh0mKGuu+7ZWiUVbi6OE6Rmz4s7TXGPn65x2SVSTdaz0l5NQ7ZFyNQi79 Y9PxvlEUl2T8FY4EBiY4wURRnextlyRsRIXNpkKrrPr3urI5grM/SVb4MVOGfFu6fotH 0aaPqThD5uz+N1v3ygweVrwbrqw3iBguiBj6+9dMNJU+phim2DxYOGtVSfrJoNdvCw1S XyHmxUcZ48uv8Zk6iie9j7s2LSOSBSqp0ljoqrkgpYLTnAgSinwGnE6uQi1Lr8psuKnO LLVr97SwBbZqgjLO2pA8asrryuTUDTCNPDoJAD6TvB2yQGHBHW/CHXHSdJJFMs48SFZN kcwA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=WU3EDWzr; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z29si9971612pgl.584.2019.05.01.13.38.03; Wed, 01 May 2019 13:38:18 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=WU3EDWzr; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726175AbfEAUhE (ORCPT + 99 others); Wed, 1 May 2019 16:37:04 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:39687 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726173AbfEAUhD (ORCPT ); Wed, 1 May 2019 16:37:03 -0400 Received: by mail-io1-f65.google.com with SMTP id c3so130108iok.6 for ; Wed, 01 May 2019 13:37:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3zIAKpFfXPkXqRz5OrRs3k5HritCnvTMh+/IiInNaVk=; b=WU3EDWzrKPd8bv5M9R2EmAJo+tuQeQfxsPd/zkBzzTFPbnFAKtJEBcTTgVdStqwkq/ tJbXmkjQ6n9eMjakSPQVs65e7nswhRIT1ApRhKA9VBrE4RsLm+DOma75Xh8Wf+0k9wS5 DjbtXAvU75Jd99XdJfAr9BSmFTG0eSODaXGCCbjB/IamS/NDPypzban3QtGyWZ7E2+Ci sJ0PLQKVvByZfySNTBYxqHtg9wOlJwiLhh5HWB+ybpuivLweRCc9ovHzYyMN5a1gnFnb ABxrGp72ww8JjXvPXc/ruXO42Q5V5HQsZdHmILBVi6JV2PIR9MMjXlw6HVmg3ao4+ve5 9O1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3zIAKpFfXPkXqRz5OrRs3k5HritCnvTMh+/IiInNaVk=; b=iiIvaqdqJcq0yEMMCehK4J73jzbHwnKi8FuhK3geiTo0EIcYwDIRYE4PzeGmE2AiV9 yTV9b4ZznBi6gfIBTR7k+VqQh+72haq3DVizIvM8LMLIpK8lP+eFCvPo51vyyZNTWiVd aqs1mftumFGI/aAiZWganH2Fv/PGM6vTKiTWdb8wsO1Q+t4WYyTEzViIFxUFx/63xqRr 1e0zA2BrEf7SGBUW3V5ztOc5cqmwG0TapfNohrXfDz5sJimyr99EK4R6TWUk52s49N2j A3vgug/F1lTL9N48HXJBUd6cTNa2E4ULyvw3phWs/gtBBN4lhAwXoKfT1UMNzN/n3P58 UckQ== X-Gm-Message-State: APjAAAWuQcMHQW4wmRO9vg5+HwsyGu0yuS3xShSs5OkSeH1DKG+K46na P+pmRBvfixTeBNBUok+4sg== X-Received: by 2002:a6b:c38d:: with SMTP id t135mr17799785iof.284.1556743021797; Wed, 01 May 2019 13:37:01 -0700 (PDT) Received: from localhost.localdomain ([92.117.183.162]) by smtp.gmail.com with ESMTPSA id u16sm9323998iol.66.2019.05.01.13.36.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 01 May 2019 13:37:01 -0700 (PDT) From: Viktor Rosendahl To: Steven Rostedt , Ingo Molnar , linux-kernel@vger.kernel.org Cc: Joel Fernandes , Viktor Rosendahl Subject: [PATCH v2 2/4] preemptirq_delay_test: Add the burst feature and a sysfs trigger Date: Wed, 1 May 2019 22:36:48 +0200 Message-Id: <20190501203650.29548-3-viktor.rosendahl@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190501203650.29548-1-viktor.rosendahl@gmail.com> References: <20190501203650.29548-1-viktor.rosendahl@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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 35e5fd3224f6..e5e8f2a0199e 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -750,9 +750,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) + * Copyright (C) 2018, 2019 BMW Car IT GmbH */ #include @@ -10,18 +11,25 @@ #include #include #include +#include #include #include #include #include +#include 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