diff options
| author | Steven Rostedt (Red Hat) <rostedt@goodmis.org> | 2015-03-24 09:57:52 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-03-24 11:19:06 -0400 |
| commit | 2771984c7f5e6cab812e86ec152da4fb5f6df908 (patch) | |
| tree | d64fc4817823894a6a069707812f16bd197c72fa /tools/lib | |
| parent | 55426296963c678650e26fc5e61ea75a5598ef5a (diff) | |
tools lib traceevent: Add pevent_data_pid_from_comm()
There is a pevent_data_comm_from_pid() that returns the cmdline stored for
a given pid in order for users to map pids to comms, but there's no method
to convert a comm back to a pid. This is useful for filters that specify
a comm instead of a PID (it's faster than searching each individual event).
Add a way to retrieve a comm from a pid. Since there can be more than one
pid associated to a comm, it returns a data structure that lets the user
iterate over all the saved comms for a given pid.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/r/20150324135923.001103479@goodmis.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/lib')
| -rw-r--r-- | tools/lib/traceevent/event-parse.c | 90 | ||||
| -rw-r--r-- | tools/lib/traceevent/event-parse.h | 5 |
2 files changed, 95 insertions, 0 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index bdb1dd618e0e..bc227225c7f4 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
| @@ -4954,6 +4954,96 @@ const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid) | |||
| 4954 | return comm; | 4954 | return comm; |
| 4955 | } | 4955 | } |
| 4956 | 4956 | ||
| 4957 | static struct cmdline * | ||
| 4958 | pid_from_cmdlist(struct pevent *pevent, const char *comm, struct cmdline *next) | ||
| 4959 | { | ||
| 4960 | struct cmdline_list *cmdlist = (struct cmdline_list *)next; | ||
| 4961 | |||
| 4962 | if (cmdlist) | ||
| 4963 | cmdlist = cmdlist->next; | ||
| 4964 | else | ||
| 4965 | cmdlist = pevent->cmdlist; | ||
| 4966 | |||
| 4967 | while (cmdlist && strcmp(cmdlist->comm, comm) != 0) | ||
| 4968 | cmdlist = cmdlist->next; | ||
| 4969 | |||
| 4970 | return (struct cmdline *)cmdlist; | ||
| 4971 | } | ||
| 4972 | |||
| 4973 | /** | ||
| 4974 | * pevent_data_pid_from_comm - return the pid from a given comm | ||
| 4975 | * @pevent: a handle to the pevent | ||
| 4976 | * @comm: the cmdline to find the pid from | ||
| 4977 | * @next: the cmdline structure to find the next comm | ||
| 4978 | * | ||
| 4979 | * This returns the cmdline structure that holds a pid for a given | ||
| 4980 | * comm, or NULL if none found. As there may be more than one pid for | ||
| 4981 | * a given comm, the result of this call can be passed back into | ||
| 4982 | * a recurring call in the @next paramater, and then it will find the | ||
| 4983 | * next pid. | ||
| 4984 | * Also, it does a linear seach, so it may be slow. | ||
| 4985 | */ | ||
| 4986 | struct cmdline *pevent_data_pid_from_comm(struct pevent *pevent, const char *comm, | ||
| 4987 | struct cmdline *next) | ||
| 4988 | { | ||
| 4989 | struct cmdline *cmdline; | ||
| 4990 | |||
| 4991 | /* | ||
| 4992 | * If the cmdlines have not been converted yet, then use | ||
| 4993 | * the list. | ||
| 4994 | */ | ||
| 4995 | if (!pevent->cmdlines) | ||
| 4996 | return pid_from_cmdlist(pevent, comm, next); | ||
| 4997 | |||
| 4998 | if (next) { | ||
| 4999 | /* | ||
| 5000 | * The next pointer could have been still from | ||
| 5001 | * a previous call before cmdlines were created | ||
| 5002 | */ | ||
| 5003 | if (next < pevent->cmdlines || | ||
| 5004 | next >= pevent->cmdlines + pevent->cmdline_count) | ||
| 5005 | next = NULL; | ||
| 5006 | else | ||
| 5007 | cmdline = next++; | ||
| 5008 | } | ||
| 5009 | |||
| 5010 | if (!next) | ||
| 5011 | cmdline = pevent->cmdlines; | ||
| 5012 | |||
| 5013 | while (cmdline < pevent->cmdlines + pevent->cmdline_count) { | ||
| 5014 | if (strcmp(cmdline->comm, comm) == 0) | ||
| 5015 | return cmdline; | ||
| 5016 | cmdline++; | ||
| 5017 | } | ||
| 5018 | return NULL; | ||
| 5019 | } | ||
| 5020 | |||
| 5021 | /** | ||
| 5022 | * pevent_cmdline_pid - return the pid associated to a given cmdline | ||
| 5023 | * @cmdline: The cmdline structure to get the pid from | ||
| 5024 | * | ||
| 5025 | * Returns the pid for a give cmdline. If @cmdline is NULL, then | ||
| 5026 | * -1 is returned. | ||
| 5027 | */ | ||
| 5028 | int pevent_cmdline_pid(struct pevent *pevent, struct cmdline *cmdline) | ||
| 5029 | { | ||
| 5030 | struct cmdline_list *cmdlist = (struct cmdline_list *)cmdline; | ||
| 5031 | |||
| 5032 | if (!cmdline) | ||
| 5033 | return -1; | ||
| 5034 | |||
| 5035 | /* | ||
| 5036 | * If cmdlines have not been created yet, or cmdline is | ||
| 5037 | * not part of the array, then treat it as a cmdlist instead. | ||
| 5038 | */ | ||
| 5039 | if (!pevent->cmdlines || | ||
| 5040 | cmdline < pevent->cmdlines || | ||
| 5041 | cmdline >= pevent->cmdlines + pevent->cmdline_count) | ||
| 5042 | return cmdlist->pid; | ||
| 5043 | |||
| 5044 | return cmdline->pid; | ||
| 5045 | } | ||
| 5046 | |||
| 4957 | /** | 5047 | /** |
| 4958 | * pevent_data_comm_from_pid - parse the data into the print format | 5048 | * pevent_data_comm_from_pid - parse the data into the print format |
| 4959 | * @s: the trace_seq to write to | 5049 | * @s: the trace_seq to write to |
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 84e554f84574..8bd7c6a4cbd7 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h | |||
| @@ -678,6 +678,11 @@ int pevent_data_type(struct pevent *pevent, struct pevent_record *rec); | |||
| 678 | struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type); | 678 | struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type); |
| 679 | int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec); | 679 | int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec); |
| 680 | const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid); | 680 | const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid); |
| 681 | struct cmdline; | ||
| 682 | struct cmdline *pevent_data_pid_from_comm(struct pevent *pevent, const char *comm, | ||
| 683 | struct cmdline *next); | ||
| 684 | int pevent_cmdline_pid(struct pevent *pevent, struct cmdline *cmdline); | ||
| 685 | |||
| 681 | void pevent_event_info(struct trace_seq *s, struct event_format *event, | 686 | void pevent_event_info(struct trace_seq *s, struct event_format *event, |
| 682 | struct pevent_record *record); | 687 | struct pevent_record *record); |
| 683 | int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum, | 688 | int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum, |
