From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935293AbcIVPlP (ORCPT ); Thu, 22 Sep 2016 11:41:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43778 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965322AbcIVPjX (ORCPT ); Thu, 22 Sep 2016 11:39:23 -0400 From: Jiri Olsa To: Arnaldo Carvalho de Melo Cc: lkml , Don Zickus , Joe Mario , Ingo Molnar , Peter Zijlstra , Namhyung Kim , David Ahern , Andi Kleen Subject: [PATCH 51/57] perf c2c report: Allow to set cacheline sort fields Date: Thu, 22 Sep 2016 17:37:19 +0200 Message-Id: <1474558645-19956-52-git-send-email-jolsa@kernel.org> In-Reply-To: <1474558645-19956-1-git-send-email-jolsa@kernel.org> References: <1474558645-19956-1-git-send-email-jolsa@kernel.org> X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Thu, 22 Sep 2016 15:39:23 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Allowing user to configure the way the single cacheline data are sorted after being sorted by offset. Adding 'c' option to specify sorting fields for single cacheline: -c, --coalesce coalesce fields: pid,tid,iaddr,dso It's allowed to use following combination of fields: pid - process pid tid - process tid iaddr - code address dso - shared object Link: http://lkml.kernel.org/n/tip-aka8z31umxoq2gqr5mjd81zr@git.kernel.org Signed-off-by: Jiri Olsa --- tools/perf/builtin-c2c.c | 119 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 102 insertions(+), 17 deletions(-) diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index 771991cf6946..ee64537493ce 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c @@ -46,6 +46,8 @@ struct c2c_hist_entry { struct hist_entry he; }; +static char const *coalesce_default = "pid,tid,iaddr"; + struct perf_c2c { struct perf_tool tool; struct c2c_hists hists; @@ -65,6 +67,11 @@ struct perf_c2c { int shared_clines; int display; + + const char *coalesce; + char *cl_sort; + char *cl_resort; + char *cl_output; }; enum { @@ -237,7 +244,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, if (!mi_dup) goto free_mi; - c2c_hists = he__get_c2c_hists(he, "offset", 2); + c2c_hists = he__get_c2c_hists(he, c2c.cl_sort, 2); if (!c2c_hists) goto free_mi_dup; @@ -1736,22 +1743,7 @@ static int resort_cl_cb(struct hist_entry *he) c2c_hists = c2c_he->hists; if (display && c2c_hists) { - c2c_hists__reinit(c2c_hists, - "percent_rmt_hitm," - "percent_lcl_hitm," - "percent_stores_l1hit," - "percent_stores_l1miss," - "offset," - "pid," - "tid," - "mean_rmt," - "mean_lcl," - "mean_load," - "cpucnt," - "symbol," - "dso," - "node", - "offset,rmt_hitm,lcl_hitm"); + c2c_hists__reinit(c2c_hists, c2c.cl_output, c2c.cl_resort); hists__collapse_resort(&c2c_hists->hists, NULL); hists__output_resort_cb(&c2c_hists->hists, NULL, filter_cb); @@ -1995,6 +1987,7 @@ static void print_c2c_info(FILE *out, struct perf_session *session) } fprintf(out, " Cachelines sort on : %s HITMs\n", c2c.display == DISPLAY_LCL ? "Local" : "Remote"); + fprintf(out, " Cacheline data grouping : %s\n", c2c.cl_sort); } static void perf_c2c__hists_fprintf(FILE *out, struct perf_session *session) @@ -2274,6 +2267,89 @@ static int setup_display(const char *str) return 0; } +#define for_each_token(__tok, __buf, __sep, __tmp) \ + for (__tok = strtok_r(__buf, __sep, &__tmp); __tok; \ + __tok = strtok_r(NULL, __sep, &__tmp)) + +static int build_cl_output(char *cl_sort) +{ + char *tok, *tmp, *buf = strdup(cl_sort); + bool add_pid = false; + bool add_tid = false; + bool add_iaddr = false; + bool add_sym = false; + bool add_dso = false; + bool add_src = false; + + if (!buf) + return -ENOMEM; + + for_each_token(tok, buf, ",", tmp) { + if (!strcmp(tok, "tid")) { + add_tid = true; + } else if (!strcmp(tok, "pid")) { + add_pid = true; + } else if (!strcmp(tok, "iaddr")) { + add_iaddr = true; + add_sym = true; + add_dso = true; + add_src = true; + } else if (!strcmp(tok, "dso")) { + add_dso = true; + } else if (strcmp(tok, "offset")) { + pr_err("unrecognized sort token: %s\n", tok); + return -EINVAL; + } + } + + if (asprintf(&c2c.cl_output, + "%s%s%s%s%s%s%s%s%s", + "percent_rmt_hitm," + "percent_lcl_hitm," + "percent_stores_l1hit," + "percent_stores_l1miss," + "offset,", + add_pid ? "pid," : "", + add_tid ? "tid," : "", + add_iaddr ? "iaddr," : "", + "mean_rmt," + "mean_lcl," + "mean_load," + "cpucnt,", + add_sym ? "symbol," : "", + add_dso ? "dso," : "", + add_src ? "cl_srcline," : "", + "node") < 0) + return -ENOMEM; + + c2c.show_src = add_src; + + free(buf); + return 0; +} + +static int setup_coalesce(const char *coalesce) +{ + const char *c = coalesce ?: coalesce_default; + + if (asprintf(&c2c.cl_sort, "offset,%s", c) < 0) + return -ENOMEM; + + if (build_cl_output(c2c.cl_sort)) + return -1; + + if (asprintf(&c2c.cl_resort, "offset,%s", + c2c.display == DISPLAY_RMT ? + "rmt_hitm,lcl_hitm" : + "lcl_hitm,rmt_hitm") < 0) + return -ENOMEM; + + pr_debug("coalesce sort fields: %s\n", c2c.cl_sort); + pr_debug("coalesce resort fields: %s\n", c2c.cl_resort); + pr_debug("coalesce output fields: %s\n", c2c.cl_output); + return 0; +} + static int perf_c2c__report(int argc, const char **argv) { struct perf_session *session; @@ -2283,6 +2359,7 @@ static int perf_c2c__report(int argc, const char **argv) }; char callchain_default_opt[] = CALLCHAIN_DEFAULT_OPT; const char *display = NULL; + const char *coalesce = NULL; const struct option c2c_options[] = { OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, "file", "vmlinux pathname"), @@ -2302,6 +2379,8 @@ static int perf_c2c__report(int argc, const char **argv) callchain_help, &parse_callchain_opt, callchain_default_opt), OPT_STRING('d', "display", &display, NULL, "lcl,rmt"), + OPT_STRING('c', "coalesce", &coalesce, "coalesce fields", + "coalesce fields: pid,tid,iaddr,dso"), OPT_END() }; int err = 0; @@ -2330,6 +2409,12 @@ static int perf_c2c__report(int argc, const char **argv) if (err) goto out; + err = setup_coalesce(coalesce); + if (err) { + pr_debug("Failed to initialize hists\n"); + goto out; + } + err = c2c_hists__init(&c2c.hists, "dcacheline", 2); if (err) { pr_debug("Failed to initialize hists\n"); -- 2.7.4