From patchwork Sun Feb 25 15:18:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Masami Hiramatsu (Google)" X-Patchwork-Id: 206061 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp1621625dyb; Sun, 25 Feb 2024 07:20:40 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVjndkn9Oc7xlcJ8EBzuQBh+7/kRLulXjb+uTjsH4Yx5Hy1hNjzcTpAJtbLpmZz29W3iZr3ELd9oeVeo0TRMWkFwmxdyw== X-Google-Smtp-Source: AGHT+IHOJPQS0MCaJnZGFmGyzn2UzuhLAX1GPfXW1fGB0XKenjQYyaQ8P8mtVk9WBNzo7LgUpF5a X-Received: by 2002:a05:6512:46c:b0:512:db3f:436 with SMTP id x12-20020a056512046c00b00512db3f0436mr2774545lfd.36.1708874440626; Sun, 25 Feb 2024 07:20:40 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708874440; cv=pass; d=google.com; s=arc-20160816; b=w5KNxZh9FRFvUcwwABrPTxoo59oTDbMrlsTDW9S/HfcvMI23IP4HvzV0VTsCzyrBi0 n6dnC/rrnaAv9Uie85uGsEjDJIs8oLm+Q+kJyPvYhgDn4lAUZ2h8H7zFvknKr9KlwV5t ONqd5GgRrDiaqWsjlEoxuNa4AwMrlI9tQ7d4UAVIPpCZWGbBXCkXbhjTST/Zpv7QfERz dRw0VU1BSP3GJycronv4e+TrDvNZoaPaSguCMoy+ljUdICAewlDQ3bB/rpaqKADNxjjS fb3g5cPI9y+qbxdjAZpcw/UuuAiP0wWac6HwwpAcX1WIzlswcvatmdCqHhWLA1pC7/mz Xb0A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:user-agent:references:in-reply-to :message-id:date:subject:cc:to:from:dkim-signature; bh=ySGEbW/HT2pFbxuMPF7e8gDTzeMpu8m1uMxfjPZdL4A=; fh=SIgps5XdV0XNwjZfT2uAI7g3mrspDldK9Qs8qQAfoa4=; b=O8psjGnZ5FMknzxOewj0DNBJUmPNEcKIxaqgqXVpSWLL9aEZpDp3RDPf6PwS8oei4k g/2hXb7/WDbzsx9wXGOub688MSjp9HXQs0TW+UfmWZK4bJOgK8RngsPC1vgrC4T7F7LO g0cKXXYS2LAmYaKWubdSBbfzoaLaNhQRrP4fmXTzv09UxCFiVSGb220EtrLVrqoX+Nh0 iygl7iIUcpgdJ/SPfByAVY4NDNuhXcEq2KRT2LDndbV+2kE0aDMO6F7dUtqv8RTuBynL lAjT98mo03eoEzqq2owLW51q6uOHoltK/oAN42VtfF/sdsUbG3tT4QxBXer6axmULMyf lBRg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=qffAzJkG; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-80148-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-80148-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id e11-20020a170906248b00b00a4300440af8si1037867ejb.135.2024.02.25.07.20.40 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Feb 2024 07:20:40 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-80148-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=qffAzJkG; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-80148-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-80148-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=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 18E401F219AD for ; Sun, 25 Feb 2024 15:20:40 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9932F1B977; Sun, 25 Feb 2024 15:18:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="qffAzJkG" 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 0EB901B956; Sun, 25 Feb 2024 15:18:46 +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=1708874327; cv=none; b=VLwN47CO3Le3Mmi80ohXPIFZZJ1B6QFcXYQ/Qpbw/xGHV5JWAU7Ea9VEgX8YYGELt/jccB9oBBSqeyWpzlIRHjjqrsnbDeywBpTuQnHTZZBrXglmfHUMzD+lzU+p/8FFA7LoZDG6fhIPqQBz2oH+QcDJcPG1P6sVthMxtZ9IJ4E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708874327; c=relaxed/simple; bh=OI14DCdYU06rheNefUFi3hlSeUEDnhHm2BLTTP7W5co=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=hi0LKSjzR40emovteonUjJ6Ij3v54vaWeJDOwVi6qmH2N9r6MA97WeqtaQYcSt5DKT9EtOpIDmVnGyH9LH9b6DsiJB7rWhzY1UkOqfwX8m3Ds7cAN06PchMq5BRKG0kRF+THWJPz6gmoRRfpkNhHomz2rL4RwllBnQCh9fDTwzg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qffAzJkG; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id D77F3C433C7; Sun, 25 Feb 2024 15:18:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708874326; bh=OI14DCdYU06rheNefUFi3hlSeUEDnhHm2BLTTP7W5co=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qffAzJkGdy95HteKBBv6kSWnmNan0rnQry34pK8tjTT27iKvqhxhPtHLXMpcEtw3x xz9XAOsQvIYG6oGzCPc+LE+hKZgVNLPYx+Klvj43rOlNLePt9shgm6iwoQa9s69ahQ k2ZO9QiowG27iXYbU6q81YBFZ8mtizReakUovbwPJJZWnYNuLGS13CHSgO1l7o9Zz6 bwCtet7dz1MyBG+5BjndaK21erpKcYjHCL+qAJJvyEDJAIbnr0yOFmbKKoLE286SJH HCgQReqdJHs2v3aKZaBc97qpBSjNcSeze017eakn9bhhvTN3+6n0wOfYaoegwwdbAN yZhmcbGTcNfRg== From: "Masami Hiramatsu (Google)" To: Alexei Starovoitov , Steven Rostedt , Florent Revest Cc: linux-trace-kernel@vger.kernel.org, LKML , Martin KaFai Lau , bpf , Sven Schnelle , Alexei Starovoitov , Jiri Olsa , Arnaldo Carvalho de Melo , Daniel Borkmann , Alan Maguire , Mark Rutland , Peter Zijlstra , Thomas Gleixner , Guo Ren Subject: [PATCH v8 20/35] ftrace: Add multiple fgraph storage selftest Date: Mon, 26 Feb 2024 00:18:41 +0900 Message-Id: <170887432173.564249.6935140706767509870.stgit@devnote2> X-Mailer: git-send-email 2.34.1 In-Reply-To: <170887410337.564249.6360118840946697039.stgit@devnote2> References: <170887410337.564249.6360118840946697039.stgit@devnote2> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791884725281084068 X-GMAIL-MSGID: 1791884725281084068 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. Signed-off-by: Masami Hiramatsu (Google) Suggested-by: Steven Rostedt (Google) --- Changes in v8: - Newly added. --- 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 4d86cd4c8c8c..ca1687b274bc 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;