From patchwork Wed Dec 13 00:13:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490186 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fS+oYds8" Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88CED92; Tue, 12 Dec 2023 16:13:28 -0800 (PST) Received: by mail-pj1-x102e.google.com with SMTP id 98e67ed59e1d1-28ad44e5d5aso834353a91.3; Tue, 12 Dec 2023 16:13:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426408; x=1703031208; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=lG5uhH6+vrhrt8eFk+mi+3iC/XTE/ZNynaN3tsBSr8c=; b=fS+oYds8KN2olU1eUM/RQgGaaU3g6FSgRAJ7Vh2kHCJGnCdQ1krBSVwXn/p2Didg55 fAtrgvCuw2GuEGFga0W20xdoqM7HO29vnL6kNAwNv+JYLs4p3bVvZtl+bKb3XOq7EvN8 13XEYn/gF3zTWjBj6xUlz336yg9LdXV5pXDiGMDl+w17FLjSEcqjCM/R04tvDXiKGUoL ofSMdVXS9wyk1nImv2pLFKLcKEHuhkLTAd9A5/rxsM0qCIkcIWP6lB05XZcOfRR5vZpD jecYzl7J+/SPGXPg1UmcKSJ8kiSoZEvt/ctfmek7LhhVYDu2FWq3W41/ANVF6FnMljrl ZOwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426408; x=1703031208; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=lG5uhH6+vrhrt8eFk+mi+3iC/XTE/ZNynaN3tsBSr8c=; b=QT225El6+mVi1oyYJkdqtFTHk0bsP09FUBXFsXtpvdjzzr+8iEPUzOHMRdZc5D1WpX sh8NNOhCAuZsQOYUt+lQ/9eALTMPeu9++9Im3aFQSxYyTjEtgFnChDNHg8AatxpBcKNo 9BEKg4qmmMlGWy1g5aqewayp5VGvwvWee1wN9sqLv8PIz0OPGILb7ZCQ1L/S61Y6+kYt ufm8tEK1FZmy59j4X5i3SFH3HB4hRij3yPiOlA0TtASO4DVkzDH92D21YMS7lSewc29v cPN2A6FP6Rlt0iIcrw8nFVQHXrIdWI9nbVMTkDnVv22s5Yzu8sFcHn/OztG/hK3MHFcF +Kjw== X-Gm-Message-State: AOJu0Yy0Q4HNmFHPfYbI04jqqKceuqq/WjBe1+WP4+ENJMTUcExI5t+V rgV8pqyuR6NqqWwJ+lErelU= X-Google-Smtp-Source: AGHT+IHTA0FcHf41HpX86cu/kMoU8JzP9CdC51uGuAStlcn8QS7QkMFa2VxqMhixXwXv/2MmrrLzMQ== X-Received: by 2002:a17:90b:1213:b0:286:f16c:caff with SMTP id gl19-20020a17090b121300b00286f16ccaffmr5449689pjb.33.1702426407843; Tue, 12 Dec 2023 16:13:27 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:27 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 01/17] perf dwarf-aux: Factor out die_get_typename_from_type() Date: Tue, 12 Dec 2023 16:13:07 -0800 Message-ID: <20231213001323.718046-2-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The die_get_typename_from_type() is to get the name of the given DIE in C-style type name. The difference from the die_get_typename() is that it does not retrieve the DW_AT_type and use the given DIE directly. This will be used when users know the type DIE already. Cc: Masami Hiramatsu Signed-off-by: Namhyung Kim --- tools/perf/util/dwarf-aux.c | 38 ++++++++++++++++++++++++++----------- tools/perf/util/dwarf-aux.h | 3 +++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index edd9e407bc74..7aa5fee0da19 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -1051,32 +1051,28 @@ Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name, } /** - * die_get_typename - Get the name of given variable DIE - * @vr_die: a variable DIE + * die_get_typename_from_type - Get the name of given type DIE + * @type_die: a type DIE * @buf: a strbuf for result type name * - * Get the name of @vr_die and stores it to @buf. Return 0 if succeeded. + * Get the name of @type_die and stores it to @buf. Return 0 if succeeded. * and Return -ENOENT if failed to find type name. * Note that the result will stores typedef name if possible, and stores * "*(function_type)" if the type is a function pointer. */ -int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf) +int die_get_typename_from_type(Dwarf_Die *type_die, struct strbuf *buf) { - Dwarf_Die type; int tag, ret; const char *tmp = ""; - if (__die_get_real_type(vr_die, &type) == NULL) - return -ENOENT; - - tag = dwarf_tag(&type); + tag = dwarf_tag(type_die); if (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type) tmp = "*"; else if (tag == DW_TAG_subroutine_type) { /* Function pointer */ return strbuf_add(buf, "(function_type)", 15); } else { - const char *name = dwarf_diename(&type); + const char *name = dwarf_diename(type_die); if (tag == DW_TAG_union_type) tmp = "union "; @@ -1089,7 +1085,7 @@ int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf) /* Write a base name */ return strbuf_addf(buf, "%s%s", tmp, name ?: ""); } - ret = die_get_typename(&type, buf); + ret = die_get_typename(type_die, buf); if (ret < 0) { /* void pointer has no type attribute */ if (tag == DW_TAG_pointer_type && ret == -ENOENT) @@ -1100,6 +1096,26 @@ int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf) return strbuf_addstr(buf, tmp); } +/** + * die_get_typename - Get the name of given variable DIE + * @vr_die: a variable DIE + * @buf: a strbuf for result type name + * + * Get the name of @vr_die and stores it to @buf. Return 0 if succeeded. + * and Return -ENOENT if failed to find type name. + * Note that the result will stores typedef name if possible, and stores + * "*(function_type)" if the type is a function pointer. + */ +int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf) +{ + Dwarf_Die type; + + if (__die_get_real_type(vr_die, &type) == NULL) + return -ENOENT; + + return die_get_typename_from_type(&type, buf); +} + /** * die_get_varname - Get the name and type of given variable DIE * @vr_die: a variable DIE diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index 0ddf61fd3f8b..4e64caac6df8 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h @@ -116,6 +116,9 @@ Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name, Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name, Dwarf_Die *die_mem); +/* Get the name of given type DIE */ +int die_get_typename_from_type(Dwarf_Die *type_die, struct strbuf *buf); + /* Get the name of given variable DIE */ int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf); From patchwork Wed Dec 13 00:13:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490187 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="AIXJgCZr" Received: from mail-io1-xd2b.google.com (mail-io1-xd2b.google.com [IPv6:2607:f8b0:4864:20::d2b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8C5EDBC; Tue, 12 Dec 2023 16:13:30 -0800 (PST) Received: by mail-io1-xd2b.google.com with SMTP id ca18e2360f4ac-7b7039d30acso365328039f.3; Tue, 12 Dec 2023 16:13:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426410; x=1703031210; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=1yE8tDVZHn5Q5IZE7sgzYyBr3j80GHRhr26uqjreUGM=; b=AIXJgCZrV2whvpPckxYKmj5a7FxRulAE1yMGD1ynu8KZnXITmN269U5oa6s86wHeZk bXvWyeRRv/4o3Q1APWQt97qyY896g/dSM3wXhWGv38r6Hga4208CfC5Xf7cpUF8qruFK Ed7Cdp6g63QifG9DMcyCsrPntHsYt+WRon7gpIrgB9kUykYe91SIwFLzSuXJAavQ33AG NuofKgjHbxrW1Mxoinuv/qvqvmHHKWY6nAUrAokRGvPbpdUkkxS7ttwGvNY/QFXO9DJ6 sAdorHLdeO1k4UO4uEts5NTVenCZo/Fc9LMjZdv+N1HF7G8GZzb9iyymEW8ttF/Vsof0 BCCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426410; x=1703031210; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=1yE8tDVZHn5Q5IZE7sgzYyBr3j80GHRhr26uqjreUGM=; b=G8Ty/AdkU4ZTDtQ6IngdiVRHCVr/OcGCqRqd5HHlD6DM/+v0DxRGAzDtLwtZR3xY/z hnVwHcK2o5BP4SxnQEJXqMc+6luP8obUxcKH9w2gnuk6U5mILpP1yT4S87pC/iMGbMQe +QllHGLA9WZA6MXHbXtZASlgb/oqXjHiT4OQrmoEAa75U5CHEjrdDdpxz8hKJKMOFcK3 8lFnLGCb5grimgaLGszO2XLjnRHAu8cfc9cvu3Px4z1PwrXx+XwxjExXWqOXqqNHCOw/ J+ZptovqUpaK1ENExSN4bxYps913Jo9qiItFfcxfuCeUotMFdbA33KCgcUjYiNMpnDBh gqAg== X-Gm-Message-State: AOJu0YxHnH8yqIwKWhx5lJDiF0rM8hAk8IZnspY7LOh53G3Y3h7Y6TxW iH27W4Gahnjc3xtbS+tY7yA= X-Google-Smtp-Source: AGHT+IHCOUHbghffD9nTh2liqpDCfNSN3Nu/R/yotPPFOFlBFCd5bu6rSoH70raZS37aoXS7kG/nSg== X-Received: by 2002:a05:6e02:ef3:b0:35d:7ce5:3a55 with SMTP id j19-20020a056e020ef300b0035d7ce53a55mr7544753ilk.121.1702426409690; Tue, 12 Dec 2023 16:13:29 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:28 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 02/17] perf dwarf-regs: Add get_dwarf_regnum() Date: Tue, 12 Dec 2023 16:13:08 -0800 Message-ID: <20231213001323.718046-3-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The get_dwarf_regnum() returns a DWARF register number from a register name string according to the psABI. Also add two pseudo encodings of DWARF_REG_PC which is a register that are used by PC-relative addressing and DWARF_REG_FB which is a frame base register. They need to be handled in a special way. Cc: Masami Hiramatsu Signed-off-by: Namhyung Kim --- tools/perf/arch/x86/util/dwarf-regs.c | 38 +++++++++++++++++++++++++++ tools/perf/util/dwarf-regs.c | 34 ++++++++++++++++++++++++ tools/perf/util/include/dwarf-regs.h | 19 ++++++++++++++ 3 files changed, 91 insertions(+) diff --git a/tools/perf/arch/x86/util/dwarf-regs.c b/tools/perf/arch/x86/util/dwarf-regs.c index 530934805710..399c4a0a29d8 100644 --- a/tools/perf/arch/x86/util/dwarf-regs.c +++ b/tools/perf/arch/x86/util/dwarf-regs.c @@ -113,3 +113,41 @@ int regs_query_register_offset(const char *name) return roff->offset; return -EINVAL; } + +struct dwarf_regs_idx { + const char *name; + int idx; +}; + +static const struct dwarf_regs_idx x86_regidx_table[] = { + { "rax", 0 }, { "eax", 0 }, { "ax", 0 }, { "al", 0 }, + { "rdx", 1 }, { "edx", 1 }, { "dx", 1 }, { "dl", 1 }, + { "rcx", 2 }, { "ecx", 2 }, { "cx", 2 }, { "cl", 2 }, + { "rbx", 3 }, { "edx", 3 }, { "bx", 3 }, { "bl", 3 }, + { "rsi", 4 }, { "esi", 4 }, { "si", 4 }, { "sil", 4 }, + { "rdi", 5 }, { "edi", 5 }, { "di", 5 }, { "dil", 5 }, + { "rbp", 6 }, { "ebp", 6 }, { "bp", 6 }, { "bpl", 6 }, + { "rsp", 7 }, { "esp", 7 }, { "sp", 7 }, { "spl", 7 }, + { "r8", 8 }, { "r8d", 8 }, { "r8w", 8 }, { "r8b", 8 }, + { "r9", 9 }, { "r9d", 9 }, { "r9w", 9 }, { "r9b", 9 }, + { "r10", 10 }, { "r10d", 10 }, { "r10w", 10 }, { "r10b", 10 }, + { "r11", 11 }, { "r11d", 11 }, { "r11w", 11 }, { "r11b", 11 }, + { "r12", 12 }, { "r12d", 12 }, { "r12w", 12 }, { "r12b", 12 }, + { "r13", 13 }, { "r13d", 13 }, { "r13w", 13 }, { "r13b", 13 }, + { "r14", 14 }, { "r14d", 14 }, { "r14w", 14 }, { "r14b", 14 }, + { "r15", 15 }, { "r15d", 15 }, { "r15w", 15 }, { "r15b", 15 }, + { "rip", DWARF_REG_PC }, +}; + +int get_arch_regnum(const char *name) +{ + unsigned int i; + + if (*name != '%') + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(x86_regidx_table); i++) + if (!strcmp(x86_regidx_table[i].name, name + 1)) + return x86_regidx_table[i].idx; + return -ENOENT; +} diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c index 69cfaa5953bf..5b7f86c0063f 100644 --- a/tools/perf/util/dwarf-regs.c +++ b/tools/perf/util/dwarf-regs.c @@ -5,9 +5,12 @@ * Written by: Masami Hiramatsu */ +#include +#include #include #include #include +#include #include #ifndef EM_AARCH64 @@ -68,3 +71,34 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine) } return NULL; } + +__weak int get_arch_regnum(const char *name __maybe_unused) +{ + return -ENOTSUP; +} + +/* Return DWARF register number from architecture register name */ +int get_dwarf_regnum(const char *name, unsigned int machine) +{ + char *regname = strdup(name); + int reg = -1; + char *p; + + if (regname == NULL) + return -EINVAL; + + /* For convenience, remove trailing characters */ + p = strpbrk(regname, " ,)"); + if (p) + *p = '\0'; + + switch (machine) { + case EM_NONE: /* Generic arch - use host arch */ + reg = get_arch_regnum(regname); + break; + default: + pr_err("ELF MACHINE %x is not supported.\n", machine); + } + free(regname); + return reg; +} diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h index 7d99a084e82d..01fb25a1150a 100644 --- a/tools/perf/util/include/dwarf-regs.h +++ b/tools/perf/util/include/dwarf-regs.h @@ -2,6 +2,9 @@ #ifndef _PERF_DWARF_REGS_H_ #define _PERF_DWARF_REGS_H_ +#define DWARF_REG_PC 0xd3af9c /* random number */ +#define DWARF_REG_FB 0xd3affb /* random number */ + #ifdef HAVE_DWARF_SUPPORT const char *get_arch_regstr(unsigned int n); /* @@ -10,6 +13,22 @@ const char *get_arch_regstr(unsigned int n); * machine: ELF machine signature (EM_*) */ const char *get_dwarf_regstr(unsigned int n, unsigned int machine); + +int get_arch_regnum(const char *name); +/* + * get_dwarf_regnum - Returns DWARF regnum from register name + * name: architecture register name + * machine: ELF machine signature (EM_*) + */ +int get_dwarf_regnum(const char *name, unsigned int machine); + +#else /* HAVE_DWARF_SUPPORT */ + +static inline int get_dwarf_regnum(const char *name __maybe_unused, + unsigned int machine __maybe_unused) +{ + return -1; +} #endif #ifdef HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET From patchwork Wed Dec 13 00:13:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490188 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="POyDM7Zz" Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 896DE92; Tue, 12 Dec 2023 16:13:32 -0800 (PST) Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-1d03bcf27e9so39541665ad.0; Tue, 12 Dec 2023 16:13:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426412; x=1703031212; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=jUL8XAmO2qiHdWokVXe8WU7dwxVOHJXV31dlSpnABqs=; b=POyDM7Zz2mJ/TjEWN/s8el/mDMWOU5lqMwUanTXP2fR/a9AMA+QovAeU+FRubGNnsu srN/GgG34z25tdRKg3gGYUNKNydhNAhdPnoPR7AqWvGnCXF4OMZjjeJIQ2vdK1xfFidX tSugM9NnOEOmUrtyxHTj27mKqgKAJgcQ/t27mKYQUcZScuzCbchvWULMp62dlaUj59aD ixmQFzjMgfhscf89OYUI9dJe6/70XDzVTJTHW4X4HczT27iz3y89Lg4CESYMbKvq3aGH 9zTiW3jkfHnAfiss7g5zxn4z3RAsKiwFII78k/6JOUeF7pSndcCpAAXVCmBl83kHgWI7 WPXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426412; x=1703031212; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=jUL8XAmO2qiHdWokVXe8WU7dwxVOHJXV31dlSpnABqs=; b=pfXEU8x8Y8vWqhtGruNiBSh27J+eGW1Y7zv2cBJaBPfeYBaDKiYw/QudUp+YZKsxrM nET34/mYBsKq7m7rMXQFmY/MvEtnb2OMOpT5DXkMTdvkAJZEoG0pOHgBIgdQtmR4XFHH nJBRb5FWYcxkHOSuuu7VuY30qe/AzDM48SLQUDNW4AV+zecHdEFMCoRet/I0qvhdYiWi UYexnceOPkgAD0W/A0PTp+ytB0xIblXrKEISox07gbuovTs8ZJzJys+rEWPqjxxiTtFx w//J+52qwL/99Hv2qms/1X/b9KIvVoZLG5+Fg7jYcHDPWMByWVnapNXShUdPs+U+9EHX nDJA== X-Gm-Message-State: AOJu0Yx6iidhvDnZch3EBFSdqUDI19Rz+t9w+ncAEKECjGoim0NE72kS DpjGZQ+vtM4cpEBkM2Bk1gg= X-Google-Smtp-Source: AGHT+IGpMYGeqGHw+LbYWTHi4KX/Qmq5JaiI4ACRKC9vfRYU/uoiSEHyZeG3Uk0zOT+cM6x5nWNS0g== X-Received: by 2002:a17:902:680d:b0:1d3:3eb8:53c3 with SMTP id h13-20020a170902680d00b001d33eb853c3mr1100315plk.89.1702426411841; Tue, 12 Dec 2023 16:13:31 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:30 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 03/17] perf annotate-data: Add find_data_type() Date: Tue, 12 Dec 2023 16:13:09 -0800 Message-ID: <20231213001323.718046-4-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The find_data_type() is to get a data type from the memory access at the given address (IP) using a register and an offset. It requires DWARF debug info in the DSO and searches the list of variables and function parameters in the scope. In a pseudo code, it does basically the following: find_data_type(dso, ip, reg, offset) { pc = map__rip_2objdump(ip); CU = dwarf_addrdie(dso->dwarf, pc); scopes = die_get_scopes(CU, pc); for_each_scope(S, scopes) { V = die_find_variable_by_reg(S, pc, reg); if (V && V.type == pointer_type) { T = die_get_real_type(V); if (offset < T.size) return T; } } return NULL; } Signed-off-by: Namhyung Kim --- tools/perf/util/Build | 1 + tools/perf/util/annotate-data.c | 163 ++++++++++++++++++++++++++++++++ tools/perf/util/annotate-data.h | 40 ++++++++ 3 files changed, 204 insertions(+) create mode 100644 tools/perf/util/annotate-data.c create mode 100644 tools/perf/util/annotate-data.h diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 73e3f194f949..5cf000302080 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -196,6 +196,7 @@ perf-$(CONFIG_DWARF) += probe-finder.o perf-$(CONFIG_DWARF) += dwarf-aux.o perf-$(CONFIG_DWARF) += dwarf-regs.o perf-$(CONFIG_DWARF) += debuginfo.o +perf-$(CONFIG_DWARF) += annotate-data.o perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind-local.o diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c new file mode 100644 index 000000000000..1ddec786721c --- /dev/null +++ b/tools/perf/util/annotate-data.c @@ -0,0 +1,163 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Convert sample address to data type using DWARF debug info. + * + * Written by Namhyung Kim + */ + +#include +#include + +#include "annotate-data.h" +#include "debuginfo.h" +#include "debug.h" +#include "dso.h" +#include "map.h" +#include "map_symbol.h" +#include "strbuf.h" +#include "symbol.h" + +static bool find_cu_die(struct debuginfo *di, u64 pc, Dwarf_Die *cu_die) +{ + Dwarf_Off off, next_off; + size_t header_size; + + if (dwarf_addrdie(di->dbg, pc, cu_die) != NULL) + return cu_die; + + /* + * There are some kernels don't have full aranges and contain only a few + * aranges entries. Fallback to iterate all CU entries in .debug_info + * in case it's missing. + */ + off = 0; + while (dwarf_nextcu(di->dbg, off, &next_off, &header_size, + NULL, NULL, NULL) == 0) { + if (dwarf_offdie(di->dbg, off + header_size, cu_die) && + dwarf_haspc(cu_die, pc)) + return true; + + off = next_off; + } + return false; +} + +/* The type info will be saved in @type_die */ +static int check_variable(Dwarf_Die *var_die, Dwarf_Die *type_die, int offset) +{ + Dwarf_Word size; + + /* Get the type of the variable */ + if (die_get_real_type(var_die, type_die) == NULL) { + pr_debug("variable has no type\n"); + return -1; + } + + /* + * It expects a pointer type for a memory access. + * Convert to a real type it points to. + */ + if (dwarf_tag(type_die) != DW_TAG_pointer_type || + die_get_real_type(type_die, type_die) == NULL) { + pr_debug("no pointer or no type\n"); + return -1; + } + + /* Get the size of the actual type */ + if (dwarf_aggregate_size(type_die, &size) < 0) { + pr_debug("type size is unknown\n"); + return -1; + } + + /* Minimal sanity check */ + if ((unsigned)offset >= size) { + pr_debug("offset: %d is bigger than size: %lu\n", offset, size); + return -1; + } + + return 0; +} + +/* The result will be saved in @type_die */ +static int find_data_type_die(struct debuginfo *di, u64 pc, + int reg, int offset, Dwarf_Die *type_die) +{ + Dwarf_Die cu_die, var_die; + Dwarf_Die *scopes = NULL; + int ret = -1; + int i, nr_scopes; + + /* Get a compile_unit for this address */ + if (!find_cu_die(di, pc, &cu_die)) { + pr_debug("cannot find CU for address %lx\n", pc); + return -1; + } + + /* Get a list of nested scopes - i.e. (inlined) functions and blocks. */ + nr_scopes = die_get_scopes(&cu_die, pc, &scopes); + + /* Search from the inner-most scope to the outer */ + for (i = nr_scopes - 1; i >= 0; i--) { + /* Look up variables/parameters in this scope */ + if (!die_find_variable_by_reg(&scopes[i], pc, reg, &var_die)) + continue; + + /* Found a variable, see if it's correct */ + ret = check_variable(&var_die, type_die, offset); + break; + } + + free(scopes); + return ret; +} + +/** + * find_data_type - Return a data type at the location + * @ms: map and symbol at the location + * @ip: instruction address of the memory access + * @reg: register that holds the base address + * @offset: offset from the base address + * + * This functions searches the debug information of the binary to get the data + * type it accesses. The exact location is expressed by (ip, reg, offset). + * It return %NULL if not found. + */ +struct annotated_data_type *find_data_type(struct map_symbol *ms, u64 ip, + int reg, int offset) +{ + struct annotated_data_type *result = NULL; + struct dso *dso = map__dso(ms->map); + struct debuginfo *di; + Dwarf_Die type_die; + struct strbuf sb; + u64 pc; + + di = debuginfo__new(dso->long_name); + if (di == NULL) { + pr_debug("cannot get the debug info\n"); + return NULL; + } + + /* + * IP is a relative instruction address from the start of the map, as + * it can be randomized/relocated, it needs to translate to PC which is + * a file address for DWARF processing. + */ + pc = map__rip_2objdump(ms->map, ip); + if (find_data_type_die(di, pc, reg, offset, &type_die) < 0) + goto out; + + result = zalloc(sizeof(*result)); + if (result == NULL) + goto out; + + strbuf_init(&sb, 32); + if (die_get_typename_from_type(&type_die, &sb) < 0) + strbuf_add(&sb, "(unknown type)", 14); + + result->type_name = strbuf_detach(&sb, NULL); + +out: + debuginfo__delete(di); + return result; +} diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h new file mode 100644 index 000000000000..633147f78ca5 --- /dev/null +++ b/tools/perf/util/annotate-data.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _PERF_ANNOTATE_DATA_H +#define _PERF_ANNOTATE_DATA_H + +#include +#include +#include + +struct map_symbol; + +/** + * struct annotated_data_type - Data type to profile + * @type_name: Name of the data type + * @type_size: Size of the data type + * + * This represents a data type accessed by samples in the profile data. + */ +struct annotated_data_type { + char *type_name; + int type_size; +}; + +#ifdef HAVE_DWARF_SUPPORT + +/* Returns data type at the location (ip, reg, offset) */ +struct annotated_data_type *find_data_type(struct map_symbol *ms, u64 ip, + int reg, int offset); + +#else /* HAVE_DWARF_SUPPORT */ + +static inline struct annotated_data_type * +find_data_type(struct map_symbol *ms __maybe_unused, u64 ip __maybe_unused, + int reg __maybe_unused, int offset __maybe_unused) +{ + return NULL; +} + +#endif /* HAVE_DWARF_SUPPORT */ + +#endif /* _PERF_ANNOTATE_DATA_H */ From patchwork Wed Dec 13 00:13:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490189 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bG+AORQZ" Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B5B5CE; Tue, 12 Dec 2023 16:13:34 -0800 (PST) Received: by mail-pl1-x62d.google.com with SMTP id d9443c01a7336-1d04dba2781so39406685ad.3; Tue, 12 Dec 2023 16:13:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426413; x=1703031213; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=5AIxOsgkzzVIRMn2jiHfaF7XNgXwAIgH856PArZgcqg=; b=bG+AORQZdpXIEry6qYel/7KDxuzvQwCoRHN7RqLekwW+cq1pMRQqybiSATpW+mo+tR 0MkdHGEv9DPoxQAnG7MP4w69lnZYYQsmCX+VAlfeJ983ssS1+v6gBxqWWnST7km9XTaC vTwjiO7pqK2W+4f627+UwS7olEpscDKchSmIiAKhnFe0Ho294Z5YnEVyrOUJSBbvtREo lrIUDoiCvNABPFvmetPFHardQ297uCfS7jundkL0RPTAnqWdR/J3bbuWld0E71ayMMzc YcAbOO2t07UWUecJdWXqSYlOM6Wi6glBO6ATZ36rZaUiISooHW9n+J6O49GT8xoyy4Kg u2ww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426413; x=1703031213; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=5AIxOsgkzzVIRMn2jiHfaF7XNgXwAIgH856PArZgcqg=; b=X3+BD9iKTs6eiUwmuTWzL5xEBoZtf+lUD+7X+vRxl/g4DBvHo5SWd200oBnnf2Cdao ZWu/bO1S5Z2b73dVB4VvuwZHoSAltnIm0sUz0NlLi4sfm6gNXo+X5dNeB/6SmhBryQ47 5Zt/J2LfDiwYYIj81q0n7p3DKTfFuP8XIPdNfDgh7ePzlMzMo7HYgVMX9v646EEhudaT DFK+Cm2n0f6K9ip/KleknAhWAhIFIf28DwPiceaI7m9TaSSlGr46+nF0Zf+xn2fnPnLI Q/qSPmoyFFwEgdy0HH4hLtyCB+0/eHxtFyrceBH//r9KpIXAgT74gbjRalZE5FSeXA9o 38qA== X-Gm-Message-State: AOJu0Yx4oviXWdm5hXoLzg3lOrn3VGg+5wmqvQ54Djd3X46j/LhSha4d k1clrVwBYemjudm4olp2iS0= X-Google-Smtp-Source: AGHT+IFQd9MdDuECR4TOQyAOLg7i/BkVFGPf8ZFLyZpSlWhQQvTAkJyutQ3BLlwfCK1gylmUY2ua/w== X-Received: by 2002:a17:902:e88f:b0:1d0:7072:e241 with SMTP id w15-20020a170902e88f00b001d07072e241mr4494528plg.49.1702426413443; Tue, 12 Dec 2023 16:13:33 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:32 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 04/17] perf annotate-data: Add dso->data_types tree Date: Tue, 12 Dec 2023 16:13:10 -0800 Message-ID: <20231213001323.718046-5-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 To aggregate accesses to the same data type, add 'data_types' tree in DSO to maintain data types and find it by name and size. It might have different data types that happen to have the same name. So it also compares the size of the type. Even if it doesn't 100% guarantee, it'd reduce the possiblility of mis-handling of such conflicts. And I don't think it's common to have different types with the same name. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 95 +++++++++++++++++++++++++++++---- tools/perf/util/annotate-data.h | 9 ++++ tools/perf/util/dso.c | 4 ++ tools/perf/util/dso.h | 2 + 4 files changed, 100 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index 1ddec786721c..c9c359b4d4ad 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -17,6 +17,76 @@ #include "strbuf.h" #include "symbol.h" +/* + * Compare type name and size to maintain them in a tree. + * I'm not sure if DWARF would have information of a single type in many + * different places (compilation units). If not, it could compare the + * offset of the type entry in the .debug_info section. + */ +static int data_type_cmp(const void *_key, const struct rb_node *node) +{ + const struct annotated_data_type *key = _key; + struct annotated_data_type *type; + + type = rb_entry(node, struct annotated_data_type, node); + + if (key->type_size != type->type_size) + return key->type_size - type->type_size; + return strcmp(key->type_name, type->type_name); +} + +static bool data_type_less(struct rb_node *node_a, const struct rb_node *node_b) +{ + struct annotated_data_type *a, *b; + + a = rb_entry(node_a, struct annotated_data_type, node); + b = rb_entry(node_b, struct annotated_data_type, node); + + if (a->type_size != b->type_size) + return a->type_size < b->type_size; + return strcmp(a->type_name, b->type_name) < 0; +} + +static struct annotated_data_type *dso__findnew_data_type(struct dso *dso, + Dwarf_Die *type_die) +{ + struct annotated_data_type *result = NULL; + struct annotated_data_type key; + struct rb_node *node; + struct strbuf sb; + char *type_name; + Dwarf_Word size; + + strbuf_init(&sb, 32); + if (die_get_typename_from_type(type_die, &sb) < 0) + strbuf_add(&sb, "(unknown type)", 14); + type_name = strbuf_detach(&sb, NULL); + dwarf_aggregate_size(type_die, &size); + + /* Check existing nodes in dso->data_types tree */ + key.type_name = type_name; + key.type_size = size; + node = rb_find(&key, &dso->data_types, data_type_cmp); + if (node) { + result = rb_entry(node, struct annotated_data_type, node); + free(type_name); + return result; + } + + /* If not, add a new one */ + result = zalloc(sizeof(*result)); + if (result == NULL) { + free(type_name); + return NULL; + } + + result->type_name = type_name; + result->type_size = size; + + rb_add(&result->node, &dso->data_types, data_type_less); + return result; +} + static bool find_cu_die(struct debuginfo *di, u64 pc, Dwarf_Die *cu_die) { Dwarf_Off off, next_off; @@ -129,7 +199,6 @@ struct annotated_data_type *find_data_type(struct map_symbol *ms, u64 ip, struct dso *dso = map__dso(ms->map); struct debuginfo *di; Dwarf_Die type_die; - struct strbuf sb; u64 pc; di = debuginfo__new(dso->long_name); @@ -147,17 +216,23 @@ struct annotated_data_type *find_data_type(struct map_symbol *ms, u64 ip, if (find_data_type_die(di, pc, reg, offset, &type_die) < 0) goto out; - result = zalloc(sizeof(*result)); - if (result == NULL) - goto out; - - strbuf_init(&sb, 32); - if (die_get_typename_from_type(&type_die, &sb) < 0) - strbuf_add(&sb, "(unknown type)", 14); - - result->type_name = strbuf_detach(&sb, NULL); + result = dso__findnew_data_type(dso, &type_die); out: debuginfo__delete(di); return result; } + +void annotated_data_type__tree_delete(struct rb_root *root) +{ + struct annotated_data_type *pos; + + while (!RB_EMPTY_ROOT(root)) { + struct rb_node *node = rb_first(root); + + rb_erase(node, root); + pos = rb_entry(node, struct annotated_data_type, node); + free(pos->type_name); + free(pos); + } +} diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h index 633147f78ca5..ab9f187bd7f1 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -4,6 +4,7 @@ #include #include +#include #include struct map_symbol; @@ -16,6 +17,7 @@ struct map_symbol; * This represents a data type accessed by samples in the profile data. */ struct annotated_data_type { + struct rb_node node; char *type_name; int type_size; }; @@ -26,6 +28,9 @@ struct annotated_data_type { struct annotated_data_type *find_data_type(struct map_symbol *ms, u64 ip, int reg, int offset); +/* Release all data type information in the tree */ +void annotated_data_type__tree_delete(struct rb_root *root); + #else /* HAVE_DWARF_SUPPORT */ static inline struct annotated_data_type * @@ -35,6 +40,10 @@ find_data_type(struct map_symbol *ms __maybe_unused, u64 ip __maybe_unused, return NULL; } +static inline void annotated_data_type__tree_delete(struct rb_root *root __maybe_unused) +{ +} + #endif /* HAVE_DWARF_SUPPORT */ #endif /* _PERF_ANNOTATE_DATA_H */ diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 1f629b6fb7cf..22fd5fa806ed 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -31,6 +31,7 @@ #include "debug.h" #include "string2.h" #include "vdso.h" +#include "annotate-data.h" static const char * const debuglink_paths[] = { "%.0s%s", @@ -1327,6 +1328,7 @@ struct dso *dso__new_id(const char *name, struct dso_id *id) dso->data.cache = RB_ROOT; dso->inlined_nodes = RB_ROOT_CACHED; dso->srclines = RB_ROOT_CACHED; + dso->data_types = RB_ROOT; dso->data.fd = -1; dso->data.status = DSO_DATA_STATUS_UNKNOWN; dso->symtab_type = DSO_BINARY_TYPE__NOT_FOUND; @@ -1370,6 +1372,8 @@ void dso__delete(struct dso *dso) symbols__delete(&dso->symbols); dso->symbol_names_len = 0; zfree(&dso->symbol_names); + annotated_data_type__tree_delete(&dso->data_types); + if (dso->short_name_allocated) { zfree((char **)&dso->short_name); dso->short_name_allocated = false; diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 3759de8c2267..ce9f3849a773 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -154,6 +154,8 @@ struct dso { size_t symbol_names_len; struct rb_root_cached inlined_nodes; struct rb_root_cached srclines; + struct rb_root data_types; + struct { u64 addr; struct symbol *symbol; From patchwork Wed Dec 13 00:13:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490190 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Iza/XTFq" Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1AE62F2; Tue, 12 Dec 2023 16:13:35 -0800 (PST) Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-1d350dff621so91945ad.1; Tue, 12 Dec 2023 16:13:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426415; x=1703031215; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=PkkFWfvjQLCvXur8tZcl1ZlAE8gNAy7zE9mjhobcdGI=; b=Iza/XTFqaPFbG0sf6s2K/afH/mNtHb5+/Pl55K9aVdQYxEDHTVvgY0LD6QsWEIjRlI KpHlYDxKY4k0w9fLgqxtWhsYLE184MOU9Rx+GvLe29XoWPuvg2Fo+UG5SADOzQerrrg1 9opd27fNwk4GkDBfoOIcncQYXpI8Y7qRO5RFBTnX5+cup7fxNUnfpk87pMXR+QmHSu+A HtI1Hr1R/oxs2jk8e4fj2A3Yur0bTCBcrRfiLIJUK3TOZAgvHfANd//DSkPtcS+gG7Ix r8hqNm3M3Yi3K9rEwH4O9Q4mSAh7zLmOcxo7DUuyrDBBBo+Lx42lK/d/dBLpjMTGUmsf fzHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426415; x=1703031215; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=PkkFWfvjQLCvXur8tZcl1ZlAE8gNAy7zE9mjhobcdGI=; b=lhwh/fu7NXTgx9sAi/5v2fgEXigRb1hrUV+HOWL7wNrIhlHavpq0rYGCxKM17zH77u 8tZsvaNyUWxmH/e1jF9mJ2SlLNsVsegjQ8n15L/HJzlQoFmWREN6CaouuKcrtMTeCIuI Rnp1G0DlvetB3pNd7KwlxZUyzppda/1dO+vkJri31+lzuVg6X4/AWgBq3J6flyeAEdj/ gFKVaDv3vGyuaFmRo+K/4BxjdUA6w8iDzjM87g5NrExnrM2rlRno1KG+3Tp8dVR/6gi8 8YkZjbMcgz6V+e9MlAy+v+HqRZy40+eQF5fIaRhIevDH1gPy4mX8LNSRVVCjrtl9HcG4 HXzA== X-Gm-Message-State: AOJu0Yy1SkJb19Vg89H2EMlbiVsO1G7x7VRZ08EBYBel0sdOP3P2l6M1 YupFn8jFjAZS115jooVV6dQ= X-Google-Smtp-Source: AGHT+IFcTDro9RYV5lVrmC9QPOmsck94l6Vq6oGMX/nT6RiCpEnyKcb1hYKRm49ENiezN9lOibBrpg== X-Received: by 2002:a17:902:7ecf:b0:1d3:3c35:81b5 with SMTP id p15-20020a1709027ecf00b001d33c3581b5mr1294421plb.46.1702426415314; Tue, 12 Dec 2023 16:13:35 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:34 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 05/17] perf annotate: Factor out evsel__get_arch() Date: Tue, 12 Dec 2023 16:13:11 -0800 Message-ID: <20231213001323.718046-6-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The evsel__get_arch() is to get architecture info from the environ. It'll be used by other places later so let's factor it out. Also add arch__is() to check the arch info by name. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate.c | 44 +++++++++++++++++++++++++++----------- tools/perf/util/annotate.h | 2 ++ 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index c81fa0791918..27b2a9961cd5 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -843,6 +843,11 @@ static struct arch *arch__find(const char *name) return bsearch(name, architectures, nmemb, sizeof(struct arch), arch__key_cmp); } +bool arch__is(struct arch *arch, const char *name) +{ + return !strcmp(arch->name, name); +} + static struct annotated_source *annotated_source__new(void) { struct annotated_source *src = zalloc(sizeof(*src)); @@ -2378,15 +2383,8 @@ void symbol__calc_percent(struct symbol *sym, struct evsel *evsel) annotation__calc_percent(notes, evsel, symbol__size(sym)); } -int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, - struct arch **parch) +static int evsel__get_arch(struct evsel *evsel, struct arch **parch) { - struct symbol *sym = ms->sym; - struct annotation *notes = symbol__annotation(sym); - struct annotate_args args = { - .evsel = evsel, - .options = &annotate_opts, - }; struct perf_env *env = evsel__env(evsel); const char *arch_name = perf_env__arch(env); struct arch *arch; @@ -2395,23 +2393,43 @@ int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, if (!arch_name) return errno; - args.arch = arch = arch__find(arch_name); + *parch = arch = arch__find(arch_name); if (arch == NULL) { pr_err("%s: unsupported arch %s\n", __func__, arch_name); return ENOTSUP; } - if (parch) - *parch = arch; - if (arch->init) { err = arch->init(arch, env ? env->cpuid : NULL); if (err) { - pr_err("%s: failed to initialize %s arch priv area\n", __func__, arch->name); + pr_err("%s: failed to initialize %s arch priv area\n", + __func__, arch->name); return err; } } + return 0; +} + +int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, + struct arch **parch) +{ + struct symbol *sym = ms->sym; + struct annotation *notes = symbol__annotation(sym); + struct annotate_args args = { + .evsel = evsel, + .options = &annotate_opts, + }; + struct arch *arch = NULL; + int err; + + err = evsel__get_arch(evsel, &arch); + if (err < 0) + return err; + + if (parch) + *parch = arch; + args.arch = arch; args.ms = *ms; if (annotate_opts.full_addr) notes->start = map__objdump_2mem(ms->map, ms->sym->start); diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 589f8aaf0236..2ef7e7dda7bd 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -61,6 +61,8 @@ struct ins_operands { struct arch; +bool arch__is(struct arch *arch, const char *name); + struct ins_ops { void (*free)(struct ins_operands *ops); int (*parse)(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms); From patchwork Wed Dec 13 00:13:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490191 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nYoss4tX" Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C769210A; Tue, 12 Dec 2023 16:13:37 -0800 (PST) Received: by mail-pg1-x52f.google.com with SMTP id 41be03b00d2f7-5c229dabbb6so3580230a12.0; Tue, 12 Dec 2023 16:13:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426417; x=1703031217; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=Gp0h3Jhclsi2kLqdk87eOr+U+R23NUw3mkweFdnS3Ow=; b=nYoss4tXJ3jaZGBmk5hJkYhv345Zb2SnqQ9ZFck22GJ1rBtWs8+TvB/2oaVThv1O3G bqjmh0r6WMOZHio7SofbueSm/f/2ezIzyF+MZ6iq5iIo3iMA8Z0SV59f9yjic/vdErMg VFGao+jY4oAhc/4arISdY/8t8VQZKKya1M5Mii7flwrCTXyJyKrxbhDmwj1XTuod1rUG ZuQFWsJ8Owu8q0/zanB1GlxRT349iT7Ih6CRCcxQy+NzapKXNJvWgCoT6plNrb5DTYv/ TCTUy5RYsOLs0zYjoE9iWpdhFP3qxhtq4v+nHr4dXHoNYr/ma5VL5cTqv6hePE4IFCcO GP8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426417; x=1703031217; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Gp0h3Jhclsi2kLqdk87eOr+U+R23NUw3mkweFdnS3Ow=; b=MDtwkkla6BerA+ZEk5Xz+Bs2WAvzJ1+TboW11FSxK9uQU7dLK4h9FcT08AHNyyjZcZ pONOrZQ9B14of9udVFXOZTZU1RLi/G930WsF/I8pImLKgJTLvjq48h2gzq92sf8Qd+M/ ZzIAhJ8ilURei4oZBVLztPgZbqxWq0jJ9DE40edV0NdZtCGnjdCFfIg4cdD5SBA6+Ymi A6u2j+VY8ib4QHb7N2YFa0+2WHSW5f239ddJ4m8sU491jcE1oNjtC88S/vVuFl/t0o5h lxDiQCTA0rqrTPLcd5SmUeCZDNIH3R/ns8ehU8pYEWz3eqvN23AxBM2rGmSZOmEBUcuC 5RuA== X-Gm-Message-State: AOJu0Yzyc76hF0n56YzY7rTo9JUgWY9RCsCE7OQkRVU/cRLCwMadRn73 gv9tEzOtQj/9yFpyL1POs9A= X-Google-Smtp-Source: AGHT+IHzRDn6GU8IbdRuJYvsSYpwzmx2YxHCPr2HrAbVp5s+ia737jwwh3THZ7LMC3usEyO3K2xiBA== X-Received: by 2002:a05:6a20:d41f:b0:18f:c2f6:8953 with SMTP id il31-20020a056a20d41f00b0018fc2f68953mr3544916pzb.10.1702426416915; Tue, 12 Dec 2023 16:13:36 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:36 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 06/17] perf annotate: Add annotate_get_insn_location() Date: Tue, 12 Dec 2023 16:13:12 -0800 Message-ID: <20231213001323.718046-7-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The annotate_get_insn_location() is to get the detailed information of instruction locations like registers and offset. It has source and target operands locations in an array. Each operand can have a register and an offset. The offset is meaningful when mem_ref flag is set. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate.c | 107 +++++++++++++++++++++++++++++++++++++ tools/perf/util/annotate.h | 36 +++++++++++++ 2 files changed, 143 insertions(+) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 27b2a9961cd5..7c597440dc2e 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -31,6 +31,7 @@ #include "bpf-utils.h" #include "block-range.h" #include "string2.h" +#include "dwarf-regs.h" #include "util/event.h" #include "util/sharded_mutex.h" #include "arch/common.h" @@ -3518,3 +3519,109 @@ int annotate_check_args(void) } return 0; } + +/* + * Get register number and access offset from the given instruction. + * It assumes AT&T x86 asm format like OFFSET(REG). Maybe it needs + * to revisit the format when it handles different architecture. + * Fills @reg and @offset when return 0. + */ +static int extract_reg_offset(struct arch *arch, const char *str, + struct annotated_op_loc *op_loc) +{ + char *p; + char *regname; + + if (arch->objdump.register_char == 0) + return -1; + + /* + * It should start from offset, but it's possible to skip 0 + * in the asm. So 0(%rax) should be same as (%rax). + * + * However, it also start with a segment select register like + * %gs:0x18(%rbx). In that case it should skip the part. + */ + if (*str == arch->objdump.register_char) { + while (*str && !isdigit(*str) && + *str != arch->objdump.memory_ref_char) + str++; + } + + op_loc->offset = strtol(str, &p, 0); + + p = strchr(p, arch->objdump.register_char); + if (p == NULL) + return -1; + + regname = strdup(p); + if (regname == NULL) + return -1; + + op_loc->reg = get_dwarf_regnum(regname, 0); + free(regname); + return 0; +} + +/** + * annotate_get_insn_location - Get location of instruction + * @arch: the architecture info + * @dl: the target instruction + * @loc: a buffer to save the data + * + * Get detailed location info (register and offset) in the instruction. + * It needs both source and target operand and whether it accesses a + * memory location. The offset field is meaningful only when the + * corresponding mem flag is set. + * + * Some examples on x86: + * + * mov (%rax), %rcx # src_reg = rax, src_mem = 1, src_offset = 0 + * # dst_reg = rcx, dst_mem = 0 + * + * mov 0x18, %r8 # src_reg = -1, dst_reg = r8 + */ +int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl, + struct annotated_insn_loc *loc) +{ + struct ins_operands *ops; + struct annotated_op_loc *op_loc; + int i; + + if (!strcmp(dl->ins.name, "lock")) + ops = dl->ops.locked.ops; + else + ops = &dl->ops; + + if (ops == NULL) + return -1; + + memset(loc, 0, sizeof(*loc)); + + for_each_insn_op_loc(loc, i, op_loc) { + const char *insn_str = ops->source.raw; + + if (i == INSN_OP_TARGET) + insn_str = ops->target.raw; + + /* Invalidate the register by default */ + op_loc->reg = -1; + + if (insn_str == NULL) + continue; + + if (strchr(insn_str, arch->objdump.memory_ref_char)) { + op_loc->mem_ref = true; + extract_reg_offset(arch, insn_str, op_loc); + } else { + char *s = strdup(insn_str); + + if (s) { + op_loc->reg = get_dwarf_regnum(s, 0); + free(s); + } + } + } + + return 0; +} diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 2ef7e7dda7bd..25ae8893d4f9 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -439,4 +439,40 @@ int annotate_parse_percent_type(const struct option *opt, const char *_str, int annotate_check_args(void); +/** + * struct annotated_op_loc - Location info of instruction operand + * @reg: Register in the operand + * @offset: Memory access offset in the operand + * @mem_ref: Whether the operand accesses memory + */ +struct annotated_op_loc { + int reg; + int offset; + bool mem_ref; +}; + +enum annotated_insn_ops { + INSN_OP_SOURCE = 0, + INSN_OP_TARGET = 1, + + INSN_OP_MAX, +}; + +/** + * struct annotated_insn_loc - Location info of instruction + * @ops: Array of location info for source and target operands + */ +struct annotated_insn_loc { + struct annotated_op_loc ops[INSN_OP_MAX]; +}; + +#define for_each_insn_op_loc(insn_loc, i, op_loc) \ + for (i = INSN_OP_SOURCE, op_loc = &(insn_loc)->ops[i]; \ + i < INSN_OP_MAX; \ + i++, op_loc++) + +/* Get detailed location info in the instruction */ +int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl, + struct annotated_insn_loc *loc); + #endif /* __PERF_ANNOTATE_H */ From patchwork Wed Dec 13 00:13:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490192 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WaKMdEEy" Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 62378112; Tue, 12 Dec 2023 16:13:39 -0800 (PST) Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-1d098b87eeeso56326195ad.0; Tue, 12 Dec 2023 16:13:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426419; x=1703031219; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=hu4FhpBOZPILh8fziHco9keVgUrcb3i/LhY1Cwkj/nE=; b=WaKMdEEylrJ6/OUpJlgn+WROF56jYzmLhFgq57A2N68icSBiLr2PMH5kNQHHRjlaaL IvFwM9Dgfx7Ur7Zrb/iasLd/2lRWDI6cawB9s9fn1mRmdDTLlTnfAsn0/Dzau7w2jF4s EdLKU1vILCSeDwjJ8pZAvoIIV6QOuo5lY2q0XBAs87o1Rr9WQLk2MQLRniZlhgM61CUf Iy1ZWoQrPuQnYFRmL3F7M2dmUuGi+GSr1MfUZw/psQF7KsThFIvfC2IE11idVZh0iwLs d7MlcXlypTFJguNkFEVYKZ19RUQe6exS3Db+BYFIv7we/UwtADMKJv2ZxN7CiB6XNeca t/Cg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426419; x=1703031219; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=hu4FhpBOZPILh8fziHco9keVgUrcb3i/LhY1Cwkj/nE=; b=MGEF55/xozsd+iYHHfa6p47feVjr5s7lJnoJe4Fuh0/dGJ3/mNUXvmASbG1uhGbytv WoToWFj6JTLhniClOiRFIECs20SjsQOdBkqJIRKHkyUPzM71RyHDc2jwY/K3O5jm3KZ9 hOOlzHkc4nfBgl3Zx7U+gvo3yd3oSLNCxfNQBirjuzbUJj/QLGz+4C20ySYrv4ftAccz 9CIEdvsNLghjiaiNDVvCgcO5jmht9g5z7ivDSM5H5Vf5Yg4us1O8jUoY1YdNJAXLG2ny Gp82CaDf2QX4XQMQoXrvIrZGe70WITX92S6lv2RAzsbewh/VQvkzSG1xSXke6n2QI5G9 EyNQ== X-Gm-Message-State: AOJu0Yzb0cS7rg+d9lVU+grYaBPAbz3nIti4tZ6B3ZPP0z4r8JsK+pR6 XgZW9r8q0bkbqgXDhYPdyYQ= X-Google-Smtp-Source: AGHT+IGYp55nk0e5Mh4PuJi4qEGEeU+CKxQ5ZtxvickF/7HAYgDjzFk/8HZxPNTYOKKwyG6rRALgUA== X-Received: by 2002:a17:903:452:b0:1d0:7d9e:e727 with SMTP id iw18-20020a170903045200b001d07d9ee727mr6181201plb.14.1702426418656; Tue, 12 Dec 2023 16:13:38 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:38 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 07/17] perf annotate: Implement hist_entry__get_data_type() Date: Tue, 12 Dec 2023 16:13:13 -0800 Message-ID: <20231213001323.718046-8-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 It's the function to find out the type info from the given sample data and will be called from the hist_entry sort logic when 'type' sort key is used. It first calls objdump to disassemble the instructions and figure out information about memory access at the location. Maybe we can do it better by analyzing the instruction directly, but I'll leave it for later work. The memory access is determined by checking instruction operands to have "(" and then extract register name and offset. It'll return NULL if no data type is found. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate.c | 88 ++++++++++++++++++++++++++++++++++++++ tools/perf/util/annotate.h | 4 ++ 2 files changed, 92 insertions(+) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 7c597440dc2e..8673eac4b9df 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -25,6 +25,7 @@ #include "units.h" #include "debug.h" #include "annotate.h" +#include "annotate-data.h" #include "evsel.h" #include "evlist.h" #include "bpf-event.h" @@ -3625,3 +3626,90 @@ int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl, return 0; } + +static void symbol__ensure_annotate(struct map_symbol *ms, struct evsel *evsel) +{ + struct disasm_line *dl, *tmp_dl; + struct annotation *notes; + + notes = symbol__annotation(ms->sym); + if (!list_empty(¬es->src->source)) + return; + + if (symbol__annotate(ms, evsel, NULL) < 0) + return; + + /* remove non-insn disasm lines for simplicity */ + list_for_each_entry_safe(dl, tmp_dl, ¬es->src->source, al.node) { + if (dl->al.offset == -1) { + list_del(&dl->al.node); + free(dl); + } + } +} + +static struct disasm_line *find_disasm_line(struct symbol *sym, u64 ip) +{ + struct disasm_line *dl; + struct annotation *notes; + + notes = symbol__annotation(sym); + + list_for_each_entry(dl, ¬es->src->source, al.node) { + if (sym->start + dl->al.offset == ip) + return dl; + } + return NULL; +} + +/** + * hist_entry__get_data_type - find data type for given hist entry + * @he: hist entry + * + * This function first annotates the instruction at @he->ip and extracts + * register and offset info from it. Then it searches the DWARF debug + * info to get a variable and type information using the address, register, + * and offset. + */ +struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) +{ + struct map_symbol *ms = &he->ms; + struct evsel *evsel = hists_to_evsel(he->hists); + struct arch *arch; + struct disasm_line *dl; + struct annotated_insn_loc loc; + struct annotated_op_loc *op_loc; + u64 ip = he->ip; + int i; + + if (ms->map == NULL || ms->sym == NULL) + return NULL; + + if (!symbol_conf.init_annotation) + return NULL; + + if (evsel__get_arch(evsel, &arch) < 0) + return NULL; + + /* Make sure it runs objdump to get disasm of the function */ + symbol__ensure_annotate(ms, evsel); + + /* + * Get a disasm to extract the location from the insn. + * This is too slow... + */ + dl = find_disasm_line(ms->sym, ip); + if (dl == NULL) + return NULL; + + if (annotate_get_insn_location(arch, dl, &loc) < 0) + return NULL; + + for_each_insn_op_loc(&loc, i, op_loc) { + if (!op_loc->mem_ref) + continue; + + return find_data_type(ms, ip, op_loc->reg, op_loc->offset); + } + return NULL; +} diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 25ae8893d4f9..6c75b2832286 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -23,6 +23,7 @@ struct option; struct perf_sample; struct evsel; struct symbol; +struct annotated_data_type; struct ins { const char *name; @@ -475,4 +476,7 @@ struct annotated_insn_loc { int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl, struct annotated_insn_loc *loc); +/* Returns a data type from the sample instruction (if any) */ +struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he); + #endif /* __PERF_ANNOTATE_H */ From patchwork Wed Dec 13 00:13:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490193 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Kef5QH4o" Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8C0ECCD; Tue, 12 Dec 2023 16:13:41 -0800 (PST) Received: by mail-pl1-x632.google.com with SMTP id d9443c01a7336-1d05199f34dso37900225ad.3; Tue, 12 Dec 2023 16:13:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426420; x=1703031220; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=7bFmAjroOIJW8gdT6fLbn3F46nSM2wYTcYmNZQVrmkQ=; b=Kef5QH4oS9yhs5VVjwMGSemrTwtwPDBS/WiRyNzVSPhfLS4t9GftqD02YBauw1DEeP N+kesqOHHxFOXX0zpGLjug5rT7QISFeFmrjqHcXQnRM1H6aaXpKmE1xNfVSzVKyUoWu2 JTFivk/ss2mRTwdwLvU7bNlhE3eTL8Hi3dvwiIOc0Z/a+ahsy4J7VWyc4gIrJC0Nqc4S Fef3JNCLRnNPJXTiOZgNK9hT0pPXP5jfcDHVIvU5CPnhcC/gYLOnOSK6zV3zwa7nm5Rl Gg7n4tomY74ctxMtV5XPNQpb1l5ZzBEFpsoeGXJORb4Hi3dm/TPeVFXON2oyhUzrlyt6 fTVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426420; x=1703031220; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=7bFmAjroOIJW8gdT6fLbn3F46nSM2wYTcYmNZQVrmkQ=; b=Maben6gu514kKUHXhW6/vOouErO/J95151fRh4F/prmiuGDSd79buig07JVCFnt6SC isGPAUadD3PGuuppVkDTeXV/EpNhQXGgkbmlAfUa8IsELfjHPKxYmTVJpBVE5cXGomdg m+DU6inppmC/1E6fpd+TK2g/syzOL770Oi0XvtHpJ3ZH0erpo0pittR3q2D9LDfjp78X RVWrp9rIki8QCsjzgQVs6km3p2ZAHwVQo/PimMHaPJhC3U+QHCJJDI/b/qOK5dhNUXfl pwUicBK1GKpB+v8Hh8T+DsS9LR+2Zpweu5qvsUjPZi6V7XjDvUCIuUaMSWPUjHhvdafe P+UA== X-Gm-Message-State: AOJu0YzwPjlaxmHB1mXbOby1Cm781wz/uefbdShe6lYpkqq3MHlVZlIo LdxyDJEsy2UwySXbG2fnv11h8HK9viT7TQ== X-Google-Smtp-Source: AGHT+IEWq2y2PoqSbiSJb+JJgQnf6aBhOcpE0bUST8K3cq/wuj8rE77y9cUQrwPWD3NZzeYkV7rM9Q== X-Received: by 2002:a17:902:e882:b0:1d0:a146:f859 with SMTP id w2-20020a170902e88200b001d0a146f859mr4510764plg.114.1702426420115; Tue, 12 Dec 2023 16:13:40 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:39 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 08/17] perf report: Add 'type' sort key Date: Tue, 12 Dec 2023 16:13:14 -0800 Message-ID: <20231213001323.718046-9-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The 'type' sort key is to aggregate hist entries by data type they access. Add mem_type field to hist_entry struct to save the type. If hist_entry__get_data_type() returns NULL, it'd use the 'unknown_type' instance. Signed-off-by: Namhyung Kim --- tools/perf/Documentation/perf-report.txt | 1 + tools/perf/util/annotate-data.h | 2 + tools/perf/util/hist.h | 1 + tools/perf/util/sort.c | 69 +++++++++++++++++++++++- tools/perf/util/sort.h | 4 ++ 5 files changed, 75 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index af068b4f1e5a..aec34417090b 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -118,6 +118,7 @@ OPTIONS - retire_lat: On X86, this reports pipeline stall of this instruction compared to the previous instruction in cycles. And currently supported only on X86 - simd: Flags describing a SIMD operation. "e" for empty Arm SVE predicate. "p" for partial Arm SVE predicate + - type: Data type of sample memory access. By default, comm, dso and symbol keys are used. (i.e. --sort comm,dso,symbol) diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h index ab9f187bd7f1..6efdd7e21b28 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -22,6 +22,8 @@ struct annotated_data_type { int type_size; }; +extern struct annotated_data_type unknown_type; + #ifdef HAVE_DWARF_SUPPORT /* Returns data type at the location (ip, reg, offset) */ diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 5d0db96609df..7ebbf427b1ea 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -82,6 +82,7 @@ enum hist_column { HISTC_ADDR_TO, HISTC_ADDR, HISTC_SIMD, + HISTC_TYPE, HISTC_NR_COLS, /* Last entry */ }; diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 27b123ccd2d1..e647f0117bb5 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -24,6 +24,7 @@ #include "strbuf.h" #include "mem-events.h" #include "annotate.h" +#include "annotate-data.h" #include "event.h" #include "time-utils.h" #include "cgroup.h" @@ -2094,7 +2095,7 @@ struct sort_entry sort_dso_size = { .se_width_idx = HISTC_DSO_SIZE, }; -/* --sort dso_size */ +/* --sort addr */ static int64_t sort__addr_cmp(struct hist_entry *left, struct hist_entry *right) @@ -2131,6 +2132,69 @@ struct sort_entry sort_addr = { .se_width_idx = HISTC_ADDR, }; +/* --sort type */ + +struct annotated_data_type unknown_type = { + .type_name = (char *)"(unknown)", +}; + +static int64_t +sort__type_cmp(struct hist_entry *left, struct hist_entry *right) +{ + return sort__addr_cmp(left, right); +} + +static void sort__type_init(struct hist_entry *he) +{ + if (he->mem_type) + return; + + he->mem_type = hist_entry__get_data_type(he); + if (he->mem_type == NULL) + he->mem_type = &unknown_type; +} + +static int64_t +sort__type_collapse(struct hist_entry *left, struct hist_entry *right) +{ + struct annotated_data_type *left_type = left->mem_type; + struct annotated_data_type *right_type = right->mem_type; + + if (!left_type) { + sort__type_init(left); + left_type = left->mem_type; + } + + if (!right_type) { + sort__type_init(right); + right_type = right->mem_type; + } + + return strcmp(left_type->type_name, right_type->type_name); +} + +static int64_t +sort__type_sort(struct hist_entry *left, struct hist_entry *right) +{ + return sort__type_collapse(left, right); +} + +static int hist_entry__type_snprintf(struct hist_entry *he, char *bf, + size_t size, unsigned int width) +{ + return repsep_snprintf(bf, size, "%-*s", width, he->mem_type->type_name); +} + +struct sort_entry sort_type = { + .se_header = "Data Type", + .se_cmp = sort__type_cmp, + .se_collapse = sort__type_collapse, + .se_sort = sort__type_sort, + .se_init = sort__type_init, + .se_snprintf = hist_entry__type_snprintf, + .se_width_idx = HISTC_TYPE, +}; + struct sort_dimension { const char *name; @@ -2185,7 +2249,8 @@ static struct sort_dimension common_sort_dimensions[] = { DIM(SORT_ADDR, "addr", sort_addr), DIM(SORT_LOCAL_RETIRE_LAT, "local_retire_lat", sort_local_p_stage_cyc), DIM(SORT_GLOBAL_RETIRE_LAT, "retire_lat", sort_global_p_stage_cyc), - DIM(SORT_SIMD, "simd", sort_simd) + DIM(SORT_SIMD, "simd", sort_simd), + DIM(SORT_ANNOTATE_DATA_TYPE, "type", sort_type), }; #undef DIM diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index ecfb7f1359d5..aabf0b8331a3 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -15,6 +15,7 @@ struct option; struct thread; +struct annotated_data_type; extern regex_t parent_regex; extern const char *sort_order; @@ -34,6 +35,7 @@ extern struct sort_entry sort_dso_to; extern struct sort_entry sort_sym_from; extern struct sort_entry sort_sym_to; extern struct sort_entry sort_srcline; +extern struct sort_entry sort_type; extern const char default_mem_sort_order[]; extern bool chk_double_cl; @@ -154,6 +156,7 @@ struct hist_entry { struct perf_hpp_list *hpp_list; struct hist_entry *parent_he; struct hist_entry_ops *ops; + struct annotated_data_type *mem_type; union { /* this is for hierarchical entry structure */ struct { @@ -243,6 +246,7 @@ enum sort_type { SORT_LOCAL_RETIRE_LAT, SORT_GLOBAL_RETIRE_LAT, SORT_SIMD, + SORT_ANNOTATE_DATA_TYPE, /* branch stack specific sort keys */ __SORT_BRANCH_STACK, From patchwork Wed Dec 13 00:13:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490194 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="P27Tt8ap" Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BDFD4F3; Tue, 12 Dec 2023 16:13:42 -0800 (PST) Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-1d08a924fcfso59062855ad.2; Tue, 12 Dec 2023 16:13:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426422; x=1703031222; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=jKWNHoppdDrptJRx330rZQjTF2Glc6qUjA2s/YDUwrg=; b=P27Tt8apeUEcbntKO4Yoaiv3k/I17jqZ0VXQeCwGS6/9qetEDkxG78Pb0hE2jv2Kfa JIhknpcIJFQYmjQMWI0FmlAJV7r/5VdzNf2AZRd2X/jAWK4euYMS3y9pGmbetlkIgNB7 t8KFalajCmOoPf/ARaAU59VLUQkKzdxa263o/+YLAyWdI7VA6rtQPw9xwh1Cl7173oMX Vl0sCLd++oduSO4Kd6ggqu1O9FUeJStlRIV8sv+W9rZ/5s/VMtjh9rRDj+98pw8sJIPW hO70QOVkJm0jcUEaThFcDVjrodv3N8WLxmwQ5ynSjSEpe0k52aUj1dbHS2mN4TzgyUkg ntPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426422; x=1703031222; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=jKWNHoppdDrptJRx330rZQjTF2Glc6qUjA2s/YDUwrg=; b=m+N5mXuVSC0deSnd1hrHCFSwmIPtRMxl+oiP4JPKiu8qvoFu3zo6rXushPSdIqgbjf +6yfR57rIjDQu+4HKjX5t894Xs1R+knMgyb5segdx7JEHd4folIh311i8k0Hyq8ARJK5 O/C3jxpARv4HbBXK2pGlFfv0aweObodwpd6nFVUehZJIyuUL6Ke36ljygkXhdIg7iOZr 2yaTnO0wJPsG0ZBAQeXDq1PLgVhnLhQAWusxAydWOjbVffNc/a5xBl22jOvfLJBtrBOp cr/c+k5PzShWgPtNFPIGC4xlOUCs6AlBEuFT9WEif6BtHQCpA1Xzmd1eOKyyAtDpc5vh irHQ== X-Gm-Message-State: AOJu0YzpZjyGe336iS7oDUF3zW3SCUHGpcniOh1mwU/rOkR7v3u5BnO8 4Xx6U09wLrtaz5ksH8E8vuo= X-Google-Smtp-Source: AGHT+IHce07a7VVmOT81vFUmbn9YsSdtuhACZD3dCL8ZKMuSOny3LmeidBrrZi7fdcSvex4E2ubqiQ== X-Received: by 2002:a17:902:8696:b0:1cf:ef92:18f3 with SMTP id g22-20020a170902869600b001cfef9218f3mr6793792plo.58.1702426421904; Tue, 12 Dec 2023 16:13:41 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:41 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 09/17] perf report: Support data type profiling Date: Tue, 12 Dec 2023 16:13:15 -0800 Message-ID: <20231213001323.718046-10-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Enable type annotation when the 'type' sort key is used. It shows type of variables the samples access at the moment. Users can see which types are accessed frequently. $ perf report -s dso,type --stdio ... # Overhead Shared Object Data Type # ........ ................. ......... # 35.47% [kernel.kallsyms] (unknown) 1.62% [kernel.kallsyms] struct sched_entry 1.23% [kernel.kallsyms] struct cfs_rq 0.83% [kernel.kallsyms] struct task_struct 0.34% [kernel.kallsyms] struct list_head 0.30% [kernel.kallsyms] struct mem_cgroup ... Signed-off-by: Namhyung Kim --- tools/perf/builtin-report.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 17fb171e898b..ed76152c8db8 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -96,6 +96,7 @@ struct report { bool stitch_lbr; bool disable_order; bool skip_empty; + bool data_type; int max_stack; struct perf_read_values show_threads_values; const char *pretty_printing_style; @@ -170,7 +171,7 @@ static int hist_iter__report_callback(struct hist_entry_iter *iter, struct mem_info *mi; struct branch_info *bi; - if (!ui__has_annotation() && !rep->symbol_ipc) + if (!ui__has_annotation() && !rep->symbol_ipc && !rep->data_type) return 0; if (sort__mode == SORT_MODE__BRANCH) { @@ -1619,6 +1620,16 @@ int cmd_report(int argc, const char **argv) sort_order = NULL; } + if (sort_order && strstr(sort_order, "type")) { + report.data_type = true; + annotate_opts.annotate_src = false; + +#ifndef HAVE_DWARF_GETLOCATIONS_SUPPORT + pr_err("Error: Data type profiling is disabled due to missing DWARF support\n"); + goto error; +#endif + } + if (strcmp(input_name, "-") != 0) setup_browser(true); else @@ -1677,7 +1688,7 @@ int cmd_report(int argc, const char **argv) * so don't allocate extra space that won't be used in the stdio * implementation. */ - if (ui__has_annotation() || report.symbol_ipc || + if (ui__has_annotation() || report.symbol_ipc || report.data_type || report.total_cycles_mode) { ret = symbol__annotation_init(); if (ret < 0) From patchwork Wed Dec 13 00:13:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490195 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="GA3QAx3s" Received: from mail-il1-x134.google.com (mail-il1-x134.google.com [IPv6:2607:f8b0:4864:20::134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6A2D0F2; Tue, 12 Dec 2023 16:13:45 -0800 (PST) Received: by mail-il1-x134.google.com with SMTP id e9e14a558f8ab-35d4e557c4bso27947495ab.0; Tue, 12 Dec 2023 16:13:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426424; x=1703031224; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=9LlEZ9GnF4AN+GzvPvQSgw+KzjsL2hLZSHT6H7XrNW4=; b=GA3QAx3s4stc+uMThLDL7IOsmeKHXzlOeDn1yZ2W/Fi2mvwqtiLREBJdcBAC0KaLuN 9Y5rlcw3D6ADK6GfvIyZcvhbOK4X4b9zLqTXnJALIaVDOAuiLZrMHKzJ7gB6Hj00ndIk ZtCoSdVPogoNR+K0owcLqSqZAGMfEPvQwdmT7o2D8ixpPVCI4gYOQQF+QH3WgytI0DHB bOpVTDfSe6Pk36Y+pN6AERI912hlWx2Aa5IdAqL+F+0lgu/7BXNz5McooQFf7xgDsdYb Akj5gJL6jDkFbHneke4qL7JaazO4fNTGfT6QcFVPQ0BS6Pj2qe6YdnNmqTZ9jvc4otSh W7qA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426424; x=1703031224; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=9LlEZ9GnF4AN+GzvPvQSgw+KzjsL2hLZSHT6H7XrNW4=; b=O/ZmMphXMoscAGLBjN515G8rgLidGbn1jnYTHeSVNDnpBzz1qkB8qcl6fNSuS5p/7H dpuFKS8k4cRDNuRzAr5wZcGoJ+RSqgkpteXbv4MlwDS9Ijl7zABpx230CKeIj93E4Lgb qaY5r506/ztNrLM0c1ntUpAe3Csb8gTSvihOVbg+Z/VArDQvTQr7vGPLrk9CLzW4zyja LEGc4x+JmOl/woB34van9LHng6ZcuZluAFrPrHtPoeEedf69n2XZxcQW1QKP+vapSL1e RfpYr2GEPZeCLdKcVPnNIJDH8gbRhZLwr3JgXKOApBNw2gHGaFKs+F/0Fjm6GsOk4dYk V2QQ== X-Gm-Message-State: AOJu0YyfAin6hl87PmK2dqJ3d6+CXEkS5eC6SIOPgVTkAsr8xORTHwnX PTC+uUGMR7Yy3ZE4+P7Q5g0= X-Google-Smtp-Source: AGHT+IFKHnYclCb5Lb9JWGVnsBBK4dcNEeThwFt8YIeksCqeoGJjwcXHmipUDm/1z85iK1bwJZRlFg== X-Received: by 2002:a92:cd8f:0:b0:35d:5d53:eae8 with SMTP id r15-20020a92cd8f000000b0035d5d53eae8mr10149508ilb.62.1702426424202; Tue, 12 Dec 2023 16:13:44 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:43 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 10/17] perf annotate-data: Add member field in the data type Date: Tue, 12 Dec 2023 16:13:16 -0800 Message-ID: <20231213001323.718046-11-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add child member field if the current type is a composite type like a struct or union. The member fields are linked in the children list and do the same recursively if the child itself is a composite type. Add 'self' member to the annotated_data_type to handle the members in the same way. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 101 ++++++++++++++++++++++++++++---- tools/perf/util/annotate-data.h | 27 +++++++-- tools/perf/util/sort.c | 9 ++- 3 files changed, 119 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index c9c359b4d4ad..d9c63e989b6e 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -30,9 +30,9 @@ static int data_type_cmp(const void *_key, const struct rb_node *node) type = rb_entry(node, struct annotated_data_type, node); - if (key->type_size != type->type_size) - return key->type_size - type->type_size; - return strcmp(key->type_name, type->type_name); + if (key->self.size != type->self.size) + return key->self.size - type->self.size; + return strcmp(key->self.type_name, type->self.type_name); } static bool data_type_less(struct rb_node *node_a, const struct rb_node *node_b) @@ -42,9 +42,80 @@ static bool data_type_less(struct rb_node *node_a, const struct rb_node *node_b) a = rb_entry(node_a, struct annotated_data_type, node); b = rb_entry(node_b, struct annotated_data_type, node); - if (a->type_size != b->type_size) - return a->type_size < b->type_size; - return strcmp(a->type_name, b->type_name) < 0; + if (a->self.size != b->self.size) + return a->self.size < b->self.size; + return strcmp(a->self.type_name, b->self.type_name) < 0; +} + +/* Recursively add new members for struct/union */ +static int __add_member_cb(Dwarf_Die *die, void *arg) +{ + struct annotated_member *parent = arg; + struct annotated_member *member; + Dwarf_Die member_type, die_mem; + Dwarf_Word size, loc; + Dwarf_Attribute attr; + struct strbuf sb; + int tag; + + if (dwarf_tag(die) != DW_TAG_member) + return DIE_FIND_CB_SIBLING; + + member = zalloc(sizeof(*member)); + if (member == NULL) + return DIE_FIND_CB_END; + + strbuf_init(&sb, 32); + die_get_typename(die, &sb); + + die_get_real_type(die, &member_type); + if (dwarf_aggregate_size(&member_type, &size) < 0) + size = 0; + + if (!dwarf_attr_integrate(die, DW_AT_data_member_location, &attr)) + loc = 0; + else + dwarf_formudata(&attr, &loc); + + member->type_name = strbuf_detach(&sb, NULL); + /* member->var_name can be NULL */ + if (dwarf_diename(die)) + member->var_name = strdup(dwarf_diename(die)); + member->size = size; + member->offset = loc + parent->offset; + INIT_LIST_HEAD(&member->children); + list_add_tail(&member->node, &parent->children); + + tag = dwarf_tag(&member_type); + switch (tag) { + case DW_TAG_structure_type: + case DW_TAG_union_type: + die_find_child(&member_type, __add_member_cb, member, &die_mem); + break; + default: + break; + } + return DIE_FIND_CB_SIBLING; +} + +static void add_member_types(struct annotated_data_type *parent, Dwarf_Die *type) +{ + Dwarf_Die die_mem; + + die_find_child(type, __add_member_cb, &parent->self, &die_mem); +} + +static void delete_members(struct annotated_member *member) +{ + struct annotated_member *child, *tmp; + + list_for_each_entry_safe(child, tmp, &member->children, node) { + list_del(&child->node); + delete_members(child); + free(child->type_name); + free(child->var_name); + free(child); + } } static struct annotated_data_type *dso__findnew_data_type(struct dso *dso, @@ -64,8 +135,8 @@ static struct annotated_data_type *dso__findnew_data_type(struct dso *dso, dwarf_aggregate_size(type_die, &size); /* Check existing nodes in dso->data_types tree */ - key.type_name = type_name; - key.type_size = size; + key.self.type_name = type_name; + key.self.size = size; node = rb_find(&key, &dso->data_types, data_type_cmp); if (node) { result = rb_entry(node, struct annotated_data_type, node); @@ -80,8 +151,15 @@ static struct annotated_data_type *dso__findnew_data_type(struct dso *dso, return NULL; } - result->type_name = type_name; - result->type_size = size; + result->self.type_name = type_name; + result->self.size = size; + INIT_LIST_HEAD(&result->self.children); + + /* + * Fill member info unconditionally for now, + * later perf annotate would need it. + */ + add_member_types(result, type_die); rb_add(&result->node, &dso->data_types, data_type_less); return result; @@ -232,7 +310,8 @@ void annotated_data_type__tree_delete(struct rb_root *root) rb_erase(node, root); pos = rb_entry(node, struct annotated_data_type, node); - free(pos->type_name); + delete_members(&pos->self); + free(pos->self.type_name); free(pos); } } diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h index 6efdd7e21b28..33748222e6aa 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -9,17 +9,36 @@ struct map_symbol; +/** + * struct annotated_member - Type of member field + * @node: List entry in the parent list + * @children: List head for child nodes + * @type_name: Name of the member type + * @var_name: Name of the member variable + * @offset: Offset from the outer data type + * @size: Size of the member field + * + * This represents a member type in a data type. + */ +struct annotated_member { + struct list_head node; + struct list_head children; + char *type_name; + char *var_name; + int offset; + int size; +}; + /** * struct annotated_data_type - Data type to profile - * @type_name: Name of the data type - * @type_size: Size of the data type + * @node: RB-tree node for dso->type_tree + * @self: Actual type information * * This represents a data type accessed by samples in the profile data. */ struct annotated_data_type { struct rb_node node; - char *type_name; - int type_size; + struct annotated_member self; }; extern struct annotated_data_type unknown_type; diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index e647f0117bb5..a41209e242ae 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -2135,7 +2135,10 @@ struct sort_entry sort_addr = { /* --sort type */ struct annotated_data_type unknown_type = { - .type_name = (char *)"(unknown)", + .self = { + .type_name = (char *)"(unknown)", + .children = LIST_HEAD_INIT(unknown_type.self.children), + }, }; static int64_t @@ -2170,7 +2173,7 @@ sort__type_collapse(struct hist_entry *left, struct hist_entry *right) right_type = right->mem_type; } - return strcmp(left_type->type_name, right_type->type_name); + return strcmp(left_type->self.type_name, right_type->self.type_name); } static int64_t @@ -2182,7 +2185,7 @@ sort__type_sort(struct hist_entry *left, struct hist_entry *right) static int hist_entry__type_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { - return repsep_snprintf(bf, size, "%-*s", width, he->mem_type->type_name); + return repsep_snprintf(bf, size, "%-*s", width, he->mem_type->self.type_name); } struct sort_entry sort_type = { From patchwork Wed Dec 13 00:13:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490196 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SjIihaHE" Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EAF2F18B; Tue, 12 Dec 2023 16:13:47 -0800 (PST) Received: by mail-pj1-x1030.google.com with SMTP id 98e67ed59e1d1-28aabe4a728so1595189a91.3; Tue, 12 Dec 2023 16:13:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426426; x=1703031226; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=4kifl4SjCttpoE3YbA0HzyiKu/IX8gHekgWV4VdFJxM=; b=SjIihaHE2OJQ8fvMe6RBvQcqSQWws62Wse5gpuAx6aL+xvMap1SVS/e73+Gn96SRer odpiT25oHTXNmRSaHs3R5Ywe+PWPBClngO+oWCxXdv4F0uU23wMcootzdVFe7WZKCV6i L/7Pkycq3+sjplpLznApAK9nDTptSVPsZGgEknXfTo1R8U84eMgQgGLqgUsYycMYtlNR +HrmgoAdHJkEd3vKLfSptZ6JTohRVhBGNQDNr33Sj+j9iDHk0jji3AD1LbvcPOzJDZdS i9Z1Ovm9H8k4W0XYcBaRP9KChQjxq3iERW5xRSt9OnSDMvnux3aDqAnvGsAW3O4y4UN8 CL8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426426; x=1703031226; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=4kifl4SjCttpoE3YbA0HzyiKu/IX8gHekgWV4VdFJxM=; b=AQCdLlL9HIUuzTrgUcQ+fkoDpbkTE/yKYi6ohuZzs1tGkbKTXN0XzyYYUTRMaFdNab amJuo6exuARJEyqBFk2YBI1M3dLhV1mZX08QVf+Tx2NTNf7vsp2zi+t/mvflRTHSa62r y0114R5YiOt7tv9EpOGnchkhoxN7gMziKN06I4TRl+JXzlkgfwwv2rzZzNFAtT54S/dG zyJFQ/YHEX/cHW2fr5zIsh+fwmuWdK4tqQV0rL11JHwHdfOtsJU+szDshrBK+jFimPGU WO4S25q6uN0FE6Licofi0In3k2r0pNMwGTPb6x0JcqUtHh1w7i3Xjx7dnNVDQvA33MhM qE0w== X-Gm-Message-State: AOJu0Yy/L2zelku0B4+IKTkDNq1E1kLqKerqwmWQHiUaa7M0GRasU+hO /AjvCMzXX/YjEt1r5K25EtU= X-Google-Smtp-Source: AGHT+IG1vyHSG8awy8FoP43a7HAn2By+9Bt9p19PSjYoPFI4UElEaDsfqufGTRQODkT5OXsGnyrkMA== X-Received: by 2002:a17:902:ec89:b0:1cf:b29d:3e8e with SMTP id x9-20020a170902ec8900b001cfb29d3e8emr4110430plg.58.1702426425811; Tue, 12 Dec 2023 16:13:45 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:45 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 11/17] perf annotate-data: Update sample histogram for type Date: Tue, 12 Dec 2023 16:13:17 -0800 Message-ID: <20231213001323.718046-12-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The annotated_data_type__update_samples() to get histogram for data type access. It'll be called by perf annotate to show which fields in the data type are accessed frequently. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 81 +++++++++++++++++++++++++++++++++ tools/perf/util/annotate-data.h | 42 +++++++++++++++++ tools/perf/util/annotate.c | 9 +++- 3 files changed, 131 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index d9c63e989b6e..9942a87b0664 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -12,6 +12,8 @@ #include "debuginfo.h" #include "debug.h" #include "dso.h" +#include "evsel.h" +#include "evlist.h" #include "map.h" #include "map_symbol.h" #include "strbuf.h" @@ -301,6 +303,44 @@ struct annotated_data_type *find_data_type(struct map_symbol *ms, u64 ip, return result; } +static int alloc_data_type_histograms(struct annotated_data_type *adt, int nr_entries) +{ + int i; + size_t sz = sizeof(struct type_hist); + + sz += sizeof(struct type_hist_entry) * adt->self.size; + + /* Allocate a table of pointers for each event */ + adt->nr_histograms = nr_entries; + adt->histograms = calloc(nr_entries, sizeof(*adt->histograms)); + if (adt->histograms == NULL) + return -ENOMEM; + + /* + * Each histogram is allocated for the whole size of the type. + * TODO: Probably we can move the histogram to members. + */ + for (i = 0; i < nr_entries; i++) { + adt->histograms[i] = zalloc(sz); + if (adt->histograms[i] == NULL) + goto err; + } + return 0; + +err: + while (--i >= 0) + free(adt->histograms[i]); + free(adt->histograms); + return -ENOMEM; +} + +static void delete_data_type_histograms(struct annotated_data_type *adt) +{ + for (int i = 0; i < adt->nr_histograms; i++) + free(adt->histograms[i]); + free(adt->histograms); +} + void annotated_data_type__tree_delete(struct rb_root *root) { struct annotated_data_type *pos; @@ -311,7 +351,48 @@ void annotated_data_type__tree_delete(struct rb_root *root) rb_erase(node, root); pos = rb_entry(node, struct annotated_data_type, node); delete_members(&pos->self); + delete_data_type_histograms(pos); free(pos->self.type_name); free(pos); } } + +/** + * annotated_data_type__update_samples - Update histogram + * @adt: Data type to update + * @evsel: Event to update + * @offset: Offset in the type + * @nr_samples: Number of samples at this offset + * @period: Event count at this offset + * + * This function updates type histogram at @ofs for @evsel. Samples are + * aggregated before calling this function so it can be called with more + * than one samples at a certain offset. + */ +int annotated_data_type__update_samples(struct annotated_data_type *adt, + struct evsel *evsel, int offset, + int nr_samples, u64 period) +{ + struct type_hist *h; + + if (adt == NULL) + return 0; + + if (adt->histograms == NULL) { + int nr = evsel->evlist->core.nr_entries; + + if (alloc_data_type_histograms(adt, nr) < 0) + return -1; + } + + if (offset < 0 || offset >= adt->self.size) + return -1; + + h = adt->histograms[evsel->core.idx]; + + h->nr_samples += nr_samples; + h->addr[offset].nr_samples += nr_samples; + h->period += period; + h->addr[offset].period += period; + return 0; +} diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h index 33748222e6aa..d2dc025b1934 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -7,6 +7,7 @@ #include #include +struct evsel; struct map_symbol; /** @@ -29,16 +30,42 @@ struct annotated_member { int size; }; +/** + * struct type_hist_entry - Histogram entry per offset + * @nr_samples: Number of samples + * @period: Count of event + */ +struct type_hist_entry { + int nr_samples; + u64 period; +}; + +/** + * struct type_hist - Type histogram for each event + * @nr_samples: Total number of samples in this data type + * @period: Total count of the event in this data type + * @offset: Array of histogram entry + */ +struct type_hist { + u64 nr_samples; + u64 period; + struct type_hist_entry addr[]; +}; + /** * struct annotated_data_type - Data type to profile * @node: RB-tree node for dso->type_tree * @self: Actual type information + * @nr_histogram: Number of histogram entries + * @histograms: An array of pointers to histograms * * This represents a data type accessed by samples in the profile data. */ struct annotated_data_type { struct rb_node node; struct annotated_member self; + int nr_histograms; + struct type_hist **histograms; }; extern struct annotated_data_type unknown_type; @@ -49,6 +76,11 @@ extern struct annotated_data_type unknown_type; struct annotated_data_type *find_data_type(struct map_symbol *ms, u64 ip, int reg, int offset); +/* Update type access histogram at the given offset */ +int annotated_data_type__update_samples(struct annotated_data_type *adt, + struct evsel *evsel, int offset, + int nr_samples, u64 period); + /* Release all data type information in the tree */ void annotated_data_type__tree_delete(struct rb_root *root); @@ -61,6 +93,16 @@ find_data_type(struct map_symbol *ms __maybe_unused, u64 ip __maybe_unused, return NULL; } +static inline int +annotated_data_type__update_samples(struct annotated_data_type *adt __maybe_unused, + struct evsel *evsel __maybe_unused, + int offset __maybe_unused, + int nr_samples __maybe_unused, + u64 period __maybe_unused) +{ + return -1; +} + static inline void annotated_data_type__tree_delete(struct rb_root *root __maybe_unused) { } diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 8673eac4b9df..6747779ecef8 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -3679,6 +3679,7 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) struct disasm_line *dl; struct annotated_insn_loc loc; struct annotated_op_loc *op_loc; + struct annotated_data_type *mem_type; u64 ip = he->ip; int i; @@ -3709,7 +3710,13 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) if (!op_loc->mem_ref) continue; - return find_data_type(ms, ip, op_loc->reg, op_loc->offset); + mem_type = find_data_type(ms, ip, op_loc->reg, op_loc->offset); + + annotated_data_type__update_samples(mem_type, evsel, + op_loc->offset, + he->stat.nr_events, + he->stat.period); + return mem_type; } return NULL; } From patchwork Wed Dec 13 00:13:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490197 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="D5DrRpXu" Received: from mail-pl1-x62f.google.com (mail-pl1-x62f.google.com [IPv6:2607:f8b0:4864:20::62f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB15119E; Tue, 12 Dec 2023 16:13:48 -0800 (PST) Received: by mail-pl1-x62f.google.com with SMTP id d9443c01a7336-1d0c4d84bf6so38279105ad.1; Tue, 12 Dec 2023 16:13:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426427; x=1703031227; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=pfai8ZdPoFkOghSjq9znXjq6BNqecnfi+Uhs1ECso1A=; b=D5DrRpXu+zfsX4V3yLUVs3Kul6DMLqDVJEtiqcXuhfTcLYEV+kaUlp/TX2Yh8Pv2wv SeV9Ah1Iy5sNPj6zKTkwb2ZYiBidtG5ySzegpSRiR16AkduK0P0D0qOcDCxOd/slBxEK vhkEixmWWmGiOWosX6dkbklRkikRrBg9HH7MaaECBCRcK0yB65xI7SfwrTsc7EDbCfei qNZ2XWAmUy0d0kFY8t51OR8AP/XwD1ibiwR9cIzB1dZiRpN7c67PsHsS/IdZeaHWeKb1 7Fwy1q/YfQANMREGQBW80mkzzZolAjzxt8whZn7MTaqaj6prmPSaK0Kw1aBYRoYnok+c SEQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426427; x=1703031227; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=pfai8ZdPoFkOghSjq9znXjq6BNqecnfi+Uhs1ECso1A=; b=n5QGPf58e0PZmaiuDbOgWvuUxsmNqNbYttEdP4nca8ce1okW01snUHjnykU56kXbYU zL6cpbGbHl/3o8yV6UzUAGebbDrssb3O07afIHiH2kxgbVWE8FCYA90dWsM2nP2xd+IH E0h/AUJLHgZhNzJTtVThZMGKN6xAswxeciZi/JzYfyO/laB2f3joAZwYVhUPZqter0Ap 4QVFc+hFv/Jmz3QnBt9in2OwMvQsI0OqXG/6VDBfIKCnCZoW3FmGD38E2mHZErPRwsAO glNFo8wgh2Jhr5hdMj8LZpC7mwzxhSan8cRQFYFzz9K1Q020x5eNtx8LpXVciSZPHzoU iRWQ== X-Gm-Message-State: AOJu0Yy+V4N/JMbqwJm6hrx11Lky5nfsInmPJaBF0HSw83j2E8i99yMj 8YJLYbFHxbPNxHwZ3BVZx/0= X-Google-Smtp-Source: AGHT+IEQv/3O/pCqDYWfxLwO4ADDBR5X/wzQSIYVsEkjv/f+oLsDr55MjfGukHUMFYLubX4r99wccg== X-Received: by 2002:a17:903:11cd:b0:1d3:2e0e:c889 with SMTP id q13-20020a17090311cd00b001d32e0ec889mr2318864plh.62.1702426427405; Tue, 12 Dec 2023 16:13:47 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:46 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 12/17] perf report: Add 'typeoff' sort key Date: Tue, 12 Dec 2023 16:13:18 -0800 Message-ID: <20231213001323.718046-13-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The typeoff sort key shows the data type name, offset and the name of the field. This is useful to see which field in the struct is accessed most frequently. $ perf report -s type,typeoff --hierarchy --stdio ... # Overhead Data Type / Data Type Offset # ............ ............................ # ... 1.23% struct cfs_rq 0.19% struct cfs_rq +404 (throttle_count) 0.19% struct cfs_rq +0 (load.weight) 0.19% struct cfs_rq +336 (leaf_cfs_rq_list.next) 0.09% struct cfs_rq +272 (propagate) 0.09% struct cfs_rq +196 (removed.nr) 0.09% struct cfs_rq +80 (curr) 0.09% struct cfs_rq +544 (lt_b_children_throttled) 0.06% struct cfs_rq +320 (rq) Signed-off-by: Namhyung Kim --- tools/perf/Documentation/perf-report.txt | 1 + tools/perf/util/annotate.c | 1 + tools/perf/util/hist.h | 1 + tools/perf/util/sort.c | 83 +++++++++++++++++++++++- tools/perf/util/sort.h | 2 + 5 files changed, 87 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index aec34417090b..b57eb51b47aa 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -119,6 +119,7 @@ OPTIONS to the previous instruction in cycles. And currently supported only on X86 - simd: Flags describing a SIMD operation. "e" for empty Arm SVE predicate. "p" for partial Arm SVE predicate - type: Data type of sample memory access. + - typeoff: Offset in the data type of sample memory access. By default, comm, dso and symbol keys are used. (i.e. --sort comm,dso,symbol) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 6747779ecef8..f966e8f83c5e 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -3716,6 +3716,7 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) op_loc->offset, he->stat.nr_events, he->stat.period); + he->mem_type_off = op_loc->offset; return mem_type; } return NULL; diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 7ebbf427b1ea..18128a49309e 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -83,6 +83,7 @@ enum hist_column { HISTC_ADDR, HISTC_SIMD, HISTC_TYPE, + HISTC_TYPE_OFFSET, HISTC_NR_COLS, /* Last entry */ }; diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index a41209e242ae..d78e680d3988 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -2153,8 +2153,10 @@ static void sort__type_init(struct hist_entry *he) return; he->mem_type = hist_entry__get_data_type(he); - if (he->mem_type == NULL) + if (he->mem_type == NULL) { he->mem_type = &unknown_type; + he->mem_type_off = 0; + } } static int64_t @@ -2198,6 +2200,84 @@ struct sort_entry sort_type = { .se_width_idx = HISTC_TYPE, }; +/* --sort typeoff */ + +static int64_t +sort__typeoff_sort(struct hist_entry *left, struct hist_entry *right) +{ + struct annotated_data_type *left_type = left->mem_type; + struct annotated_data_type *right_type = right->mem_type; + int64_t ret; + + if (!left_type) { + sort__type_init(left); + left_type = left->mem_type; + } + + if (!right_type) { + sort__type_init(right); + right_type = right->mem_type; + } + + ret = strcmp(left_type->self.type_name, right_type->self.type_name); + if (ret) + return ret; + return left->mem_type_off - right->mem_type_off; +} + +static void fill_member_name(char *buf, size_t sz, struct annotated_member *m, + int offset, bool first) +{ + struct annotated_member *child; + + if (list_empty(&m->children)) + return; + + list_for_each_entry(child, &m->children, node) { + if (child->offset <= offset && offset < child->offset + child->size) { + int len = 0; + + /* It can have anonymous struct/union members */ + if (child->var_name) { + len = scnprintf(buf, sz, "%s%s", + first ? "" : ".", child->var_name); + first = false; + } + + fill_member_name(buf + len, sz - len, child, offset, first); + return; + } + } +} + +static int hist_entry__typeoff_snprintf(struct hist_entry *he, char *bf, + size_t size, unsigned int width __maybe_unused) +{ + struct annotated_data_type *he_type = he->mem_type; + char buf[4096]; + + buf[0] = '\0'; + if (list_empty(&he_type->self.children)) + snprintf(buf, sizeof(buf), "no field"); + else + fill_member_name(buf, sizeof(buf), &he_type->self, + he->mem_type_off, true); + buf[4095] = '\0'; + + return repsep_snprintf(bf, size, "%s %+d (%s)", he_type->self.type_name, + he->mem_type_off, buf); +} + +struct sort_entry sort_type_offset = { + .se_header = "Data Type Offset", + .se_cmp = sort__type_cmp, + .se_collapse = sort__typeoff_sort, + .se_sort = sort__typeoff_sort, + .se_init = sort__type_init, + .se_snprintf = hist_entry__typeoff_snprintf, + .se_width_idx = HISTC_TYPE_OFFSET, +}; + struct sort_dimension { const char *name; @@ -2254,6 +2334,7 @@ static struct sort_dimension common_sort_dimensions[] = { DIM(SORT_GLOBAL_RETIRE_LAT, "retire_lat", sort_global_p_stage_cyc), DIM(SORT_SIMD, "simd", sort_simd), DIM(SORT_ANNOTATE_DATA_TYPE, "type", sort_type), + DIM(SORT_ANNOTATE_DATA_TYPE_OFFSET, "typeoff", sort_type_offset), }; #undef DIM diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index aabf0b8331a3..d806adcc1e1e 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -113,6 +113,7 @@ struct hist_entry { u64 p_stage_cyc; u8 cpumode; u8 depth; + int mem_type_off; struct simd_flags simd_flags; /* We are added by hists__add_dummy_entry. */ @@ -247,6 +248,7 @@ enum sort_type { SORT_GLOBAL_RETIRE_LAT, SORT_SIMD, SORT_ANNOTATE_DATA_TYPE, + SORT_ANNOTATE_DATA_TYPE_OFFSET, /* branch stack specific sort keys */ __SORT_BRANCH_STACK, From patchwork Wed Dec 13 00:13:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490198 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="YB5Gx0Vh" Received: from mail-pl1-x631.google.com (mail-pl1-x631.google.com [IPv6:2607:f8b0:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6FC971BF; Tue, 12 Dec 2023 16:13:51 -0800 (PST) Received: by mail-pl1-x631.google.com with SMTP id d9443c01a7336-1d0ccda19eeso39492205ad.1; Tue, 12 Dec 2023 16:13:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426429; x=1703031229; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=Q4UEMHhiignCwX0EjxC7/0B5MhyjQn86th3on3YHVjY=; b=YB5Gx0VhKM5KpNaWf89X3AlRS615oRwOZdVZp8nk2SQAzwyh/cSwYb5KRIF5w27PmP Wz1gtz12XqO8kTP4Wjgcc6Fs2/ZzN8msPZAPtbOrYEM79Bvl7UCw4QrN+R95LXR0fGEj kXX2ez7f7ysEaSv8mM3eUJoUoH6hYutfZYBnscJDT2Mr5vchIX8RtowfB7bnF83JGkj9 MiqlB5ZU9Vz+F7kRpAR6MwFWggR68YgygOY9Ir4X8/OQG5O49N+Bao+eCmAGCXz6e3OG MrZe+0aPQBLKw1GkND4JbwSVaQTxbIoZhknaFNMRJeGqlBIc3qDhE6ZDI4F5elmqXHc7 DZ2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426429; x=1703031229; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Q4UEMHhiignCwX0EjxC7/0B5MhyjQn86th3on3YHVjY=; b=ihe4CqDf45HpVjBcaLrIzI0vbE8o+qnmz82u5Kg8qRawq7WF0Gq2FjibUOjPrqXacO s+rRmhIrHIqLFndwQqmiThxkH5f/8q/5n9ZSvGGGA5zWRkVNz+VbIAXJp2m7NluGTCOc lFapJf59LM5pzQWrQZPZP29Nw6tPcVFyx+RTWKyIdNoB9dykLYJfQKeYyWlwkhej5OSo 7mTIvzXnR0u+XlaMheWtHcji8aslmT4S+zkXiOWUSZkI71Xwr0EIzzTIHBPlBPrWMbjJ dDGJ0ri4wjbmRvKkvOQhhThMsqRTgOkCEU56kBT1gEDZl1myK/PWHonNdHXckenKFgVS JneA== X-Gm-Message-State: AOJu0YwBBgkPk/+VOAUfzOaRV6Ltjy7yuu1x9syHmm/5j1wV7u5HqD2V AKBE/zBJZl04WUgLgo0v+5U= X-Google-Smtp-Source: AGHT+IF1ppacjeHy1QfN9R1urpl1T+hzGF2wUXlm405kbRKcpjG2u6jFQo0KPZygdhNc6Ot3ItKiRg== X-Received: by 2002:a17:903:44a:b0:1cc:446c:770c with SMTP id iw10-20020a170903044a00b001cc446c770cmr3763140plb.33.1702426429067; Tue, 12 Dec 2023 16:13:49 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:48 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 13/17] perf report: Add 'symoff' sort key Date: Tue, 12 Dec 2023 16:13:19 -0800 Message-ID: <20231213001323.718046-14-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The symoff sort key is to print symbol and offset of sample. This is useful for data type profiling to show exact instruction in the function which refers the data. $ perf report -s type,sym,typeoff,symoff --hierarchy ... # Overhead Data Type / Symbol / Data Type Offset / Symbol Offset # .............. ..................................................... # 1.23% struct cfs_rq 0.84% update_blocked_averages 0.19% struct cfs_rq +336 (leaf_cfs_rq_list.next) 0.19% [k] update_blocked_averages+0x96 0.19% struct cfs_rq +0 (load.weight) 0.14% [k] update_blocked_averages+0x104 0.04% [k] update_blocked_averages+0x31c 0.17% struct cfs_rq +404 (throttle_count) 0.12% [k] update_blocked_averages+0x9d 0.05% [k] update_blocked_averages+0x1f9 0.08% struct cfs_rq +272 (propagate) 0.07% [k] update_blocked_averages+0x3d3 0.02% [k] update_blocked_averages+0x45b ... Signed-off-by: Namhyung Kim --- tools/perf/Documentation/perf-report.txt | 1 + tools/perf/util/hist.h | 1 + tools/perf/util/sort.c | 47 ++++++++++++++++++++++++ tools/perf/util/sort.h | 1 + 4 files changed, 50 insertions(+) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index b57eb51b47aa..38f59ac064f7 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -120,6 +120,7 @@ OPTIONS - simd: Flags describing a SIMD operation. "e" for empty Arm SVE predicate. "p" for partial Arm SVE predicate - type: Data type of sample memory access. - typeoff: Offset in the data type of sample memory access. + - symoff: Offset in the symbol. By default, comm, dso and symbol keys are used. (i.e. --sort comm,dso,symbol) diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 18128a49309e..4a0aea0c9e00 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -84,6 +84,7 @@ enum hist_column { HISTC_SIMD, HISTC_TYPE, HISTC_TYPE_OFFSET, + HISTC_SYMBOL_OFFSET, HISTC_NR_COLS, /* Last entry */ }; diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index d78e680d3988..0cbbd5ba8175 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -419,6 +419,52 @@ struct sort_entry sort_sym = { .se_width_idx = HISTC_SYMBOL, }; +/* --sort symoff */ + +static int64_t +sort__symoff_cmp(struct hist_entry *left, struct hist_entry *right) +{ + int64_t ret; + + ret = sort__sym_cmp(left, right); + if (ret) + return ret; + + return left->ip - right->ip; +} + +static int64_t +sort__symoff_sort(struct hist_entry *left, struct hist_entry *right) +{ + int64_t ret; + + ret = sort__sym_sort(left, right); + if (ret) + return ret; + + return left->ip - right->ip; +} + +static int +hist_entry__symoff_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) +{ + struct symbol *sym = he->ms.sym; + + if (sym == NULL) + return repsep_snprintf(bf, size, "[%c] %-#.*llx", he->level, width - 4, he->ip); + + return repsep_snprintf(bf, size, "[%c] %s+0x%llx", he->level, sym->name, he->ip - sym->start); +} + +struct sort_entry sort_sym_offset = { + .se_header = "Symbol Offset", + .se_cmp = sort__symoff_cmp, + .se_sort = sort__symoff_sort, + .se_snprintf = hist_entry__symoff_snprintf, + .se_filter = hist_entry__sym_filter, + .se_width_idx = HISTC_SYMBOL_OFFSET, +}; + /* --sort srcline */ char *hist_entry__srcline(struct hist_entry *he) @@ -2335,6 +2381,7 @@ static struct sort_dimension common_sort_dimensions[] = { DIM(SORT_SIMD, "simd", sort_simd), DIM(SORT_ANNOTATE_DATA_TYPE, "type", sort_type), DIM(SORT_ANNOTATE_DATA_TYPE_OFFSET, "typeoff", sort_type_offset), + DIM(SORT_SYM_OFFSET, "symoff", sort_sym_offset), }; #undef DIM diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index d806adcc1e1e..6f6b4189a389 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -249,6 +249,7 @@ enum sort_type { SORT_SIMD, SORT_ANNOTATE_DATA_TYPE, SORT_ANNOTATE_DATA_TYPE_OFFSET, + SORT_SYM_OFFSET, /* branch stack specific sort keys */ __SORT_BRANCH_STACK, From patchwork Wed Dec 13 00:13:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490199 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fqxPwFAG" Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AD37810E; Tue, 12 Dec 2023 16:13:53 -0800 (PST) Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-1d336760e72so12470045ad.3; Tue, 12 Dec 2023 16:13:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426431; x=1703031231; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=b2XDRHe3hVdb0VRyKswuL5JnyalndJNwy6dou82qAxk=; b=fqxPwFAG8DhExsJoYn3nQi/ny3FB/oLe0adW+iecJjuZn5kxr3ApRqqlM8c5tWc7GM hBrhel7qMDcpIgW3Q6j4FYeWX0+Oq6Rs6rUfes5oreJEVuAB/2wXZ6qZlei43R/oVTph UObwS9FeTg7tQ2bBwQWCChR00CcfUdIjVgbvUXN/HizYjSIF2mSXl/IFkivL89jGg05e Xw0K+HdPstREIS5ZthO0+SB0Qe9MAnMUe/nFSULdnovNcr8n+E2ctqgThcOv66qcHfai gkCdsir6IGf6NgT9nMExkOOeh+sC/iceQHtpbKRmkiMOyb6mB1kr/5se1Ch4XlhSixkD EwEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426431; x=1703031231; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=b2XDRHe3hVdb0VRyKswuL5JnyalndJNwy6dou82qAxk=; b=igOKGn7yJS2AuryyVINEbm4iHsSnnHvzrnyjzutfNF1HSWBN67YjbAH0/Pbv91r3n7 v+cYPf3my1Bs1UFiz6Qt/lsSV3kNhgo1jQxDfz8hm5FVLdlqDQWs4b60GBp7jEo+F+ac Nu4FBpYALauKZcsZy2rX/XLoiQFo/iQHaPK639ZvKNMgfQUgCw7Nzyno4wySCdUR5My5 Pio4zXixphkkJWbgmsVhx1RJZyj7F0QuWyJtkc7b8IjdFlSvxD6xB0MDzfCLb0+VRLdP derk9ftSww/+NHnE5Gz8OkVOQ6A6whEm9a3zknjNzM8K0JSuNjmkwlGbmMqaX05lNu1G n52w== X-Gm-Message-State: AOJu0YyRZ5Fs7pzj2Kk/5Arz9tmIM1pK5wN6Nj+uFt4Y2Nb4GHL+IPyT IZQ+KSEoRur4Iw6U6JzjGx8= X-Google-Smtp-Source: AGHT+IHWhmH+Hv19SHfk6K7ZVAnHZ7QxMYCRT0e6s5fQAqR/T2RX30oAsz7HpG715oWq+/f5xLb+LQ== X-Received: by 2002:a17:903:2b0f:b0:1d3:44ad:2156 with SMTP id mc15-20020a1709032b0f00b001d344ad2156mr1490405plb.2.1702426431031; Tue, 12 Dec 2023 16:13:51 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:50 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 14/17] perf annotate: Add --data-type option Date: Tue, 12 Dec 2023 16:13:20 -0800 Message-ID: <20231213001323.718046-15-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Support data type annotation with new --data-type option. It internally uses type sort key to collect sample histogram for the type and display every members like below. $ perf annotate --data-type ... Annotate type: 'struct cfs_rq' in [kernel.kallsyms] (13 samples): ============================================================================ samples offset size field 13 0 640 struct cfs_rq { 2 0 16 struct load_weight load { 2 0 8 unsigned long weight; 0 8 4 u32 inv_weight; }; 0 16 8 unsigned long runnable_weight; 0 24 4 unsigned int nr_running; 1 28 4 unsigned int h_nr_running; ... For simplicity it prints the number of samples per field for now. But it should be easy to show the overhead percentage instead. The number at the outer struct is a sum of the numbers of the inner members. For example, struct cfs_rq got total 13 samples, and 2 came from the load (struct load_weight) and 1 from h_nr_running. Similarly, the struct load_weight got total 2 samples and they all came from the weight field. I've added two new flags in the symbol_conf for this. The annotate_data_member is to get the members of the type. This is also needed for perf report with typeoff sort key. The annotate_data_sample is to update sample stats for each offset and used only in annotate. Currently it only support stdio output mode, TUI support can be added later. Signed-off-by: Namhyung Kim --- tools/perf/Documentation/perf-annotate.txt | 8 ++ tools/perf/builtin-annotate.c | 97 +++++++++++++++++++++- tools/perf/util/annotate-data.c | 8 +- tools/perf/util/annotate.c | 10 ++- tools/perf/util/sort.c | 2 + tools/perf/util/symbol_conf.h | 4 +- 6 files changed, 118 insertions(+), 11 deletions(-) diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt index fe168e8165c8..0e6a49b7795c 100644 --- a/tools/perf/Documentation/perf-annotate.txt +++ b/tools/perf/Documentation/perf-annotate.txt @@ -155,6 +155,14 @@ include::itrace.txt[] stdio or stdio2 (Default: 0). Note that this is about selection of functions to display, not about lines within the function. +--data-type[=TYPE_NAME]:: + Display data type annotation instead of code. It infers data type of + samples (if they are memory accessing instructions) using DWARF debug + information. It can take an optional argument of data type name. In + that case it'd show annotation for the type only, otherwise it'd show + all data types it finds. + + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-report[1] diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index d880f1b039fd..8acfbbc1b9c2 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -20,6 +20,7 @@ #include "util/evlist.h" #include "util/evsel.h" #include "util/annotate.h" +#include "util/annotate-data.h" #include "util/event.h" #include #include "util/parse-events.h" @@ -55,9 +56,11 @@ struct perf_annotate { bool skip_missing; bool has_br_stack; bool group_set; + bool data_type; float min_percent; const char *sym_hist_filter; const char *cpu_list; + const char *target_data_type; DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); }; @@ -322,6 +325,32 @@ static int hist_entry__tty_annotate(struct hist_entry *he, return symbol__tty_annotate2(&he->ms, evsel); } +static void print_annotated_data_type(struct annotated_data_type *mem_type, + struct annotated_member *member, + struct evsel *evsel, int indent) +{ + struct annotated_member *child; + struct type_hist *h = mem_type->histograms[evsel->core.idx]; + int i, samples = 0; + + for (i = 0; i < member->size; i++) + samples += h->addr[member->offset + i].nr_samples; + + printf(" %10d %10d %10d %*s%s\t%s", + samples, member->offset, member->size, indent, "", member->type_name, + member->var_name ?: ""); + + if (!list_empty(&member->children)) + printf(" {\n"); + + list_for_each_entry(child, &member->children, node) + print_annotated_data_type(mem_type, child, evsel, indent + 4); + + if (!list_empty(&member->children)) + printf("%*s}", 35 + indent, ""); + printf(";\n"); +} + static void hists__find_annotations(struct hists *hists, struct evsel *evsel, struct perf_annotate *ann) @@ -361,6 +390,40 @@ static void hists__find_annotations(struct hists *hists, continue; } + if (ann->data_type) { + struct dso *dso = map__dso(he->ms.map); + + /* skip unknown type */ + if (he->mem_type->histograms == NULL) + goto find_next; + + if (ann->target_data_type) { + const char *type_name = he->mem_type->self.type_name; + + /* skip 'struct ' prefix in the type name */ + if (strncmp(ann->target_data_type, "struct ", 7) && + !strncmp(type_name, "struct ", 7)) + type_name += 7; + + /* skip 'union ' prefix in the type name */ + if (strncmp(ann->target_data_type, "union ", 6) && + !strncmp(type_name, "union ", 6)) + type_name += 6; + + if (strcmp(ann->target_data_type, type_name)) + goto find_next; + } + + printf("Annotate type: '%s' in %s (%d samples):\n", + he->mem_type->self.type_name, dso->name, he->stat.nr_events); + printf("============================================================================\n"); + printf(" %10s %10s %10s %s\n", "samples", "offset", "size", "field"); + + print_annotated_data_type(he->mem_type, &he->mem_type->self, evsel, 0); + printf("\n"); + goto find_next; + } + if (use_browser == 2) { int ret; int (*annotate)(struct hist_entry *he, @@ -496,6 +559,17 @@ static int parse_percent_limit(const struct option *opt, const char *str, return 0; } +static int parse_data_type(const struct option *opt, const char *str, int unset) +{ + struct perf_annotate *ann = opt->value; + + ann->data_type = !unset; + if (str) + ann->target_data_type = strdup(str); + + return 0; +} + static const char * const annotate_usage[] = { "perf annotate []", NULL @@ -607,6 +681,9 @@ int cmd_annotate(int argc, const char **argv) OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", "Instruction Tracing options\n" ITRACE_HELP, itrace_parse_synth_opts), + OPT_CALLBACK_OPTARG(0, "data-type", &annotate, NULL, "name", + "Show data type annotate for the memory accesses", + parse_data_type), OPT_END() }; @@ -661,6 +738,13 @@ int cmd_annotate(int argc, const char **argv) } #endif +#ifndef HAVE_DWARF_GETLOCATIONS_SUPPORT + if (annotate.data_type) { + pr_err("Error: Data type profiling is disabled due to missing DWARF support\n"); + return -ENOTSUP; + } +#endif + ret = symbol__validate_sym_arguments(); if (ret) return ret; @@ -703,6 +787,14 @@ int cmd_annotate(int argc, const char **argv) use_browser = 2; #endif + /* FIXME: only support stdio for now */ + if (annotate.data_type) { + use_browser = 0; + annotate_opts.annotate_src = false; + symbol_conf.annotate_data_member = true; + symbol_conf.annotate_data_sample = true; + } + setup_browser(true); /* @@ -710,7 +802,10 @@ int cmd_annotate(int argc, const char **argv) * symbol, we do not care about the processes in annotate, * set sort order to avoid repeated output. */ - sort_order = "dso,symbol"; + if (annotate.data_type) + sort_order = "dso,type"; + else + sort_order = "dso,symbol"; /* * Set SORT_MODE__BRANCH so that annotate display IPC/Cycle diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index 9942a87b0664..06be6b279d6a 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -18,6 +18,7 @@ #include "map_symbol.h" #include "strbuf.h" #include "symbol.h" +#include "symbol_conf.h" /* * Compare type name and size to maintain them in a tree. @@ -157,11 +158,8 @@ static struct annotated_data_type *dso__findnew_data_type(struct dso *dso, result->self.size = size; INIT_LIST_HEAD(&result->self.children); - /* - * Fill member info unconditionally for now, - * later perf annotate would need it. - */ - add_member_types(result, type_die); + if (symbol_conf.annotate_data_member) + add_member_types(result, type_die); rb_add(&result->node, &dso->data_types, data_type_less); return result; diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index f966e8f83c5e..68424ee0215e 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -3712,10 +3712,12 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) mem_type = find_data_type(ms, ip, op_loc->reg, op_loc->offset); - annotated_data_type__update_samples(mem_type, evsel, - op_loc->offset, - he->stat.nr_events, - he->stat.period); + if (symbol_conf.annotate_data_sample) { + annotated_data_type__update_samples(mem_type, evsel, + op_loc->offset, + he->stat.nr_events, + he->stat.period); + } he->mem_type_off = op_loc->offset; return mem_type; } diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 0cbbd5ba8175..30254eb63709 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -3401,6 +3401,8 @@ int sort_dimension__add(struct perf_hpp_list *list, const char *tok, list->thread = 1; } else if (sd->entry == &sort_comm) { list->comm = 1; + } else if (sd->entry == &sort_type_offset) { + symbol_conf.annotate_data_member = true; } return __sort_dimension__add(sd, list, level); diff --git a/tools/perf/util/symbol_conf.h b/tools/perf/util/symbol_conf.h index 6040286e07a6..c114bbceef40 100644 --- a/tools/perf/util/symbol_conf.h +++ b/tools/perf/util/symbol_conf.h @@ -44,7 +44,9 @@ struct symbol_conf { buildid_mmap2, guest_code, lazy_load_kernel_maps, - keep_exited_threads; + keep_exited_threads, + annotate_data_member, + annotate_data_sample; const char *vmlinux_name, *kallsyms_name, *source_prefix, From patchwork Wed Dec 13 00:13:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490200 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Lof7l3mS" Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F41DED54; Tue, 12 Dec 2023 16:13:54 -0800 (PST) Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-1d06819a9cbso38208615ad.1; Tue, 12 Dec 2023 16:13:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426433; x=1703031233; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=VxLAF5RjXuu8mgch2ETJfxdZfj9JgVVMGl5qHF6yEa4=; b=Lof7l3mSxSFZZktBxx/wmeIf5p7QoPcHcEhSEq2/k7hzIwb8hqBUm2WT7JmvJwZjl0 tXpagBxvR4Sv5efpIbw8AIDQZ8jPSzQhGsIIBB9OsucpsPA+HJc2E8/OmRUdDp3TE3Vf 0DfKsqeo0cGxCVQcWEeC+GKfzomXDUH++tTgHWuz4Na7HiMeSUBJvkf061sqluZz8pN+ 8O/8hJ4igbw6bkuKW4iLxR56V6FQW/4oCwhiereE/gz8fAELa+y8LVv8h56+SwTkSmWj 94Ec5nvp3jeTSbjbeZpkPyWXftPNpNP+9ptgSojKJdMclqXsrPGM6VC0wgG1MOEaTxEo Ef2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426433; x=1703031233; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=VxLAF5RjXuu8mgch2ETJfxdZfj9JgVVMGl5qHF6yEa4=; b=vGoyUPDq7QZr/TqQ45L1Pd29xxn0am2LCzNYe0y6Y7N1XhsPBZIDoqN8etmAxm//p8 MXSZQZH4yIzKqde9Rb/MlkGWxYc/QRrAx8dt5yalCkAeYF0eluQP9jLTzPssrxaUjfJE 4h/2x6stsydXeTtpLkbmXWayuvz8gFRJ50um0Y/D/R2Fa08wuxE+lUW7YtKZHfsXb2ne BnuAXLg/7KaTtrWsuM1YhnnF1gK2Jau3V9iBO611fWuMrTpVGm30N7xV6ccf6jKa9gOY l6YsQxBOJVi+WOKpUTHzbF/OkTz0V3crcNZ8yTOb+Y+lGDRHglfcqfbL4/aPncSohjJg e05Q== X-Gm-Message-State: AOJu0YxgAY8R6I1w1/JXkVAQ7dV3ZQY6tqtSC8HmLC97Sax1CfmiGBz/ L8JF0tGdaCLXxw7tYTH0RUY= X-Google-Smtp-Source: AGHT+IEr6tiiQWA+np8ums6vuW+JECMdOvPW+LcNfuzmkf6oyx4mYwGqbVcoOpzvw3Jy31EM/I1MPw== X-Received: by 2002:a17:903:1c3:b0:1d3:4783:ce7 with SMTP id e3-20020a17090301c300b001d347830ce7mr860001plh.103.1702426432635; Tue, 12 Dec 2023 16:13:52 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:51 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 15/17] perf annotate: Support event group display Date: Tue, 12 Dec 2023 16:13:21 -0800 Message-ID: <20231213001323.718046-16-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 When events are grouped together, it'd be natural to show them at once like in other mode. Handle group leaders with members to collect the number of samples together and display like below: $ perf annotate --data-type --group ... Annotate type: 'struct page' in vmlinux (1 samples): event[0] = cpu/mem-loads,ldlat=30/P event[1] = cpu/mem-stores/P event[2] = dummy:u ============================================================================ samples offset size field 1 0 0 0 64 struct page { 0 0 0 0 8 long unsigned int flags; 0 0 0 8 40 union { 0 0 0 8 40 struct { 0 0 0 8 16 union { 0 0 0 8 16 struct list_head lru { 0 0 0 8 8 struct list_head* next; 0 0 0 16 8 struct list_head* prev; }; 0 0 0 8 16 struct { 0 0 0 8 8 void* __filler; 0 0 0 16 4 unsigned int mlock_count; }; 0 0 0 8 16 struct list_head buddy_list { 0 0 0 8 8 struct list_head* next; 0 0 0 16 8 struct list_head* prev; }; Signed-off-by: Namhyung Kim --- tools/perf/builtin-annotate.c | 89 ++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 8acfbbc1b9c2..3956ea1334cc 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -325,19 +325,64 @@ static int hist_entry__tty_annotate(struct hist_entry *he, return symbol__tty_annotate2(&he->ms, evsel); } +static void print_annotated_data_header(struct hist_entry *he, struct evsel *evsel) +{ + struct dso *dso = map__dso(he->ms.map); + int nr_members = 1; + int nr_samples = he->stat.nr_events; + + if (evsel__is_group_event(evsel)) { + struct hist_entry *pair; + + list_for_each_entry(pair, &he->pairs.head, pairs.node) + nr_samples += pair->stat.nr_events; + } + + printf("Annotate type: '%s' in %s (%d samples):\n", + he->mem_type->self.type_name, dso->name, nr_samples); + + if (evsel__is_group_event(evsel)) { + struct evsel *pos; + int i = 0; + + for_each_group_evsel(pos, evsel) + printf(" event[%d] = %s\n", i++, pos->name); + + nr_members = evsel->core.nr_members; + } + + printf("============================================================================\n"); + printf("%*s %10s %10s %s\n", 11 * nr_members, "samples", "offset", "size", "field"); +} + static void print_annotated_data_type(struct annotated_data_type *mem_type, struct annotated_member *member, struct evsel *evsel, int indent) { struct annotated_member *child; struct type_hist *h = mem_type->histograms[evsel->core.idx]; - int i, samples = 0; + int i, nr_events = 1, samples = 0; for (i = 0; i < member->size; i++) samples += h->addr[member->offset + i].nr_samples; + printf(" %10d", samples); + + if (evsel__is_group_event(evsel)) { + struct evsel *pos; + + for_each_group_member(pos, evsel) { + h = mem_type->histograms[pos->core.idx]; + + samples = 0; + for (i = 0; i < member->size; i++) + samples += h->addr[member->offset + i].nr_samples; + printf(" %10d", samples); + } + nr_events = evsel->core.nr_members; + } - printf(" %10d %10d %10d %*s%s\t%s", - samples, member->offset, member->size, indent, "", member->type_name, + printf(" %10d %10d %*s%s\t%s", + member->offset, member->size, indent, "", member->type_name, member->var_name ?: ""); if (!list_empty(&member->children)) @@ -347,7 +392,7 @@ static void print_annotated_data_type(struct annotated_data_type *mem_type, print_annotated_data_type(mem_type, child, evsel, indent + 4); if (!list_empty(&member->children)) - printf("%*s}", 35 + indent, ""); + printf("%*s}", 11 * nr_events + 24 + indent, ""); printf(";\n"); } @@ -391,8 +436,6 @@ static void hists__find_annotations(struct hists *hists, } if (ann->data_type) { - struct dso *dso = map__dso(he->ms.map); - /* skip unknown type */ if (he->mem_type->histograms == NULL) goto find_next; @@ -414,11 +457,7 @@ static void hists__find_annotations(struct hists *hists, goto find_next; } - printf("Annotate type: '%s' in %s (%d samples):\n", - he->mem_type->self.type_name, dso->name, he->stat.nr_events); - printf("============================================================================\n"); - printf(" %10s %10s %10s %s\n", "samples", "offset", "size", "field"); - + print_annotated_data_header(he, evsel); print_annotated_data_type(he->mem_type, &he->mem_type->self, evsel, 0); printf("\n"); goto find_next; @@ -521,8 +560,20 @@ static int __cmd_annotate(struct perf_annotate *ann) evsel__reset_sample_bit(pos, CALLCHAIN); evsel__output_resort(pos, NULL); - if (symbol_conf.event_group && !evsel__is_group_leader(pos)) + /* + * An event group needs to display other events too. + * Let's delay printing until other events are processed. + */ + if (symbol_conf.event_group) { + if (!evsel__is_group_leader(pos)) { + struct hists *leader_hists; + + leader_hists = evsel__hists(evsel__leader(pos)); + hists__match(leader_hists, hists); + hists__link(leader_hists, hists); + } continue; + } hists__find_annotations(hists, pos, ann); } @@ -533,6 +584,20 @@ static int __cmd_annotate(struct perf_annotate *ann) goto out; } + /* Display group events together */ + evlist__for_each_entry(session->evlist, pos) { + struct hists *hists = evsel__hists(pos); + u32 nr_samples = hists->stats.nr_samples; + + if (nr_samples == 0) + continue; + + if (!symbol_conf.event_group || !evsel__is_group_leader(pos)) + continue; + + hists__find_annotations(hists, pos, ann); + } + if (use_browser == 2) { void (*show_annotations)(void); From patchwork Wed Dec 13 00:13:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="VvPOwh2D" Received: from mail-pg1-x52c.google.com (mail-pg1-x52c.google.com [IPv6:2607:f8b0:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B88ADD7F; Tue, 12 Dec 2023 16:13:55 -0800 (PST) Received: by mail-pg1-x52c.google.com with SMTP id 41be03b00d2f7-5bcfc508d14so5356312a12.3; Tue, 12 Dec 2023 16:13:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426434; x=1703031234; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=xr891Vz5SQNxL8Og5romUrWd4YL5FuA0hfmf+OmYlyU=; b=VvPOwh2DAeUuySNWhCsJnkd6xJWGJdTzKxLRt2M23ZlNY5j95o8RzQuVXjKedmm2J3 dhaa13jCmKC51BiJTkRAh57ZBzImBEossEEskaE+E7E4Jcq2UYNcN12TYBevSN+B2DDL aJARlg9qTU+ndBcXSlGMTn5K4tZ/2FL6xUV7UOl3TeoSEqL6rL0qg/0xYdalvud1AdhK fR/0mIllV+sY68jEjTFd+cobauJ2DeblykPpffh8hkgV6v3l63z/HnZs/htaqo3KbygV zrekOeOa1djZs8vXddG1BWG/sjPM01dAToBy3ce5HqY7jbv3V6AchZrVtyfigFIc6ZDz OcAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426434; x=1703031234; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=xr891Vz5SQNxL8Og5romUrWd4YL5FuA0hfmf+OmYlyU=; b=H4zdyP1XcsUpOL8sIQ7jhbQidPmKmJ5+AvMZMT5Druura8xYsVr56fQF1xR+jwhpVH HEIPALu95otNnSSZfrryEv4tQ0rERPvyb0CvBlsd8H6qy7h/HjVP45Z3tOza3I8h4ucu knXehqayJ4kdWYnjeT1YGTmXg5E+NSQkHnSLBcwl4Xx9g1wAzMBgqwWa96rk1/ncElno gGabx4mFYIdatsRTgN0JdFLBK5Corg8+DdHAyaliCEutJ+nfq3hRh9LXHKTlMbhGvMeS PdcWiwkLyz+Mj9Aai1jCkcHXX9K6TcvbA5Yk9PboCVJZi1GL1N/nkah9hnFHmxMcqyF+ CVrg== X-Gm-Message-State: AOJu0YyT7aHvHDs+9J9cw0XmiSuAaf7rkr7K2Tq6Tqrr32qodALV4cnG MmLnZZIHexsZF/woqjAdvCE= X-Google-Smtp-Source: AGHT+IE46oXXhVdBoTIveX4yK2e7/LYlmjd18PJR//mvVD/fTbDIBQPtLrXgUW4acvUGUDkth9W+rw== X-Received: by 2002:a17:902:e84d:b0:1cc:548d:4252 with SMTP id t13-20020a170902e84d00b001cc548d4252mr8789872plg.57.1702426434212; Tue, 12 Dec 2023 16:13:54 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:53 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 16/17] perf annotate: Add --type-stat option for debugging Date: Tue, 12 Dec 2023 16:13:22 -0800 Message-ID: <20231213001323.718046-17-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The --type-stat option is to be used with --data-type and to print detailed failure reasons for the data type annotation. $ perf annotate --data-type --type-stat Annotate data type stats: total 294, ok 116 (39.5%), bad 178 (60.5%) ----------------------------------------------------------- 30 : no_sym 40 : no_insn_ops 33 : no_mem_ops 63 : no_var 4 : no_typeinfo 8 : bad_offset Signed-off-by: Namhyung Kim --- tools/perf/Documentation/perf-annotate.txt | 3 ++ tools/perf/builtin-annotate.c | 44 +++++++++++++++++++++- tools/perf/util/annotate-data.c | 10 ++++- tools/perf/util/annotate-data.h | 31 +++++++++++++++ tools/perf/util/annotate.c | 27 ++++++++++--- 5 files changed, 108 insertions(+), 7 deletions(-) diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt index 0e6a49b7795c..b95524bea021 100644 --- a/tools/perf/Documentation/perf-annotate.txt +++ b/tools/perf/Documentation/perf-annotate.txt @@ -162,6 +162,9 @@ include::itrace.txt[] that case it'd show annotation for the type only, otherwise it'd show all data types it finds. +--type-stat:: + Show stats for the data type annotation. + SEE ALSO -------- diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 3956ea1334cc..55f97ab1395b 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -57,6 +57,7 @@ struct perf_annotate { bool has_br_stack; bool group_set; bool data_type; + bool type_stat; float min_percent; const char *sym_hist_filter; const char *cpu_list; @@ -396,6 +397,43 @@ static void print_annotated_data_type(struct annotated_data_type *mem_type, printf(";\n"); } +static void print_annotate_data_stat(struct annotated_data_stat *s) +{ +#define PRINT_STAT(fld) if (s->fld) printf("%10d : %s\n", s->fld, #fld) + + int bad = s->no_sym + + s->no_insn + + s->no_insn_ops + + s->no_mem_ops + + s->no_reg + + s->no_dbginfo + + s->no_cuinfo + + s->no_var + + s->no_typeinfo + + s->invalid_size + + s->bad_offset; + int ok = s->total - bad; + + printf("Annotate data type stats:\n"); + printf("total %d, ok %d (%.1f%%), bad %d (%.1f%%)\n", + s->total, ok, 100.0 * ok / (s->total ?: 1), bad, 100.0 * bad / (s->total ?: 1)); + printf("-----------------------------------------------------------\n"); + PRINT_STAT(no_sym); + PRINT_STAT(no_insn); + PRINT_STAT(no_insn_ops); + PRINT_STAT(no_mem_ops); + PRINT_STAT(no_reg); + PRINT_STAT(no_dbginfo); + PRINT_STAT(no_cuinfo); + PRINT_STAT(no_var); + PRINT_STAT(no_typeinfo); + PRINT_STAT(invalid_size); + PRINT_STAT(bad_offset); + printf("\n"); + +#undef PRINT_STAT +} + static void hists__find_annotations(struct hists *hists, struct evsel *evsel, struct perf_annotate *ann) @@ -403,6 +441,9 @@ static void hists__find_annotations(struct hists *hists, struct rb_node *nd = rb_first_cached(&hists->entries), *next; int key = K_RIGHT; + if (ann->type_stat) + print_annotate_data_stat(&ann_data_stat); + while (nd) { struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); struct annotation *notes; @@ -749,7 +790,8 @@ int cmd_annotate(int argc, const char **argv) OPT_CALLBACK_OPTARG(0, "data-type", &annotate, NULL, "name", "Show data type annotate for the memory accesses", parse_data_type), - + OPT_BOOLEAN(0, "type-stat", &annotate.type_stat, + "Show stats for the data type annotation"), OPT_END() }; int ret; diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index 06be6b279d6a..2ef4daf6b12b 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -198,6 +198,7 @@ static int check_variable(Dwarf_Die *var_die, Dwarf_Die *type_die, int offset) /* Get the type of the variable */ if (die_get_real_type(var_die, type_die) == NULL) { pr_debug("variable has no type\n"); + ann_data_stat.no_typeinfo++; return -1; } @@ -208,18 +209,21 @@ static int check_variable(Dwarf_Die *var_die, Dwarf_Die *type_die, int offset) if (dwarf_tag(type_die) != DW_TAG_pointer_type || die_get_real_type(type_die, type_die) == NULL) { pr_debug("no pointer or no type\n"); + ann_data_stat.no_typeinfo++; return -1; } /* Get the size of the actual type */ if (dwarf_aggregate_size(type_die, &size) < 0) { pr_debug("type size is unknown\n"); + ann_data_stat.invalid_size++; return -1; } /* Minimal sanity check */ if ((unsigned)offset >= size) { pr_debug("offset: %d is bigger than size: %lu\n", offset, size); + ann_data_stat.bad_offset++; return -1; } @@ -238,6 +242,7 @@ static int find_data_type_die(struct debuginfo *di, u64 pc, /* Get a compile_unit for this address */ if (!find_cu_die(di, pc, &cu_die)) { pr_debug("cannot find CU for address %lx\n", pc); + ann_data_stat.no_cuinfo++; return -1; } @@ -252,9 +257,12 @@ static int find_data_type_die(struct debuginfo *di, u64 pc, /* Found a variable, see if it's correct */ ret = check_variable(&var_die, type_die, offset); - break; + goto out; } + if (ret < 0) + ann_data_stat.no_var++; +out: free(scopes); return ret; } diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h index d2dc025b1934..8e73096c01d1 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -70,6 +70,37 @@ struct annotated_data_type { extern struct annotated_data_type unknown_type; +/** + * struct annotated_data_stat - Debug statistics + * @total: Total number of entry + * @no_sym: No symbol or map found + * @no_insn: Failed to get disasm line + * @no_insn_ops: The instruction has no operands + * @no_mem_ops: The instruction has no memory operands + * @no_reg: Failed to extract a register from the operand + * @no_dbginfo: The binary has no debug information + * @no_cuinfo: Failed to find a compile_unit + * @no_var: Failed to find a matching variable + * @no_typeinfo: Failed to get a type info for the variable + * @invalid_size: Failed to get a size info of the type + * @bad_offset: The access offset is out of the type + */ +struct annotated_data_stat { + int total; + int no_sym; + int no_insn; + int no_insn_ops; + int no_mem_ops; + int no_reg; + int no_dbginfo; + int no_cuinfo; + int no_var; + int no_typeinfo; + int invalid_size; + int bad_offset; +}; +extern struct annotated_data_stat ann_data_stat; + #ifdef HAVE_DWARF_SUPPORT /* Returns data type at the location (ip, reg, offset) */ diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 68424ee0215e..9870257ce21e 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -103,6 +103,9 @@ static struct ins_ops nop_ops; static struct ins_ops lock_ops; static struct ins_ops ret_ops; +/* Data type collection debug statistics */ +struct annotated_data_stat ann_data_stat; + static int arch__grow_instructions(struct arch *arch) { struct ins *new_instructions; @@ -3683,14 +3686,22 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) u64 ip = he->ip; int i; - if (ms->map == NULL || ms->sym == NULL) + ann_data_stat.total++; + + if (ms->map == NULL || ms->sym == NULL) { + ann_data_stat.no_sym++; return NULL; + } - if (!symbol_conf.init_annotation) + if (!symbol_conf.init_annotation) { + ann_data_stat.no_sym++; return NULL; + } - if (evsel__get_arch(evsel, &arch) < 0) + if (evsel__get_arch(evsel, &arch) < 0) { + ann_data_stat.no_insn++; return NULL; + } /* Make sure it runs objdump to get disasm of the function */ symbol__ensure_annotate(ms, evsel); @@ -3700,11 +3711,15 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) * This is too slow... */ dl = find_disasm_line(ms->sym, ip); - if (dl == NULL) + if (dl == NULL) { + ann_data_stat.no_insn++; return NULL; + } - if (annotate_get_insn_location(arch, dl, &loc) < 0) + if (annotate_get_insn_location(arch, dl, &loc) < 0) { + ann_data_stat.no_insn_ops++; return NULL; + } for_each_insn_op_loc(&loc, i, op_loc) { if (!op_loc->mem_ref) @@ -3721,5 +3736,7 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) he->mem_type_off = op_loc->offset; return mem_type; } + + ann_data_stat.no_mem_ops++; return NULL; } From patchwork Wed Dec 13 00:13:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 13490202 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="R1BC/2Kg" Received: from mail-pl1-x632.google.com (mail-pl1-x632.google.com [IPv6:2607:f8b0:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 822CA10E0; Tue, 12 Dec 2023 16:13:58 -0800 (PST) Received: by mail-pl1-x632.google.com with SMTP id d9443c01a7336-1d331f12f45so11337305ad.2; Tue, 12 Dec 2023 16:13:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1702426436; x=1703031236; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=+t/jCfuCUZC9zxm3UClkrBHsoKKvmWbcSihR8oLu4is=; b=R1BC/2KgwIqom53RrJvVKuDlY9X6azxXnmVcAPgJlIaVyWx1wE9wxLnu3sLd0XwFj8 p/xYaLelZRII1YgfgZy6l873KrHdY6tz+KHVvvCgJEVKhYCcbcKfKvALund280cFo9T0 NgvvK1f7KH0vnIEk8cESFVd7K7W77TpfmCYY/kz6rgsxLf92TK4cnmpbn5rq97E9bfBK LL86ZVr0k4diLs69xKYnp2GuOQYZh0ntx8mbLE3dbhcj1bhXwEX8BHOHAWm47MaVVgaf wCQupC1plrw1PgXZ2lbbYsmDIdm3tO4eCRSR0MKb8CvL8K0O3mHSKJQOwgpvMByZb5k1 7+Vw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702426436; x=1703031236; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=+t/jCfuCUZC9zxm3UClkrBHsoKKvmWbcSihR8oLu4is=; b=lhiLw/qe80rKZhDxS81c85LWpYDJ2Z7FZJGEDcXPflrAcpfuhKRq/Fgq1jTxCFufr5 DmktqaAOKymeYGtryaCRrs0A9o3Zq2mlnJ+NKe9c/HiAJalw1bJbkntFVWjrDvkQOtAS dLOAMvtTgXM/LSRsDSYvW0UbUn12/0I2xUHA9I5SfjlIWjl8Js9L2wgyjmo12ucwApwa oFhAjzev1TUwmtu2HJveJjY/Ou7HYD6Cbq9qxxQlDheC7k9tf26v0y+ym1ZGdpaW/Jwn vJdtvQJ6M+2Uj+GeoUhl8URQO+k1xEAMLlTpWzVbLLbO4mBffezalhxbYJ7vtKuq8Zwm aTlQ== X-Gm-Message-State: AOJu0YyI0rXgpoJ0gqBKjNERm771aN2aNKio4/6MN+WiJTAP/Bvu0jW4 Pzd8VCNj8bhyXuSUBoCYTW0= X-Google-Smtp-Source: AGHT+IEulzTP+M/7vHMVxwDJSarpBqmnc2dExzmaYKk80NGHrcLvzEBUa22gIvKzaqA1aPVhi2+7fQ== X-Received: by 2002:a17:903:228b:b0:1d0:77c9:a9a2 with SMTP id b11-20020a170903228b00b001d077c9a9a2mr4760835plh.25.1702426435705; Tue, 12 Dec 2023 16:13:55 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:8251:f360:4316:214e]) by smtp.gmail.com with ESMTPSA id i11-20020a17090332cb00b001d0ab572458sm9136398plr.121.2023.12.12.16.13.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Dec 2023 16:13:55 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 17/17] perf annotate: Add --insn-stat option for debugging Date: Tue, 12 Dec 2023 16:13:23 -0800 Message-ID: <20231213001323.718046-18-namhyung@kernel.org> X-Mailer: git-send-email 2.43.0.472.g3155946c3a-goog In-Reply-To: <20231213001323.718046-1-namhyung@kernel.org> References: <20231213001323.718046-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-trace-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This is for a debugging purpose. It'd be useful to see per-instrucion level success/failure stats. $ perf annotate --data-type --insn-stat Annotate Instruction stats total 264, ok 143 (54.2%), bad 121 (45.8%) Name : Good Bad ----------------------------------------------------------- movq : 45 31 movl : 22 11 popq : 0 19 cmpl : 16 3 addq : 8 7 cmpq : 11 3 cmpxchgl : 3 7 cmpxchgq : 8 0 incl : 3 3 movzbl : 4 2 incq : 4 2 decl : 6 0 ... Signed-off-by: Namhyung Kim --- tools/perf/builtin-annotate.c | 41 +++++++++++++++++++++++++++++++++++ tools/perf/util/annotate.c | 38 ++++++++++++++++++++++++++++++++ tools/perf/util/annotate.h | 8 +++++++ 3 files changed, 87 insertions(+) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 55f97ab1395b..6c1cc797692d 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -58,6 +58,7 @@ struct perf_annotate { bool group_set; bool data_type; bool type_stat; + bool insn_stat; float min_percent; const char *sym_hist_filter; const char *cpu_list; @@ -434,6 +435,42 @@ static void print_annotate_data_stat(struct annotated_data_stat *s) #undef PRINT_STAT } +static void print_annotate_item_stat(struct list_head *head, const char *title) +{ + struct annotated_item_stat *istat, *pos, *iter; + int total_good, total_bad, total; + int sum1, sum2; + LIST_HEAD(tmp); + + /* sort the list by count */ + list_splice_init(head, &tmp); + total_good = total_bad = 0; + + list_for_each_entry_safe(istat, pos, &tmp, list) { + total_good += istat->good; + total_bad += istat->bad; + sum1 = istat->good + istat->bad; + + list_for_each_entry(iter, head, list) { + sum2 = iter->good + iter->bad; + if (sum1 > sum2) + break; + } + list_move_tail(&istat->list, &iter->list); + } + total = total_good + total_bad; + + printf("Annotate %s stats\n", title); + printf("total %d, ok %d (%.1f%%), bad %d (%.1f%%)\n\n", total, + total_good, 100.0 * total_good / (total ?: 1), + total_bad, 100.0 * total_bad / (total ?: 1)); + printf(" %-10s: %5s %5s\n", "Name", "Good", "Bad"); + printf("-----------------------------------------------------------\n"); + list_for_each_entry(istat, head, list) + printf(" %-10s: %5d %5d\n", istat->name, istat->good, istat->bad); + printf("\n"); +} + static void hists__find_annotations(struct hists *hists, struct evsel *evsel, struct perf_annotate *ann) @@ -443,6 +480,8 @@ static void hists__find_annotations(struct hists *hists, if (ann->type_stat) print_annotate_data_stat(&ann_data_stat); + if (ann->insn_stat) + print_annotate_item_stat(&ann_insn_stat, "Instruction"); while (nd) { struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); @@ -792,6 +831,8 @@ int cmd_annotate(int argc, const char **argv) parse_data_type), OPT_BOOLEAN(0, "type-stat", &annotate.type_stat, "Show stats for the data type annotation"), + OPT_BOOLEAN(0, "insn-stat", &annotate.insn_stat, + "Show instruction stats for the data type annotation"), OPT_END() }; int ret; diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 9870257ce21e..9b70ab110ce7 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -105,6 +105,7 @@ static struct ins_ops ret_ops; /* Data type collection debug statistics */ struct annotated_data_stat ann_data_stat; +LIST_HEAD(ann_insn_stat); static int arch__grow_instructions(struct arch *arch) { @@ -3665,6 +3666,30 @@ static struct disasm_line *find_disasm_line(struct symbol *sym, u64 ip) return NULL; } +static struct annotated_item_stat *annotate_data_stat(struct list_head *head, + const char *name) +{ + struct annotated_item_stat *istat; + + list_for_each_entry(istat, head, list) { + if (!strcmp(istat->name, name)) + return istat; + } + + istat = zalloc(sizeof(*istat)); + if (istat == NULL) + return NULL; + + istat->name = strdup(name); + if (istat->name == NULL) { + free(istat); + return NULL; + } + + list_add_tail(&istat->list, head); + return istat; +} + /** * hist_entry__get_data_type - find data type for given hist entry * @he: hist entry @@ -3683,6 +3708,7 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) struct annotated_insn_loc loc; struct annotated_op_loc *op_loc; struct annotated_data_type *mem_type; + struct annotated_item_stat *istat; u64 ip = he->ip; int i; @@ -3716,8 +3742,15 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) return NULL; } + istat = annotate_data_stat(&ann_insn_stat, dl->ins.name); + if (istat == NULL) { + ann_data_stat.no_insn++; + return NULL; + } + if (annotate_get_insn_location(arch, dl, &loc) < 0) { ann_data_stat.no_insn_ops++; + istat->bad++; return NULL; } @@ -3726,6 +3759,10 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) continue; mem_type = find_data_type(ms, ip, op_loc->reg, op_loc->offset); + if (mem_type) + istat->good++; + else + istat->bad++; if (symbol_conf.annotate_data_sample) { annotated_data_type__update_samples(mem_type, evsel, @@ -3738,5 +3775,6 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) } ann_data_stat.no_mem_ops++; + istat->bad++; return NULL; } diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 6c75b2832286..dba50762c6e8 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -479,4 +479,12 @@ int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl, /* Returns a data type from the sample instruction (if any) */ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he); +struct annotated_item_stat { + struct list_head list; + char *name; + int good; + int bad; +}; +extern struct list_head ann_insn_stat; + #endif /* __PERF_ANNOTATE_H */