Received: by 2002:ab2:804:0:b0:1f4:6637:5750 with SMTP id q4csp1211812lqe; Thu, 11 Apr 2024 11:39:34 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWz3Y+ac9cfSa3vXos78xGXXLPXKoa6tneMXhTKQDIWMMzkaF9LIK9FvnFdpwge0WaUxArOPJL0Yx1qZrIdG4LYjOUwiYh0WHmUq35m8g== X-Google-Smtp-Source: AGHT+IFNvmCRbhSGXTl8fd1Yf5EIGshpImeE094DaJPmAx97LtHlvlWnT1IymPkVa+SpwwzGs4Bs X-Received: by 2002:a05:6214:2d0d:b0:69b:1dd6:f310 with SMTP id mz13-20020a0562142d0d00b0069b1dd6f310mr539682qvb.33.1712860774572; Thu, 11 Apr 2024 11:39:34 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1712860774; cv=pass; d=google.com; s=arc-20160816; b=CLBDLwxKLy65WSSsolxFi1ADPGCT+yGuXNB6Qxu/61HrxbbBdr//OzvdMi54WgTbJm falE2+rEgPfBWOd9+xwv7VswdC1UPaPxe/Oapf1n6dyULZSUQgX2Y06SqYFFMnUI604k XdxC6iSFNzJVK+vsTEGyyVPRcTACSLSjpMBkVEmXOC2N8c6u27nrOU611uyUdDaqxerB NvRZ7MUP75EvCtjRuE/xNsKR1ZLCqTwQeYZg1l47HJ7S4K8Sbh3cvlWpHguPe7oC49Ro 3h5bX7JMnb9/y3w8YS1yYgnL0fhpZFJi3tibTz8+tG2O/hmbHkyQK/SvAki7wDH6WZ9o BqJw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=dYNr4hg4N4b4wlLA92NnauGBe74com7e9plHuFqT1JE=; fh=BZzRcd5Y2vYJmsOPOcIEb0V/BdS2GmLADdQhxuBcOoU=; b=TvVwIrlZsm4aU4Ipn0y7dnlhRFv4lbifgbYWQh8lBwaGUXk70IVQcIW//r2aBl3vhK VPd1uYBcIx7MB8T7JX5hhJup+difvKRD3FmBEu2QZXFyQsaZ+fGSIfaRLK5oFUNCysts OvphW2rIqoOKi4pq8WTYlJoinDv/8bI6wZO2Dxud8AtXvKT9FgTgquwldZNnWyExebfx 2keJHnNy8NqklTASD2bMQh7esNp2SaznX9tlBATOFRZUHfcITWyGrASUW+XjNATteevU 310aRKm5NQfh5GUeJzo2BH5ncfxfe1cF6U8hbkWFCtl3QONXYUrwRABNbF+xR8K6jAs4 pqUw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=gL8OQsqN; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-141465-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-141465-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id gu4-20020a056214260400b0069b432bca2esi2639753qvb.121.2024.04.11.11.39.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 11 Apr 2024 11:39:34 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-141465-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=gL8OQsqN; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-141465-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-141465-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 1F2521C21ACF for ; Thu, 11 Apr 2024 18:39:34 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 88EA418042; Thu, 11 Apr 2024 18:17:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gL8OQsqN" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D3C4714AA7; Thu, 11 Apr 2024 18:17:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712859440; cv=none; b=vBBpWMZMW6P3AFDZI9J72wdpNWebSeztBQMgqPkiyvKsvWR4kLewP9CcyOLwgf17zMW16Fy+bPoDko9YjAihO/kQp20Ua7iGm0YLYUUXFSzu8P9RU4xUvUkTHinkPNW1mwmz29qcSy5EY9p83GPkAZy4ItnRufy6PJmFQvPFVgg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712859440; c=relaxed/simple; bh=HE+EyQqPK18sz85B3UtgkLsTZLOl4vN+w8ZtI5BnGVQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XtNAT5jB5fXzhbKAMt4e6/fDmbww2ngt78YduGTzjAk8jqWWWPMWZUxqilLwT5lLc9daXCWv319du49iAvNyRMQlhuOhvMKHo7VvbmuPKsuU3qgGUjbfUpeqUyW4nd3RC3XDv4mTk2Z2ZPBs/FRFvIzvQRzBl4fzDtAQrlMP73g= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gL8OQsqN; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4DB49C2BD11; Thu, 11 Apr 2024 18:17:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1712859440; bh=HE+EyQqPK18sz85B3UtgkLsTZLOl4vN+w8ZtI5BnGVQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gL8OQsqN3jFLyhKr9kXR2bw5v4uBIBASYTBns46SqC8p/O8Dd6A0R60AR5lil+2fz ftnLMeAweqCDax7/N5ntJ+Up372hUe2jB/Lbx92igtySpYvHNTVDNDgCK9NCev51eZ bP8uw0RdxO4nVohrd+oZsPX4bUrlL2MxXfWZJKy/1qBlidf7oKp+t/lki1STjNY6lz UUDGCwtg0p62XToiyR3YqUjCKnuPo5wY3BbORUWWZwVm953XzDBAdWWxwrQDM25AEd X8p3aV2q864IbEJdoIqR2dF7W5Gy9RiI1AZuScnn7+WVht2TXfuDwhj7tcmlWSpJJF Z3zQiTYhtPFNQ== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers , Kan Liang Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Stephane Eranian , Andi Kleen , Athira Rajeev Subject: [PATCH v2 3/3] perf report: Add weight[123] output fields Date: Thu, 11 Apr 2024 11:17:18 -0700 Message-ID: <20240411181718.2367948-3-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.683.g7961c838ac-goog In-Reply-To: <20240411181718.2367948-1-namhyung@kernel.org> References: <20240411181718.2367948-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Add weight1, weight2 and weight3 fields to -F/--fields and their aliases like 'ins_lat', 'p_stage_cyc' and 'retire_lat'. Note that they are in the sort keys too but the difference is that output fields will sum up the weight values and display the average. In the sort key, users can see the distribution of weight value and I think it's confusing we have local vs. global weight for the same weight. For example, I experiment with mem-loads events to get the weights. On my laptop, it seems only weight1 field is supported. $ perf mem record -- perf test -w noploop Let's look at the noploop function only. It has 7 samples. $ perf script -F event,ip,sym,weight | grep noploop # event weight ip sym cpu/mem-loads,ldlat=30/P: 43 55b3c122bffc noploop cpu/mem-loads,ldlat=30/P: 48 55b3c122bffc noploop cpu/mem-loads,ldlat=30/P: 38 55b3c122bffc noploop <--- same weight cpu/mem-loads,ldlat=30/P: 38 55b3c122bffc noploop <--- same weight cpu/mem-loads,ldlat=30/P: 59 55b3c122bffc noploop cpu/mem-loads,ldlat=30/P: 33 55b3c122bffc noploop cpu/mem-loads,ldlat=30/P: 38 55b3c122bffc noploop <--- same weight When you use the 'weight' sort key, it'd show entries with a separate weight value separately. Also note that the first entry has 3 samples with weight value 38, so they are displayed together and the weight value is the sum of 3 samples (114 = 38 * 3). $ perf report -n -s +weight | grep -e Weight -e noploop # Overhead Samples Command Shared Object Symbol Weight 0.53% 3 perf perf [.] noploop 114 0.18% 1 perf perf [.] noploop 59 0.18% 1 perf perf [.] noploop 48 0.18% 1 perf perf [.] noploop 43 0.18% 1 perf perf [.] noploop 33 If you use 'local_weight' sort key, you can see the actualy weight. $ perf report -n -s +local_weight | grep -e Weight -e noploop # Overhead Samples Command Shared Object Symbol Local Weight 0.53% 3 perf perf [.] noploop 38 0.18% 1 perf perf [.] noploop 59 0.18% 1 perf perf [.] noploop 48 0.18% 1 perf perf [.] noploop 43 0.18% 1 perf perf [.] noploop 33 But when you use the -F/--field option instead, you can see the average weight for the while noploop function (as it won't group samples by weight value and use the default 'comm,dso,sym' sort keys). $ perf report -n -F +weight | grep -e Weight -e noploop Warning: --fields weight shows the average value unlike in the --sort key. # Overhead Samples Weight1 Command Shared Object Symbol 1.23% 7 42.4 perf perf [.] noploop The weight1 field shows the average value: (38 * 3 + 59 + 48 + 43 + 33) / 7 = 42.4 Also it'd show the warning that 'weight' field has the average value. Using 'weight1' can remove the warning. Signed-off-by: Namhyung Kim --- v2) shows the warning when 'weight' field is used (Kan) tools/perf/Documentation/perf-report.txt | 9 ++- tools/perf/ui/hist.c | 92 +++++++++++++++++++----- tools/perf/util/hist.h | 15 +++- tools/perf/util/sort.c | 28 +++++--- tools/perf/util/sort.h | 2 +- 5 files changed, 115 insertions(+), 31 deletions(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index d8b863e01fe0..d2b1593ef700 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -121,6 +121,9 @@ OPTIONS - type: Data type of sample memory access. - typeoff: Offset in the data type of sample memory access. - symoff: Offset in the symbol. + - weight1: Average value of event specific weight (1st field of weight_struct). + - weight2: Average value of event specific weight (2nd field of weight_struct). + - weight3: Average value of event specific weight (3rd field of weight_struct). By default, comm, dso and symbol keys are used. (i.e. --sort comm,dso,symbol) @@ -198,7 +201,11 @@ OPTIONS --fields=:: Specify output field - multiple keys can be specified in CSV format. Following fields are available: - overhead, overhead_sys, overhead_us, overhead_children, sample and period. + overhead, overhead_sys, overhead_us, overhead_children, sample, period, + weight1, weight2, weight3, ins_lat, p_stage_cyc and retire_lat. The + last 3 names are alias for the corresponding weights. When the weight + fields are used, they will show the average value of the weight. + Also it can contain any sort key(s). By default, every sort keys not specified in -F will be appended diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 2bf959d08354..685ba2a54fd8 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -25,7 +25,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, hpp_field_fn get_field, const char *fmt, int len, - hpp_snprint_fn print_fn, bool fmt_percent) + hpp_snprint_fn print_fn, enum perf_hpp_fmt_type fmtype) { int ret; struct hists *hists = he->hists; @@ -33,7 +33,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, char *buf = hpp->buf; size_t size = hpp->size; - if (fmt_percent) { + if (fmtype == PERF_HPP_FMT_TYPE__PERCENT) { double percent = 0.0; u64 total = hists__total_period(hists); @@ -41,8 +41,16 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, percent = 100.0 * get_field(he) / total; ret = hpp__call_print_fn(hpp, print_fn, fmt, len, percent); - } else + } else if (fmtype == PERF_HPP_FMT_TYPE__AVERAGE) { + double average = 0; + + if (he->stat.nr_events) + average = 1.0 * get_field(he) / he->stat.nr_events; + + ret = hpp__call_print_fn(hpp, print_fn, fmt, len, average); + } else { ret = hpp__call_print_fn(hpp, print_fn, fmt, len, get_field(he)); + } if (evsel__is_group_event(evsel)) { int prev_idx, idx_delta; @@ -54,6 +62,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, list_for_each_entry(pair, &he->pairs.head, pairs.node) { u64 period = get_field(pair); u64 total = hists__total_period(pair->hists); + int nr_samples = pair->stat.nr_events; if (!total) continue; @@ -66,7 +75,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, * zero-fill group members in the middle which * have no sample */ - if (fmt_percent) { + if (fmtype != PERF_HPP_FMT_TYPE__RAW) { ret += hpp__call_print_fn(hpp, print_fn, fmt, len, 0.0); } else { @@ -75,9 +84,14 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, } } - if (fmt_percent) { + if (fmtype == PERF_HPP_FMT_TYPE__PERCENT) { ret += hpp__call_print_fn(hpp, print_fn, fmt, len, 100.0 * period / total); + } else if (fmtype == PERF_HPP_FMT_TYPE__AVERAGE) { + double avg = nr_samples ? (period / nr_samples) : 0; + + ret += hpp__call_print_fn(hpp, print_fn, fmt, + len, avg); } else { ret += hpp__call_print_fn(hpp, print_fn, fmt, len, period); @@ -92,7 +106,7 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, /* * zero-fill group members at last which have no sample */ - if (fmt_percent) { + if (fmtype != PERF_HPP_FMT_TYPE__RAW) { ret += hpp__call_print_fn(hpp, print_fn, fmt, len, 0.0); } else { @@ -114,33 +128,35 @@ static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, int hpp__fmt(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hist_entry *he, hpp_field_fn get_field, - const char *fmtstr, hpp_snprint_fn print_fn, bool fmt_percent) + const char *fmtstr, hpp_snprint_fn print_fn, + enum perf_hpp_fmt_type fmtype) { int len = fmt->user_len ?: fmt->len; if (symbol_conf.field_sep) { return __hpp__fmt(hpp, he, get_field, fmtstr, 1, - print_fn, fmt_percent); + print_fn, fmtype); } - if (fmt_percent) + if (fmtype == PERF_HPP_FMT_TYPE__PERCENT) len -= 2; /* 2 for a space and a % sign */ else len -= 1; - return __hpp__fmt(hpp, he, get_field, fmtstr, len, print_fn, fmt_percent); + return __hpp__fmt(hpp, he, get_field, fmtstr, len, print_fn, fmtype); } int hpp__fmt_acc(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hist_entry *he, hpp_field_fn get_field, - const char *fmtstr, hpp_snprint_fn print_fn, bool fmt_percent) + const char *fmtstr, hpp_snprint_fn print_fn, + enum perf_hpp_fmt_type fmtype) { if (!symbol_conf.cumulate_callchain) { int len = fmt->user_len ?: fmt->len; return snprintf(hpp->buf, hpp->size, " %*s", len - 1, "N/A"); } - return hpp__fmt(fmt, hpp, he, get_field, fmtstr, print_fn, fmt_percent); + return hpp__fmt(fmt, hpp, he, get_field, fmtstr, print_fn, fmtype); } static int field_cmp(u64 field_a, u64 field_b) @@ -350,7 +366,7 @@ static int hpp__color_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ return hpp__fmt(fmt, hpp, he, he_get_##_field, " %*.2f%%", \ - hpp_color_scnprintf, true); \ + hpp_color_scnprintf, PERF_HPP_FMT_TYPE__PERCENT); \ } #define __HPP_ENTRY_PERCENT_FN(_type, _field) \ @@ -358,7 +374,7 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ return hpp__fmt(fmt, hpp, he, he_get_##_field, " %*.2f%%", \ - hpp_entry_scnprintf, true); \ + hpp_entry_scnprintf, PERF_HPP_FMT_TYPE__PERCENT); \ } #define __HPP_SORT_FN(_type, _field) \ @@ -378,7 +394,7 @@ static int hpp__color_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ return hpp__fmt_acc(fmt, hpp, he, he_get_acc_##_field, " %*.2f%%", \ - hpp_color_scnprintf, true); \ + hpp_color_scnprintf, PERF_HPP_FMT_TYPE__PERCENT); \ } #define __HPP_ENTRY_ACC_PERCENT_FN(_type, _field) \ @@ -386,7 +402,7 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ return hpp__fmt_acc(fmt, hpp, he, he_get_acc_##_field, " %*.2f%%", \ - hpp_entry_scnprintf, true); \ + hpp_entry_scnprintf, PERF_HPP_FMT_TYPE__PERCENT); \ } #define __HPP_SORT_ACC_FN(_type, _field) \ @@ -406,7 +422,7 @@ static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ return hpp__fmt(fmt, hpp, he, he_get_raw_##_field, " %*"PRIu64, \ - hpp_entry_scnprintf, false); \ + hpp_entry_scnprintf, PERF_HPP_FMT_TYPE__RAW); \ } #define __HPP_SORT_RAW_FN(_type, _field) \ @@ -416,6 +432,26 @@ static int64_t hpp__sort_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ return __hpp__sort(a, b, he_get_raw_##_field); \ } +#define __HPP_ENTRY_AVERAGE_FN(_type, _field) \ +static u64 he_get_##_field(struct hist_entry *he) \ +{ \ + return he->stat._field; \ +} \ + \ +static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ + struct perf_hpp *hpp, struct hist_entry *he) \ +{ \ + return hpp__fmt(fmt, hpp, he, he_get_##_field, " %*.1f", \ + hpp_entry_scnprintf, PERF_HPP_FMT_TYPE__AVERAGE); \ +} + +#define __HPP_SORT_AVERAGE_FN(_type, _field) \ +static int64_t hpp__sort_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ + struct hist_entry *a, struct hist_entry *b) \ +{ \ + return __hpp__sort(a, b, he_get_##_field); \ +} + #define HPP_PERCENT_FNS(_type, _field) \ __HPP_COLOR_PERCENT_FN(_type, _field) \ @@ -431,6 +467,10 @@ __HPP_SORT_ACC_FN(_type, _field) __HPP_ENTRY_RAW_FN(_type, _field) \ __HPP_SORT_RAW_FN(_type, _field) +#define HPP_AVERAGE_FNS(_type, _field) \ +__HPP_ENTRY_AVERAGE_FN(_type, _field) \ +__HPP_SORT_AVERAGE_FN(_type, _field) + HPP_PERCENT_FNS(overhead, period) HPP_PERCENT_FNS(overhead_sys, period_sys) HPP_PERCENT_FNS(overhead_us, period_us) @@ -441,6 +481,10 @@ HPP_PERCENT_ACC_FNS(overhead_acc, period) HPP_RAW_FNS(samples, nr_events) HPP_RAW_FNS(period, period) +HPP_AVERAGE_FNS(weight1, weight1) +HPP_AVERAGE_FNS(weight2, weight2) +HPP_AVERAGE_FNS(weight3, weight3) + static int64_t hpp__nop_cmp(struct perf_hpp_fmt *fmt __maybe_unused, struct hist_entry *a __maybe_unused, struct hist_entry *b __maybe_unused) @@ -510,7 +554,10 @@ struct perf_hpp_fmt perf_hpp__format[] = { HPP__COLOR_PRINT_FNS("guest usr", overhead_guest_us, OVERHEAD_GUEST_US), HPP__COLOR_ACC_PRINT_FNS("Children", overhead_acc, OVERHEAD_ACC), HPP__PRINT_FNS("Samples", samples, SAMPLES), - HPP__PRINT_FNS("Period", period, PERIOD) + HPP__PRINT_FNS("Period", period, PERIOD), + HPP__PRINT_FNS("Weight1", weight1, WEIGHT1), + HPP__PRINT_FNS("Weight2", weight2, WEIGHT2), + HPP__PRINT_FNS("Weight3", weight3, WEIGHT3), }; struct perf_hpp_list perf_hpp_list = { @@ -526,6 +573,7 @@ struct perf_hpp_list perf_hpp_list = { #undef HPP_PERCENT_FNS #undef HPP_PERCENT_ACC_FNS #undef HPP_RAW_FNS +#undef HPP_AVERAGE_FNS #undef __HPP_HEADER_FN #undef __HPP_WIDTH_FN @@ -534,9 +582,11 @@ struct perf_hpp_list perf_hpp_list = { #undef __HPP_COLOR_ACC_PERCENT_FN #undef __HPP_ENTRY_ACC_PERCENT_FN #undef __HPP_ENTRY_RAW_FN +#undef __HPP_ENTRY_AVERAGE_FN #undef __HPP_SORT_FN #undef __HPP_SORT_ACC_FN #undef __HPP_SORT_RAW_FN +#undef __HPP_SORT_AVERAGE_FN static void fmt_free(struct perf_hpp_fmt *fmt) { @@ -785,6 +835,12 @@ void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists) fmt->len = 12; break; + case PERF_HPP__WEIGHT1: + case PERF_HPP__WEIGHT2: + case PERF_HPP__WEIGHT3: + fmt->len = 8; + break; + default: break; } diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index f34f101c36c2..5260822b9773 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -550,6 +550,9 @@ enum { PERF_HPP__OVERHEAD_ACC, PERF_HPP__SAMPLES, PERF_HPP__PERIOD, + PERF_HPP__WEIGHT1, + PERF_HPP__WEIGHT2, + PERF_HPP__WEIGHT3, PERF_HPP__MAX_INDEX }; @@ -596,16 +599,24 @@ void perf_hpp__reset_sort_width(struct perf_hpp_fmt *fmt, struct hists *hists); void perf_hpp__set_user_width(const char *width_list_str); void hists__reset_column_width(struct hists *hists); +enum perf_hpp_fmt_type { + PERF_HPP_FMT_TYPE__RAW, + PERF_HPP_FMT_TYPE__PERCENT, + PERF_HPP_FMT_TYPE__AVERAGE, +}; + typedef u64 (*hpp_field_fn)(struct hist_entry *he); typedef int (*hpp_callback_fn)(struct perf_hpp *hpp, bool front); typedef int (*hpp_snprint_fn)(struct perf_hpp *hpp, const char *fmt, ...); int hpp__fmt(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hist_entry *he, hpp_field_fn get_field, - const char *fmtstr, hpp_snprint_fn print_fn, bool fmt_percent); + const char *fmtstr, hpp_snprint_fn print_fn, + enum perf_hpp_fmt_type fmtype); int hpp__fmt_acc(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hist_entry *he, hpp_field_fn get_field, - const char *fmtstr, hpp_snprint_fn print_fn, bool fmt_percent); + const char *fmtstr, hpp_snprint_fn print_fn, + enum perf_hpp_fmt_type fmtype); static inline void advance_hpp(struct perf_hpp *hpp, int inc) { diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 92a1bd695e8a..add8601c57fd 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -2441,6 +2441,13 @@ static struct hpp_dimension hpp_sort_dimensions[] = { DIM(PERF_HPP__OVERHEAD_ACC, "overhead_children"), DIM(PERF_HPP__SAMPLES, "sample"), DIM(PERF_HPP__PERIOD, "period"), + DIM(PERF_HPP__WEIGHT1, "weight1"), + DIM(PERF_HPP__WEIGHT2, "weight2"), + DIM(PERF_HPP__WEIGHT3, "weight3"), + /* aliases for weight_struct */ + DIM(PERF_HPP__WEIGHT2, "ins_lat"), + DIM(PERF_HPP__WEIGHT3, "retire_lat"), + DIM(PERF_HPP__WEIGHT3, "p_stage_cyc"), }; #undef DIM @@ -3743,26 +3750,29 @@ void sort__setup_elide(FILE *output) } } -int output_field_add(struct perf_hpp_list *list, char *tok) +int output_field_add(struct perf_hpp_list *list, const char *tok) { unsigned int i; - for (i = 0; i < ARRAY_SIZE(common_sort_dimensions); i++) { - struct sort_dimension *sd = &common_sort_dimensions[i]; + for (i = 0; i < ARRAY_SIZE(hpp_sort_dimensions); i++) { + struct hpp_dimension *hd = &hpp_sort_dimensions[i]; - if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) + if (strncasecmp(tok, hd->name, strlen(tok))) continue; - return __sort_dimension__add_output(list, sd); + if (!strcasecmp(tok, "weight")) + ui__warning("--fields weight shows the average value unlike in the --sort key.\n"); + + return __hpp_dimension__add_output(list, hd); } - for (i = 0; i < ARRAY_SIZE(hpp_sort_dimensions); i++) { - struct hpp_dimension *hd = &hpp_sort_dimensions[i]; + for (i = 0; i < ARRAY_SIZE(common_sort_dimensions); i++) { + struct sort_dimension *sd = &common_sort_dimensions[i]; - if (strncasecmp(tok, hd->name, strlen(tok))) + if (!sd->name || strncasecmp(tok, sd->name, strlen(tok))) continue; - return __hpp_dimension__add_output(list, hd); + return __sort_dimension__add_output(list, sd); } for (i = 0; i < ARRAY_SIZE(bstack_sort_dimensions); i++) { diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 690892a92cf3..0bd0ee3ae76b 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -141,7 +141,7 @@ void reset_dimensions(void); int sort_dimension__add(struct perf_hpp_list *list, const char *tok, struct evlist *evlist, int level); -int output_field_add(struct perf_hpp_list *list, char *tok); +int output_field_add(struct perf_hpp_list *list, const char *tok); int64_t sort__iaddr_cmp(struct hist_entry *left, struct hist_entry *right); int64_t -- 2.44.0.683.g7961c838ac-goog