All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Jiri Olsa <jolsa@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>,
	lkml <linux-kernel@vger.kernel.org>,
	Ingo Molnar <mingo@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>,
	David Ahern <dsahern@gmail.com>, Andi Kleen <ak@linux.intel.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>
Subject: Re: [PATCH 12/12] perf report: Add --task option to display monitored tasks
Date: Mon, 8 Jan 2018 12:55:34 -0300	[thread overview]
Message-ID: <20180108155534.GL25476@kernel.org> (raw)
In-Reply-To: <20180107160356.28203-13-jolsa@kernel.org>

Em Sun, Jan 07, 2018 at 05:03:56PM +0100, Jiri Olsa escreveu:
> Adding --task option to display monitored tasks stored
> in perf.data. Displaying pid/tid/ppid plus the command
> string aligned to distinguish parent and child tasks.

I'm making this --tasks, plural, but then you can also use --task :-)

- Arnaldo
 
>   $ perf record -a
>   ...
>   $ perf report --task
>   #     pid     tid    ppid  comm
>           0       0      -1 |swapper
>           2       2       0 | kthreadd
>       14080   14080       2 |  kworker/u17:1
>           4       4       2 |  kworker/0:0H
>           6       6       2 |  mm_percpu_wq
>   ...
>           1       1       0 | systemd
>       23242   23242       1 |  firefox
>       23242   23298   23242 |   Cache2 I/O
>       23242   23304   23242 |   GMPThread
>   ...
>        1195    1195       1 |  login
>        1611    1611    1195 |   bash
>        1639    1639    1611 |    startx
>        1663    1663    1639 |     xinit
>        1673    1673    1663 |      xmonad-x86_64-l
>       23939   23939    1673 |       xterm
>       23941   23941   23939 |        bash
>       23963   23963   23941 |         mutt
>       24954   24954   23963 |          offlineimap
> 
> Link: http://lkml.kernel.org/n/tip-ehvadnmg8b3kdhvgsbuesbr7@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/Documentation/perf-report.txt |   4 +
>  tools/perf/builtin-report.c              | 136 ++++++++++++++++++++++++++++++-
>  2 files changed, 138 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
> index b0d70bf4ddfe..dcf0d154918f 100644
> --- a/tools/perf/Documentation/perf-report.txt
> +++ b/tools/perf/Documentation/perf-report.txt
> @@ -441,6 +441,10 @@ include::itrace.txt[]
>  	Display overall events statistics without any further processing.
>  	(like the one at the end of the perf report -D command)
>  
> +--task::
> +	Display monitored tasks stored in perf data. Displaying pid/tid/ppid
> +	plus the command string aligned to distinguish parent and child tasks.
> +
>  include::callchain-overhead-calculation.txt[]
>  
>  SEE ALSO
> diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
> index 11d303494b0c..f2ca2cbe63c1 100644
> --- a/tools/perf/builtin-report.c
> +++ b/tools/perf/builtin-report.c
> @@ -15,6 +15,7 @@
>  #include "util/color.h"
>  #include <linux/list.h>
>  #include <linux/rbtree.h>
> +#include <linux/err.h>
>  #include "util/symbol.h"
>  #include "util/callchain.h"
>  #include "util/values.h"
> @@ -61,6 +62,7 @@ struct report {
>  	bool			inverted_callchain;
>  	bool			mem_mode;
>  	bool			stat_mode;
> +	bool			task_mode;
>  	bool			header;
>  	bool			header_only;
>  	bool			nonany_branch_mode;
> @@ -598,6 +600,124 @@ static int stat_print(struct report *rep)
>  	return 0;
>  }
>  
> +static void task_setup(struct report *rep)
> +{
> +	memset(&rep->tool, 0, sizeof(rep->tool));
> +	rep->tool.comm = perf_event__process_comm;
> +	rep->tool.exit = perf_event__process_exit;
> +	rep->tool.fork = perf_event__process_fork;
> +	rep->tool.no_warn = true;
> +}
> +
> +struct task {
> +	struct thread		*thread;
> +	struct list_head	 list;
> +	struct list_head	 children;
> +};
> +
> +static struct task *task_list(struct task *task, struct machine *machine)
> +{
> +	struct thread *parent_thread, *thread = task->thread;
> +	struct task   *parent_task;
> +
> +	/* Already listed. */
> +	if (!list_empty(&task->list))
> +		return NULL;
> +
> +	/* Last one in the chain. */
> +	if (thread->ppid == -1)
> +		return task;
> +
> +	parent_thread = machine__findnew_thread(machine, -1, thread->ppid);
> +	if (!parent_thread)
> +		return ERR_PTR(-ENOMEM);
> +
> +	parent_task = thread__priv(parent_thread);
> +	list_add_tail(&task->list, &parent_task->children);
> +	return task_list(parent_task, machine);
> +}
> +
> +static void task__print_level(struct task *task, FILE *fp, int level)
> +{
> +	struct thread *thread = task->thread;
> +	struct task *child;
> +
> +	fprintf(fp, "  %8d %8d %8d |%*s%s\n",
> +		thread->pid_, thread->tid, thread->ppid,
> +		level, "", thread__comm_str(thread));
> +
> +	if (!list_empty(&task->children)) {
> +		list_for_each_entry(child, &task->children, list)
> +			task__print_level(child, fp, level + 1);
> +	}
> +}
> +
> +static int task_print(struct report *rep, FILE *fp)
> +{
> +	struct perf_session *session = rep->session;
> +	struct machine      *machine = &session->machines.host;
> +	struct task *tasks, *task;
> +	unsigned int nr = 0, itask = 0, i;
> +	struct rb_node *nd;
> +	LIST_HEAD(list);
> +
> +	/*
> +	 * No locking needed while accessing machine->threads,
> +	 * because --task is single threaded command.
> +	 */
> +
> +	/* Count all the threads. */
> +	for (i = 0; i < THREADS__TABLE_SIZE; i++)
> +		nr += machine->threads[i].nr;
> +
> +	tasks = malloc(sizeof(*tasks) * nr);
> +	if (!tasks)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < THREADS__TABLE_SIZE; i++) {
> +		struct threads *threads = &machine->threads[i];
> +
> +		for (nd = rb_first(&threads->entries); nd; nd = rb_next(nd)) {
> +			task = tasks + itask++;
> +
> +			task->thread = rb_entry(nd, struct thread, rb_node);
> +			INIT_LIST_HEAD(&task->children);
> +			INIT_LIST_HEAD(&task->list);
> +			thread__set_priv(task->thread, task);
> +		}
> +	}
> +
> +	/*
> +	 * Iterate every task down to the unprocessed parent
> +	 * and link all in task children list. Task with no
> +	 * parent is added into 'list'.
> +	 */
> +	for (itask = 0; itask < nr; itask++) {
> +		task = tasks + itask;
> +
> +		if (!list_empty(&task->list))
> +			continue;
> +
> +		task = task_list(task, machine);
> +		if (IS_ERR(task)) {
> +			pr_err("Error: failed to process tasks\n");
> +			free(tasks);
> +			return -ENOMEM;
> +		}
> +
> +		if (task)
> +			list_add_tail(&task->list, &list);
> +	}
> +
> +	fprintf(fp, "# %8s %8s %8s  %s\n", "pid", "tid", "ppid", "comm");
> +
> +	list_for_each_entry(task, &list, list)
> +		task__print_level(task, fp, 0);
> +
> +	free(tasks);
> +	return 0;
> +}
> +
>  static int __cmd_report(struct report *rep)
>  {
>  	int ret;
> @@ -632,6 +752,9 @@ static int __cmd_report(struct report *rep)
>  	if (rep->stat_mode)
>  		stat_setup(rep);
>  
> +	if (rep->task_mode)
> +		task_setup(rep);
> +
>  	ret = perf_session__process_events(session);
>  	if (ret) {
>  		ui__error("failed to process sample\n");
> @@ -641,6 +764,9 @@ static int __cmd_report(struct report *rep)
>  	if (rep->stat_mode)
>  		return stat_print(rep);
>  
> +	if (rep->task_mode)
> +		return task_print(rep, stdout);
> +
>  	report__warn_kptr_restrict(rep);
>  
>  	evlist__for_each_entry(session->evlist, pos)
> @@ -798,6 +924,7 @@ int cmd_report(int argc, const char **argv)
>  	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
>  		    "dump raw trace in ASCII"),
>  	OPT_BOOLEAN(0, "stat", &report.stat_mode, "Display event stats"),
> +	OPT_BOOLEAN(0, "task", &report.task_mode, "Display recorded tasks"),
>  	OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
>  		   "file", "vmlinux pathname"),
>  	OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
> @@ -1059,8 +1186,12 @@ int cmd_report(int argc, const char **argv)
>  		report.tool.show_feat_hdr = SHOW_FEAT_HEADER;
>  	if (report.show_full_info)
>  		report.tool.show_feat_hdr = SHOW_FEAT_HEADER_FULL_INFO;
> -	if (report.stat_mode)
> +	if (report.stat_mode || report.task_mode)
>  		use_browser = 0;
> +	if (report.stat_mode && report.task_mode) {
> +		pr_err("Error: --task and --stat options cannot be used together\n");
> +		goto error;
> +	}
>  
>  	if (strcmp(input_name, "-") != 0)
>  		setup_browser(true);
> @@ -1083,7 +1214,8 @@ int cmd_report(int argc, const char **argv)
>  			ret = 0;
>  			goto error;
>  		}
> -	} else if (use_browser == 0 && !quiet && !report.stat_mode) {
> +	} else if (use_browser == 0 && !quiet &&
> +		   !report.stat_mode && !report.task_mode) {
>  		fputs("# To display the perf.data header info, please use --header/--header-only options.\n#\n",
>  		      stdout);
>  	}
> -- 
> 2.13.6

  reply	other threads:[~2018-01-08 15:55 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-07 16:03 [PATCH 00/12] perf: Assorted fixes Jiri Olsa
2018-01-07 16:03 ` [PATCH 01/12] perf tools: Enable LIBBABELTRACE by default Jiri Olsa
2018-01-08 15:17   ` Arnaldo Carvalho de Melo
2018-01-08 15:20     ` Arnaldo Carvalho de Melo
2018-01-08 15:24       ` Arnaldo Carvalho de Melo
2018-01-08 17:11         ` Jiri Olsa
2018-01-08 17:16           ` Jiri Olsa
2018-01-09  9:26             ` [PATCH] perf build: Display EXTRA features for VF=1 build Jiri Olsa
2018-01-19 10:15               ` Jiri Olsa
2018-01-19 12:43                 ` Arnaldo Carvalho de Melo
2018-01-24 11:23               ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-01-11  6:24   ` [tip:perf/core] perf tools: Enable LIBBABELTRACE by default tip-bot for Jiri Olsa
2018-01-07 16:03 ` [PATCH 02/12] perf tools: Display perf_event_attr::namespaces debug info Jiri Olsa
2018-01-11  6:24   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-01-07 16:03 ` [PATCH 03/12] perf: Allocate context task_ctx_data for child event Jiri Olsa
2018-01-08 12:14   ` Peter Zijlstra
2018-01-11  6:24   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-01-07 16:03 ` [PATCH 04/12] perf: Add sample_id to PERF_RECORD_ITRACE_START event comment Jiri Olsa
2018-01-11  6:25   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-01-07 16:03 ` [PATCH 05/12] perf: Make perf_callchain function static Jiri Olsa
2018-01-11  6:25   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-01-07 16:03 ` [PATCH 06/12] perf: Return empty callchain instead of NULL Jiri Olsa
2018-01-08 12:15   ` Peter Zijlstra
2018-01-11  6:26   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-01-07 16:03 ` [PATCH 07/12] perf: Update PERF_RECORD_MISC_* comment for perf_event_header::misc bit 13 Jiri Olsa
2018-01-11  6:26   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-01-07 16:03 ` [PATCH 08/12] perf script: Add support to display sample misc field Jiri Olsa
2018-01-11  6:27   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-01-07 16:03 ` [PATCH 09/12] perf script: Add support to display lost events Jiri Olsa
2018-01-10 15:40   ` Arnaldo Carvalho de Melo
2018-01-10 15:44     ` Jiri Olsa
2018-01-11  6:27   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-01-07 16:03 ` [PATCH 10/12] perf tools: Make the tool's warning messages optional Jiri Olsa
2018-01-11  6:27   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-01-07 16:03 ` [PATCH 11/12] perf report: Add --stat option to display quick data statistics Jiri Olsa
2018-01-11  6:28   ` [tip:perf/core] perf report: Add --stats " tip-bot for Jiri Olsa
2018-01-07 16:03 ` [PATCH 12/12] perf report: Add --task option to display monitored tasks Jiri Olsa
2018-01-08 15:55   ` Arnaldo Carvalho de Melo [this message]
2018-01-08 16:03     ` Arnaldo Carvalho de Melo
2018-01-09  1:56   ` Namhyung Kim
2018-01-09  9:15     ` Jiri Olsa
2018-01-09 13:05       ` Arnaldo Carvalho de Melo
2018-01-09 13:27         ` Jiri Olsa
2018-01-11  6:29   ` [tip:perf/core] perf report: Add --tasks " tip-bot for Jiri Olsa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180108155534.GL25476@kernel.org \
    --to=acme@kernel.org \
    --cc=a.p.zijlstra@chello.nl \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=dsahern@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.