Received: by 2002:a05:6500:1b41:b0:1fb:d597:ff75 with SMTP id cz1csp156777lqb; Tue, 4 Jun 2024 07:49:33 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVSHsFNptXFf8+HSB0m4R15RM1pvTV//Vuj1ZrjYDriFAzn8D1hFrKK9d4Kvbm7Xk5bom9cQnrFBdFrhNis8ET1K3CgI1Gjbp7Sxh16Fg== X-Google-Smtp-Source: AGHT+IFfvS114DOX7JhQl9GHo5DK5nLi4r99gN5nT2miWj7ueJarrdZYmtKMBz5uKqAJNxrhIs9K X-Received: by 2002:a17:907:91d7:b0:a68:b432:6220 with SMTP id a640c23a62f3a-a68b432632cmr657227066b.73.1717512573218; Tue, 04 Jun 2024 07:49:33 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1717512573; cv=pass; d=google.com; s=arc-20160816; b=SPXMRzHRclp1sbH7ldKZfnMkte6RgW3Ao2Z7EGfAPP7ICXngX/EoTNofF3B24AxcMc rzSvsEgTTRA+BShd0h4fOClW50NatdGK3FmlKMYNnSMETeHkZqJX+UQV0jE8jckfqj5j U2XudT83Ov0VBgMXiPoOAAMRJupHkpVGTbsfkayhX7N5ZacKkq9lshyWaeHyPIlpBJyQ vdiTpfUOIg8s3QKIsU7xiU45/6YOEYf6WIJYVi7BzBqIftzcwc6+Sz9hQ5CMCZhCmfoW 7r8yQ/e3zeCla8/ZZhPmwUqTPqKRmquSvhbYd1icBnHBZhPfV+u/nM1rIoPUCgjLOjON vRqg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:list-unsubscribe:list-subscribe:list-id:precedence :references:subject:cc:to:from:date:user-agent:message-id; bh=6ytyA5yxYex4A3Y0vuwv06d7tdl5Tqzl9dbelx1ihLw=; fh=/wy5e/q+z2qlOMkv0QH/u80KV4ZXPtz68q6c1OyjqGY=; b=ULjUTALHexJc1MgBV96G2PULOCUvtVU6CS9QWdt7IO3/AkeHzEFYLfd7rKQf+GTiCb U0FBVItgn2VteHqs6CwTxtov8ZlAiD27RCAzyPOFsvLICvpwYFuyvfi5oMv6C487vsoI clFiSWY95zRu0MGwSwPVyFh5684GZRcOCUzozOcNMPb10sDdyv4rewkT3Jpjv3ld8RJ3 EFC6I94NU0TYI7eIlSoL54vWwENBTq0E2edFOqhe8Xkvy8lCMY0gbOAqprK07EjcgNiX 1PIUktQazVOPazts/1w2Lj3+pfA5a14+DcykxtlQUzo/1EOnL6YoBdJKo6kyTu6mEwL7 0G1w==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1); spf=pass (google.com: domain of linux-kernel+bounces-200886-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-200886-linux.lists.archive=gmail.com@vger.kernel.org" Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id a640c23a62f3a-a68a9fdf9f0si406269166b.222.2024.06.04.07.49.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jun 2024 07:49:33 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-200886-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; arc=pass (i=1); spf=pass (google.com: domain of linux-kernel+bounces-200886-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-200886-linux.lists.archive=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 8826A1F26FA7 for ; Tue, 4 Jun 2024 14:49:32 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9FE2114F120; Tue, 4 Jun 2024 14:42:25 +0000 (UTC) Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0B74514A4DD; Tue, 4 Jun 2024 14:42:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717512139; cv=none; b=CI7XWnsPcPKqSe1CDW7yYsQqtngSYIIE3bALhSo/nKEDrPHR/HbPIcxjIvcK4PbdryxEO22U0Z8eNBv0CL4a+uYpJZiWUkzspWAkLZHdp35xSfZFRNSaSDaqPQYpnbM7K2fVoqSXSrFsO1JqxqiH09N5FvpYcG99mj6TEI34/pk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717512139; c=relaxed/simple; bh=DODPJgC5iTA3XbUH1M3g3CyluOcqeSJmFe7rf8Joak8=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=jqZwdOyi+CYCUE5aoy4IQczzxk0Vrl7j+0O0tgtgjmCbvoMOLoC4quHg/SUeAsHzhItyP/zsxYpRerLfKfjzIUa4AK825EBhTo2rpkdl7cm8vYcYVIQ3lk4zw8hhQxddTID55qi+Wj/XDOoZyqkd/RF4T4+HCh35Z//hfjxw+a8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 42F3EC4AF13; Tue, 4 Jun 2024 14:42:18 +0000 (UTC) Received: from rostedt by gandalf with local (Exim 4.97) (envelope-from ) id 1sEVMf-00000000Z3V-24Ne; Tue, 04 Jun 2024 10:42:17 -0400 Message-ID: <20240604144217.350436921@goodmis.org> User-Agent: quilt/0.68 Date: Tue, 04 Jun 2024 10:41:24 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Alexei Starovoitov , Florent Revest , Martin KaFai Lau , bpf , Sven Schnelle , Alexei Starovoitov , Jiri Olsa , Arnaldo Carvalho de Melo , Daniel Borkmann , Alan Maguire , Peter Zijlstra , Thomas Gleixner , Guo Ren Subject: [for-next][PATCH 21/27] ftrace: Add multiple fgraph storage selftest References: <20240604144103.293353991@goodmis.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 From: "Masami Hiramatsu (Google)" 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 Link: https://lore.kernel.org/linux-trace-kernel/20240603190824.284049716@goodmis.org Cc: Mark Rutland Cc: Mathieu Desnoyers Cc: Andrew Morton Cc: Alexei Starovoitov Cc: Florent Revest Cc: Martin KaFai Lau Cc: bpf Cc: Sven Schnelle Cc: Alexei Starovoitov Cc: Jiri Olsa Cc: Arnaldo Carvalho de Melo Cc: Daniel Borkmann Cc: Alan Maguire Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Guo Ren Reviewed-by: Masami Hiramatsu (Google) Signed-off-by: Masami Hiramatsu (Google) Suggested-by: Steven Rostedt (Google) Signed-off-by: Steven Rostedt (Google) --- 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