Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Steven Rostedt (Red Hat) and committed by
Arnaldo Carvalho de Melo
2771984c 55426296

+95
+90
tools/lib/traceevent/event-parse.c
··· 4954 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 5048 * pevent_data_comm_from_pid - parse the data into the print format 4959 5049 * @s: the trace_seq to write to
+5
tools/lib/traceevent/event-parse.h
··· 678 678 struct event_format *pevent_data_event_from_type(struct pevent *pevent, int type); 679 679 int pevent_data_pid(struct pevent *pevent, struct pevent_record *rec); 680 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 686 void pevent_event_info(struct trace_seq *s, struct event_format *event, 682 687 struct pevent_record *record); 683 688 int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum,