lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200310070245.16314-12-yao.jin@linux.intel.com>
Date:   Tue, 10 Mar 2020 15:02:42 +0800
From:   Jin Yao <yao.jin@...ux.intel.com>
To:     acme@...nel.org, jolsa@...nel.org, peterz@...radead.org,
        mingo@...hat.com, alexander.shishkin@...ux.intel.com
Cc:     Linux-kernel@...r.kernel.org, ak@...ux.intel.com,
        kan.liang@...el.com, yao.jin@...el.com,
        Jin Yao <yao.jin@...ux.intel.com>
Subject: [PATCH v1 11/14] perf diff: support hot blocks comparison

This patch reports the results of hot blocks comparison.

For example, following outputs are added to the end of
hot streams reports.

  # Output based on old stream (perf.data.old):
  #
  # Sampled Cycles%  Avg Cycles  New Stream Diff(cycles%,cycles)  New Stream Sampled Cycles%  New Stream Avg Cycles
  # ...............  ..........  ...............................  ..........................  .....................
  #
             24.76%          17                     -4.54%,   -7                           -                      -
             14.72%           7                      0.13%,   -1                           -                      -
              5.28%           2        [block not in new stream]                           -                      -
              5.09%           2                      0.52%,    0                           -                      -
              5.05%           2                     -0.15%,   -1                           -                      -
              4.18%           1                      0.12%,    0                           -                      -
              3.16%           1                      0.28%,    0                           -                      -

If we enable the source line comparison, the output might be different.

  # Output based on old stream (perf.data.old):
  #
  # Sampled Cycles%  Avg Cycles  New Stream Diff(cycles%,cycles)  New Stream Sampled Cycles%  New Stream Avg Cycles
  # ...............  ..........  ...............................  ..........................  .....................
  #
             24.76%          17    [block changed in new stream]                      20.22%                     10
             14.72%           7                      0.13%,   -1                           -                      -
              5.28%           2        [block not in new stream]                           -                      -
              5.09%           2                      0.52%,    0                           -                      -
              5.05%           2                     -0.15%,   -1                           -                      -
              4.18%           1    [block changed in new stream]                       4.31%                      1
              3.16%           1                      0.28%,    0                           -                      -

Signed-off-by: Jin Yao <yao.jin@...ux.intel.com>
---
 tools/perf/builtin-diff.c | 85 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 84 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index dcbc9bba4e61..566e811054b1 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -49,6 +49,8 @@ struct perf_diff {
 	bool				 src_cmp;
 	bool				 stream;
 	struct srclist			*src_list;
+	u64				 total_cycles;
+	float				 min_percent;
 };
 
 /* Diff command specific HPP columns. */
