From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org
Cc: Masami Hiramatsu <mhiramat@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Andrew Morton <akpm@linux-foundation.org>,
Alexei Starovoitov <alexei.starovoitov@gmail.com>,
Florent Revest <revest@chromium.org>,
Martin KaFai Lau <martin.lau@linux.dev>,
bpf <bpf@vger.kernel.org>, Sven Schnelle <svens@linux.ibm.com>,
Alexei Starovoitov <ast@kernel.org>, Jiri Olsa <jolsa@kernel.org>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Alan Maguire <alan.maguire@oracle.com>,
Peter Zijlstra <peterz@infradead.org>,
Thomas Gleixner <tglx@linutronix.de>, Guo Ren <guoren@kernel.org>
Subject: [PATCH v3 21/27] ftrace: Add multiple fgraph storage selftest
Date: Mon, 03 Jun 2024 15:07:25 -0400 [thread overview]
Message-ID: <20240603190824.284049716@goodmis.org> (raw)
In-Reply-To: 20240603190704.663840775@goodmis.org
From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
Add a selftest for multiple function graph tracer with storage on a same
function. In this case, the shadow stack entry will be shared among those
fgraph with different data storage. So this will ensure the fgraph will
not mixed those storage data.
Link: https://lore.kernel.org/linux-trace-kernel/171509111465.162236.3795819216426570800.stgit@devnote2
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Suggested-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
kernel/trace/trace_selftest.c | 171 +++++++++++++++++++++++++---------
1 file changed, 126 insertions(+), 45 deletions(-)
diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
index fcdc744c245e..369efc569238 100644
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -762,28 +762,32 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
#define SHORT_NUMBER 12345
#define WORD_NUMBER 1234567890
#define LONG_NUMBER 1234567890123456789LL
-
-static int fgraph_store_size __initdata;
-static const char *fgraph_store_type_name __initdata;
-static char *fgraph_error_str __initdata;
-static char fgraph_error_str_buf[128] __initdata;
+#define ERRSTR_BUFLEN 128
+
+struct fgraph_fixture {
+ struct fgraph_ops gops;
+ int store_size;
+ const char *store_type_name;
+ char error_str_buf[ERRSTR_BUFLEN];
+ char *error_str;
+};
static __init int store_entry(struct ftrace_graph_ent *trace,
struct fgraph_ops *gops)
{
- const char *type = fgraph_store_type_name;
- int size = fgraph_store_size;
+ struct fgraph_fixture *fixture = container_of(gops, struct fgraph_fixture, gops);
+ const char *type = fixture->store_type_name;
+ int size = fixture->store_size;
void *p;
p = fgraph_reserve_data(gops->idx, size);
if (!p) {
- snprintf(fgraph_error_str_buf, sizeof(fgraph_error_str_buf),
+ snprintf(fixture->error_str_buf, ERRSTR_BUFLEN,
"Failed to reserve %s\n", type);
- fgraph_error_str = fgraph_error_str_buf;
return 0;
}
- switch (fgraph_store_size) {
+ switch (size) {
case 1:
*(char *)p = BYTE_NUMBER;
break;
@@ -804,7 +808,8 @@ static __init int store_entry(struct ftrace_graph_ent *trace,
static __init void store_return(struct ftrace_graph_ret *trace,
struct fgraph_ops *gops)
{
- const char *type = fgraph_store_type_name;
+ struct fgraph_fixture *fixture = container_of(gops, struct fgraph_fixture, gops);
+ const char *type = fixture->store_type_name;
long long expect = 0;
long long found = -1;
int size;
@@ -812,20 +817,18 @@ static __init void store_return(struct ftrace_graph_ret *trace,
p = fgraph_retrieve_data(gops->idx, &size);
if (!p) {
- snprintf(fgraph_error_str_buf, sizeof(fgraph_error_str_buf),
+ snprintf(fixture->error_str_buf, ERRSTR_BUFLEN,
"Failed to retrieve %s\n", type);
- fgraph_error_str = fgraph_error_str_buf;
return;
}
- if (fgraph_store_size > size) {
- snprintf(fgraph_error_str_buf, sizeof(fgraph_error_str_buf),
+ if (fixture->store_size > size) {
+ snprintf(fixture->error_str_buf, ERRSTR_BUFLEN,
"Retrieved size %d is smaller than expected %d\n",
- size, (int)fgraph_store_size);
- fgraph_error_str = fgraph_error_str_buf;
+ size, (int)fixture->store_size);
return;
}
- switch (fgraph_store_size) {
+ switch (fixture->store_size) {
case 1:
expect = BYTE_NUMBER;
found = *(char *)p;
@@ -845,45 +848,44 @@ static __init void store_return(struct ftrace_graph_ret *trace,
}
if (found != expect) {
- snprintf(fgraph_error_str_buf, sizeof(fgraph_error_str_buf),
+ snprintf(fixture->error_str_buf, ERRSTR_BUFLEN,
"%s returned not %lld but %lld\n", type, expect, found);
- fgraph_error_str = fgraph_error_str_buf;
return;
}
- fgraph_error_str = NULL;
+ fixture->error_str = NULL;
}
-static struct fgraph_ops store_bytes __initdata = {
- .entryfunc = store_entry,
- .retfunc = store_return,
-};
-
-static int __init test_graph_storage_type(const char *name, int size)
+static int __init init_fgraph_fixture(struct fgraph_fixture *fixture)
{
char *func_name;
int len;
- int ret;
- fgraph_store_type_name = name;
- fgraph_store_size = size;
+ snprintf(fixture->error_str_buf, ERRSTR_BUFLEN,
+ "Failed to execute storage %s\n", fixture->store_type_name);
+ fixture->error_str = fixture->error_str_buf;
- snprintf(fgraph_error_str_buf, sizeof(fgraph_error_str_buf),
- "Failed to execute storage %s\n", name);
- fgraph_error_str = fgraph_error_str_buf;
+ func_name = "*" __stringify(DYN_FTRACE_TEST_NAME);
+ len = strlen(func_name);
+
+ return ftrace_set_filter(&fixture->gops.ops, func_name, len, 1);
+}
+
+/* Test fgraph storage for each size */
+static int __init test_graph_storage_single(struct fgraph_fixture *fixture)
+{
+ int size = fixture->store_size;
+ int ret;
pr_cont("PASSED\n");
pr_info("Testing fgraph storage of %d byte%s: ", size, size > 1 ? "s" : "");
- func_name = "*" __stringify(DYN_FTRACE_TEST_NAME);
- len = strlen(func_name);
-
- ret = ftrace_set_filter(&store_bytes.ops, func_name, len, 1);
+ ret = init_fgraph_fixture(fixture);
if (ret && ret != -ENODEV) {
pr_cont("*Could not set filter* ");
return -1;
}
- ret = register_ftrace_graph(&store_bytes);
+ ret = register_ftrace_graph(&fixture->gops);
if (ret) {
pr_warn("Failed to init store_bytes fgraph tracing\n");
return -1;
@@ -891,30 +893,109 @@ static int __init test_graph_storage_type(const char *name, int size)
DYN_FTRACE_TEST_NAME();
- unregister_ftrace_graph(&store_bytes);
+ unregister_ftrace_graph(&fixture->gops);
- if (fgraph_error_str) {
- pr_cont("*** %s ***", fgraph_error_str);
+ if (fixture->error_str) {
+ pr_cont("*** %s ***", fixture->error_str);
return -1;
}
return 0;
}
+
+static struct fgraph_fixture store_bytes[4] __initdata = {
+ [0] = {
+ .gops = {
+ .entryfunc = store_entry,
+ .retfunc = store_return,
+ },
+ .store_size = 1,
+ .store_type_name = "byte",
+ },
+ [1] = {
+ .gops = {
+ .entryfunc = store_entry,
+ .retfunc = store_return,
+ },
+ .store_size = 2,
+ .store_type_name = "short",
+ },
+ [2] = {
+ .gops = {
+ .entryfunc = store_entry,
+ .retfunc = store_return,
+ },
+ .store_size = 4,
+ .store_type_name = "word",
+ },
+ [3] = {
+ .gops = {
+ .entryfunc = store_entry,
+ .retfunc = store_return,
+ },
+ .store_size = 8,
+ .store_type_name = "long long",
+ },
+};
+
+static __init int test_graph_storage_multi(void)
+{
+ struct fgraph_fixture *fixture;
+ bool printed = false;
+ int i, ret;
+
+ pr_cont("PASSED\n");
+ pr_info("Testing multiple fgraph storage on a function: ");
+
+ for (i = 0; i < ARRAY_SIZE(store_bytes); i++) {
+ fixture = &store_bytes[i];
+ ret = init_fgraph_fixture(fixture);
+ if (ret && ret != -ENODEV) {
+ pr_cont("*Could not set filter* ");
+ printed = true;
+ goto out;
+ }
+
+ ret = register_ftrace_graph(&fixture->gops);
+ if (ret) {
+ pr_warn("Failed to init store_bytes fgraph tracing\n");
+ printed = true;
+ goto out;
+ }
+ }
+
+ DYN_FTRACE_TEST_NAME();
+out:
+ while (--i >= 0) {
+ fixture = &store_bytes[i];
+ unregister_ftrace_graph(&fixture->gops);
+
+ if (fixture->error_str && !printed) {
+ pr_cont("*** %s ***", fixture->error_str);
+ printed = true;
+ }
+ }
+ return printed ? -1 : 0;
+}
+
/* Test the storage passed across function_graph entry and return */
static __init int test_graph_storage(void)
{
int ret;
- ret = test_graph_storage_type("byte", 1);
+ ret = test_graph_storage_single(&store_bytes[0]);
+ if (ret)
+ return ret;
+ ret = test_graph_storage_single(&store_bytes[1]);
if (ret)
return ret;
- ret = test_graph_storage_type("short", 2);
+ ret = test_graph_storage_single(&store_bytes[2]);
if (ret)
return ret;
- ret = test_graph_storage_type("word", 4);
+ ret = test_graph_storage_single(&store_bytes[3]);
if (ret)
return ret;
- ret = test_graph_storage_type("long long", 8);
+ ret = test_graph_storage_multi();
if (ret)
return ret;
return 0;
--
2.43.0
next prev parent reply other threads:[~2024-06-03 19:07 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-03 19:07 [PATCH v3 00/27] function_graph: Allow multiple users for function graph tracing Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 01/27] function_graph: Convert ret_stack to a series of longs Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 02/27] fgraph: Use BUILD_BUG_ON() to make sure we have structures divisible by long Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 03/27] function_graph: Add an array structure that will allow multiple callbacks Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 04/27] function_graph: Allow multiple users to attach to function graph Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 05/27] function_graph: Handle tail calls for stack unwinding Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 06/27] function_graph: Remove logic around ftrace_graph_entry and return Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 07/27] ftrace/function_graph: Pass fgraph_ops to function graph callbacks Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 08/27] ftrace: Allow function_graph tracer to be enabled in instances Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 09/27] ftrace: Allow ftrace startup flags to exist without dynamic ftrace Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 10/27] ftrace: Add subops logic to allow one ops to manage many Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 11/27] ftrace: Allow subops filtering to be modified Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 12/27] function_graph: Have the instances use their own ftrace_ops for filtering Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 13/27] function_graph: Add pid tracing back to function graph tracer Steven Rostedt
2024-06-06 0:08 ` Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 14/27] function_graph: Use a simple LRU for fgraph_array index number Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 15/27] function_graph: Add "task variables" per task for fgraph_ops Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 16/27] function_graph: Move set_graph_function tests to shadow stack global var Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 17/27] function_graph: Move graph depth stored data " Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 18/27] function_graph: Move graph notrace bit " Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 19/27] function_graph: Implement fgraph_reserve_data() and fgraph_retrieve_data() Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 20/27] function_graph: Add selftest for passing local variables Steven Rostedt
2024-06-03 19:07 ` Steven Rostedt [this message]
2024-06-03 19:07 ` [PATCH v3 22/27] function_graph: Use for_each_set_bit() in __ftrace_return_to_handler() Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 23/27] function_graph: Use bitmask to loop on fgraph entry Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 24/27] function_graph: Use static_call and branch to optimize entry function Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 25/27] function_graph: Use static_call and branch to optimize return function Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 26/27] selftests/ftrace: Add function_graph tracer to func-filter-pid test Steven Rostedt
2024-06-03 19:07 ` [PATCH v3 27/27] selftests/ftrace: Add fgraph-multi.tc test Steven Rostedt
2024-06-04 12:18 ` [PATCH v3 00/27] function_graph: Allow multiple users for function graph tracing Steven Rostedt
2024-06-04 14:23 ` Masami Hiramatsu
2024-06-04 14:44 ` Mark Rutland
2024-06-04 16:31 ` Steven Rostedt
2024-06-04 17:04 ` Mark Rutland
2024-06-04 18:57 ` Steven Rostedt
2024-06-04 19:18 ` Steven Rostedt
2024-06-05 14:07 ` Mark Rutland
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=20240603190824.284049716@goodmis.org \
--to=rostedt@goodmis.org \
--cc=acme@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=alan.maguire@oracle.com \
--cc=alexei.starovoitov@gmail.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=guoren@kernel.org \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=martin.lau@linux.dev \
--cc=mathieu.desnoyers@efficios.com \
--cc=mhiramat@kernel.org \
--cc=peterz@infradead.org \
--cc=revest@chromium.org \
--cc=svens@linux.ibm.com \
--cc=tglx@linutronix.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox