All of lore.kernel.org
 help / color / mirror / Atom feed
From: Madadi Vineeth Reddy <vineethr@linux.ibm.com>
To: Arnaldo Carvalho de Melo <acme@kernel.org>,
	Namhyung Kim <namhyung@kernel.org>,
	Ian Rogers <irogers@google.com>,
	Athira Rajeev <atrajeev@linux.vnet.ibm.com>,
	Chen Yu <yu.c.chen@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Jiri Olsa <jolsa@kernel.org>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Kan Liang <kan.liang@linux.intel.com>,
	acme@redhat.com, Fernand Sieber <sieberf@amazon.com>,
	linux-perf-users <linux-perf-users@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Madadi Vineeth Reddy <vineethr@linux.ibm.com>
Subject: [PATCH v5 2/3] perf sched map: Add support for multiple task names using CSV
Date: Wed, 26 Jun 2024 14:45:49 +0530	[thread overview]
Message-ID: <20240626091550.46707-3-vineethr@linux.ibm.com> (raw)
In-Reply-To: <20240626091550.46707-1-vineethr@linux.ibm.com>

To track the scheduling patterns of multiple tasks simultaneously,
multiple task names can be specified using a comma separator
without any whitespace.

Sample output for --task-name perf,wdavdaemon
=============
 .  *A0  .   .   .   .   -   .   131040.641346 secs A0 => wdavdaemon:62509
 .   A0 *B0  .   .   .   -   .   131040.641378 secs B0 => wdavdaemon:62274
 -  *-   -   -   -   -   -   -   131040.641379 secs
*C0  .   B0  .   .   .   .   .   131040.641572 secs C0 => wdavdaemon:62283

...

 -  *-   -   -   -   -   -   -   131041.395649 secs
 .   .   .   .   .   .   .  *X2  131041.403969 secs X2 => perf:70211
 -   -   -   -   -   -   -  *-   131041.404006 secs

Suggested-by: Namhyung Kim <namhyung@kernel.org>
Reviewed-and-tested-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Signed-off-by: Madadi Vineeth Reddy <vineethr@linux.ibm.com>
---
 tools/perf/Documentation/perf-sched.txt |  5 +-
 tools/perf/builtin-sched.c              | 77 +++++++++++++++++++++----
 2 files changed, 69 insertions(+), 13 deletions(-)

diff --git a/tools/perf/Documentation/perf-sched.txt b/tools/perf/Documentation/perf-sched.txt
index 3255e5b8e74b..3095e280eb92 100644
--- a/tools/perf/Documentation/perf-sched.txt
+++ b/tools/perf/Documentation/perf-sched.txt
@@ -131,9 +131,10 @@ OPTIONS for 'perf sched map'
 	Highlight the given pids.
 
 --task-name <task>::
-	Map output only for the given task name. The sched-out
+	Map output only for the given task name(s). Separate the
+	task names with a comma (without whitespace). The sched-out
 	time is printed and is represented by '*-' for the given
-	task name
+	task name(s).
 	('-' indicates other tasks while '.' is idle).
 
 OPTIONS for 'perf sched timehist'
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 57f166662d54..ecb43deb9d74 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1540,24 +1540,72 @@ map__findnew_thread(struct perf_sched *sched, struct machine *machine, pid_t pid
 	return thread;
 }
 
-static bool sched_match_task(const char *comm_str, const char *commands)
+struct CommandList {
+	char **command_list;
+	int command_count;
+};
+
+static void free_command_list(struct CommandList *cmd_list)
+{
+	if (cmd_list) {
+		for (int i = 0; i < cmd_list->command_count; i++)
+			free(cmd_list->command_list[i]);
+		free(cmd_list->command_list);
+		free(cmd_list);
+	}
+}
+
+static struct CommandList *parse_commands(const char *commands)
 {
 	char *commands_copy = NULL;
+	struct CommandList *cmd_list = NULL;
 	char *token = NULL;
-	bool match_found = false;
 
 	commands_copy = strdup(commands);
 	if (commands_copy == NULL)
 		return NULL;
 
+	cmd_list = malloc(sizeof(struct CommandList));
+	if (cmd_list == NULL) {
+		free(commands_copy);
+		return NULL;
+	}
+
+	cmd_list->command_count = 0;
+	cmd_list->command_list = NULL;
+
 	token = strtok(commands_copy, ",");
+	while (token != NULL) {
+		cmd_list->command_list = realloc(cmd_list->command_list, sizeof(char *)
+							*(cmd_list->command_count + 1));
+		if (cmd_list->command_list == NULL) {
+			free_command_list(cmd_list);
+			free(commands_copy);
+			return NULL;
+		}
 
-	while (token != NULL && !match_found) {
-		match_found = !strcmp(comm_str, token);
+		cmd_list->command_list[cmd_list->command_count] = strdup(token);
+		if (cmd_list->command_list[cmd_list->command_count] == NULL) {
+			free_command_list(cmd_list);
+			free(commands_copy);
+			return NULL;
+		}
+
+		cmd_list->command_count++;
 		token = strtok(NULL, ",");
 	}
 
 	free(commands_copy);
+	return cmd_list;
+}
+
+static bool sched_match_task(const char *comm_str, struct CommandList *cmd_list)
+{
+	bool match_found = false;
+
+	for (int i = 0; i < cmd_list->command_count && !match_found; i++)
+		match_found = !strcmp(comm_str, cmd_list->command_list[i]);
+
 	return match_found;
 }
 
@@ -1624,6 +1672,8 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
 	char stimestamp[32];
 	const char *str;
 
+	struct CommandList *cmd_list = NULL;
+
 	BUG_ON(this_cpu.cpu >= MAX_CPUS || this_cpu.cpu < 0);
 
 	if (this_cpu.cpu > sched->max_cpu.cpu)
@@ -1664,7 +1714,11 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
 	sched->curr_thread[this_cpu.cpu] = thread__get(sched_in);
 	sched->curr_out_thread[this_cpu.cpu] = thread__get(sched_out);
 
+	if (sched->map.task_name)
+		cmd_list = parse_commands(sched->map.task_name);
+
 	new_shortname = 0;
+	str = thread__comm_str(sched_in);
 	if (!tr->shortname[0]) {
 		if (!strcmp(thread__comm_str(sched_in), "swapper")) {
 			/*
@@ -1673,8 +1727,7 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
 			 */
 			tr->shortname[0] = '.';
 			tr->shortname[1] = ' ';
-		} else if (!sched->map.task_name || sched_match_task(thread__comm_str(sched_in),
-								sched->map.task_name)) {
+		} else if (!sched->map.task_name || sched_match_task(str, cmd_list)) {
 			tr->shortname[0] = sched->next_shortname1;
 			tr->shortname[1] = sched->next_shortname2;
 
@@ -1703,15 +1756,15 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
 	 * Check which of sched_in and sched_out matches the passed --task-name
 	 * arguments and call the corresponding print_sched_map.
 	 */
-	if (sched->map.task_name && !sched_match_task(str, sched->map.task_name)) {
-		if (!sched_match_task(thread__comm_str(sched_out), sched->map.task_name))
+	if (sched->map.task_name && !sched_match_task(str, cmd_list)) {
+		if (!sched_match_task(thread__comm_str(sched_out), cmd_list))
 			goto out;
 		else
 			goto sched_out;
 
 	} else {
 		str = thread__comm_str(sched_out);
-		if (!(sched->map.task_name && !sched_match_task(str, sched->map.task_name)))
+		if (!(sched->map.task_name && !sched_match_task(str, cmd_list)))
 			proceed = 1;
 	}
 
@@ -1758,8 +1811,10 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
 	color_fprintf(stdout, color, "\n");
 
 out:
-	if (sched->map.task_name)
+	if (sched->map.task_name) {
+		free_command_list(cmd_list);
 		thread__put(sched_out);
+	}
 
 	thread__put(sched_in);
 
@@ -3651,7 +3706,7 @@ int cmd_sched(int argc, const char **argv)
 	OPT_STRING(0, "cpus", &sched.map.cpus_str, "cpus",
                     "display given CPUs in map"),
 	OPT_STRING(0, "task-name", &sched.map.task_name, "task",
-		"map output only for the given task name"),
+		"map output only for the given task name(s)."),
 	OPT_PARENT(sched_options)
 	};
 	const struct option timehist_options[] = {
-- 
2.43.2


  parent reply	other threads:[~2024-06-26  9:17 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-26  9:15 [PATCH v5 0/3] Introduce --task-name and --fuzzy-name options in perf sched map Madadi Vineeth Reddy
2024-06-26  9:15 ` [PATCH v5 1/3] perf sched map: Add task-name option to filter the output map Madadi Vineeth Reddy
2024-06-27 23:13   ` Namhyung Kim
2024-06-30  6:32     ` Madadi Vineeth Reddy
2024-06-26  9:15 ` Madadi Vineeth Reddy [this message]
2024-06-27 23:36   ` [PATCH v5 2/3] perf sched map: Add support for multiple task names using CSV Namhyung Kim
2024-06-30  6:35     ` Madadi Vineeth Reddy
2024-06-26  9:15 ` [PATCH v5 3/3] perf sched map: Add --fuzzy-name option for fuzzy matching in task names Madadi Vineeth Reddy
2024-06-27 23:39   ` Namhyung Kim
2024-06-30  6:36     ` Madadi Vineeth Reddy

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=20240626091550.46707-3-vineethr@linux.ibm.com \
    --to=vineethr@linux.ibm.com \
    --cc=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=adrian.hunter@intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=atrajeev@linux.vnet.ibm.com \
    --cc=irogers@google.com \
    --cc=jolsa@kernel.org \
    --cc=kan.liang@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=sieberf@amazon.com \
    --cc=yu.c.chen@intel.com \
    /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.