@@ -76,8 +78,10 @@ struct diff_hpp_fmt {
 
 struct data__file {
 	struct perf_session	*session;
+	struct block_report	*block_reports;
 	struct perf_data	 data;
 	int			 idx;
+	int			 nr_block_reports;
 	struct hists		*hists;
 	struct callchain_streams *evsel_streams;
 	int			 nr_evsel_streams;
@@ -445,8 +449,10 @@ static int diff__process_sample_event(struct perf_tool *tool,
 			pr_debug("problem adding hist entry, skipping event\n");
 			goto out_put;
 		}
-		break;
 
+		hist__account_cycles(sample->branch_stack, &al, sample, false,
+				     &pdiff->total_cycles);
+		break;
 	default:
 		if (!hists__add_entry(hists, &al, NULL, NULL, NULL, sample,
 				      true)) {
@@ -992,6 +998,7 @@ static int process_base_stream(struct data__file *data_base,
 	struct evlist *evlist_pair = data_pair->session->evlist;
 	struct evsel *evsel_base, *evsel_pair;
 	struct callchain_streams *es_base, *es_pair;
+	struct block_report *rep_base, *rep_pair;
 
 	evlist__for_each_entry(evlist_base, evsel_base) {
 		evsel_pair = evsel_match(evsel_base, evlist_pair);
@@ -1014,6 +1021,37 @@ static int process_base_stream(struct data__file *data_base,
 		callchain_stream_report(es_base, es_pair);
 	}
 
+	evlist__for_each_entry(evlist_base, evsel_base) {
+		rep_base = block_info__get_report(data_base->block_reports,
+						  data_base->nr_block_reports,
+						  evsel_base->idx);
+
+		if (!rep_base)
+			return -1;
+
+		block_hists_addr2line(&rep_base->hist.block_hists, base_dir);
+
+		evlist_pair = data_pair->session->evlist;
+		evsel_pair = evsel_match(evsel_base, evlist_pair);
+		if (!evsel_pair)
+			continue;
+
+		rep_pair = block_info__get_report(data_pair->block_reports,
+						  data_pair->nr_block_reports,
+						  evsel_pair->idx);
+
+		block_hists_addr2line(&rep_pair->hist.block_hists, pair_dir);
+
+		block_info__match_report(rep_base, rep_pair,
+					 pdiff.src_list, NULL);
+
+		fprintf(stdout, "%s", title);
+
+		use_browser = 0;
+		report__browse_block_hists(&rep_base->hist, pdiff.min_percent,
+					   evsel_base, NULL, NULL);
+	}
+
 	return 0;
 }
 
@@ -1142,6 +1180,26 @@ static int check_file_brstack(void)
 	return 0;
 }
 
+static struct block_report *create_block_reports(struct evlist *evlist,
+						 u64 total_cycles,
+						 int *nr_block_reports)
+{
+	struct block_report *reps;
+	int block_hpps[7] = {
+		PERF_HPP_REPORT__BLOCK_TOTAL_CYCLES_PCT,
+		PERF_HPP_REPORT__BLOCK_AVG_CYCLES,
+		PERF_HPP__BLOCK_NEW_STREAM_DIFF,
+		PERF_HPP__BLOCK_NEW_STREAM_TOTAL_CYCLES_PCT,
+		PERF_HPP__BLOCK_NEW_STREAM_AVG_CYCLES,
+		PERF_HPP_REPORT__BLOCK_RANGE,
+		PERF_HPP_REPORT__BLOCK_DSO,
+	};
+
+	reps = block_info__create_report(evlist, total_cycles, block_hpps, 7,
+					 nr_block_reports);
+	return reps;
+}
+
 static struct callchain_streams *create_evsel_streams(struct evlist *evlist,
 						      int nr_streams_max,
 						      int *nr_evsel_streams)
@@ -1197,6 +1255,8 @@ static int __cmd_diff(void)
 				goto out_delete;
 		}
 
+		pdiff.total_cycles = 0;
+
 		ret = perf_session__process_events(d->session);
 		if (ret) {
 			pr_err("Failed to process %s\n", d->data.path);
@@ -1215,6 +1275,12 @@ static int __cmd_diff(void)
 						&d->nr_evsel_streams);
 			if (!d->evsel_streams)
 				goto out_delete;
+
+			d->block_reports = create_block_reports(d->session->evlist,
+								pdiff.total_cycles,
+								&d->nr_block_reports);
+			if (!d->block_reports)
+				goto out_delete;
 		}
 	}
 
@@ -1225,6 +1291,11 @@ static int __cmd_diff(void)
 
  out_delete:
 	data__for_each_file(i, d) {
+		if (d->block_reports) {
+			block_info__free_report(d->block_reports,
+						d->nr_block_reports);
+		}
+
 		perf_session__delete(d->session);
 		data__free(d);
 	}
@@ -1244,6 +1315,15 @@ static int __cmd_diff(void)
 	return ret;
 }
 
+static int parse_percent_limit(const struct option *opt, const char *arg,
+			       int unset __maybe_unused)
+{
+	struct perf_diff *d = opt->value;
+
+	d->min_percent = strtof(arg, NULL);
+	return 0;
+}
+
 static const char * const diff_usage[] = {
 	"perf diff [<options>] [old_file] [new_file]",
 	NULL,
@@ -1307,6 +1387,9 @@ static const struct option options[] = {
 	OPT_STRING(0, "after", &pdiff.after_dir, "dir",
 		   "Source code directory corresponding to perf.data. "
 		   "WARNING: use with --before and --stream"),
+	OPT_CALLBACK(0, "percent-limit", &pdiff, "percent",
+		     "Don't show entries under that percent",
+		     parse_percent_limit),
 	OPT_END()
 };
 
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