Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b498ce1f authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Ingo Molnar
Browse files

perf probe: Simplify event naming



Simplify event naming as <symbol>_<seqnum>. Each event name is
globally unique (group name is not checked). So, if there is
schedule_0, next probe event on schedule() will be schedule_1.

Signed-off-by: default avatarMasami Hiramatsu <mhiramat@redhat.com>
Cc: systemtap <systemtap@sources.redhat.com>
Cc: DLE <dle-develop@lists.sourceforge.net>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: K.Prasad <prasad@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <20091201002024.10235.2353.stgit@harusame>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 4de189fe
Loading
Loading
Loading
Loading
+53 −14
Original line number Diff line number Diff line
@@ -403,6 +403,29 @@ void show_perf_probe_events(void)
	strlist__delete(rawlist);
}

/* Get current perf-probe event names */
static struct strlist *get_perf_event_names(int fd)
{
	unsigned int i;
	char *group, *event;
	struct strlist *sl, *rawlist;
	struct str_node *ent;

	rawlist = get_trace_kprobe_event_rawlist(fd);

	sl = strlist__new(false, NULL);
	for (i = 0; i < strlist__nr_entries(rawlist); i++) {
		ent = strlist__entry(rawlist, i);
		parse_trace_kprobe_event(ent->s, &group, &event, NULL);
		strlist__add(sl, event);
		free(group);
	}

	strlist__delete(rawlist);

	return sl;
}

static int write_trace_kprobe_event(int fd, const char *buf)
{
	int ret;
@@ -416,29 +439,45 @@ static int write_trace_kprobe_event(int fd, const char *buf)
	return ret;
}

static void get_new_event_name(char *buf, size_t len, const char *base,
			       struct strlist *namelist)
{
	int i, ret;
	for (i = 0; i < MAX_EVENT_INDEX; i++) {
		ret = e_snprintf(buf, len, "%s_%d", base, i);
		if (ret < 0)
			die("snprintf() failed: %s", strerror(-ret));
		if (!strlist__has_entry(namelist, buf))
			break;
	}
	if (i == MAX_EVENT_INDEX)
		die("Too many events are on the same function.");
}

void add_trace_kprobe_events(struct probe_point *probes, int nr_probes)
{
	int i, j, fd;
	struct probe_point *pp;
	char buf[MAX_CMDLEN];
	char event[64];
	struct strlist *namelist;

	fd = open_kprobe_events(O_WRONLY, O_APPEND);
	fd = open_kprobe_events(O_RDWR, O_APPEND);
	/* Get current event names */
	namelist = get_perf_event_names(fd);

	for (j = 0; j < nr_probes; j++) {
		pp = probes + j;
		if (pp->found == 1) {
			snprintf(buf, MAX_CMDLEN, "%c:%s/%s_%x %s\n",
				pp->retprobe ? 'r' : 'p', PERFPROBE_GROUP,
				pp->function, pp->offset, pp->probes[0]);
			write_trace_kprobe_event(fd, buf);
		} else
		for (i = 0; i < pp->found; i++) {
				snprintf(buf, MAX_CMDLEN, "%c:%s/%s_%x_%d %s\n",
			/* Get an unused new event name */
			get_new_event_name(event, 64, pp->function, namelist);
			snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n",
				 pp->retprobe ? 'r' : 'p',
					PERFPROBE_GROUP,
					pp->function, pp->offset, i,
				 PERFPROBE_GROUP, event,
				 pp->probes[i]);
			write_trace_kprobe_event(fd, buf);
			/* Add added event name to namelist */
			strlist__add(namelist, event);
		}
	}
	close(fd);
+3 −0
Original line number Diff line number Diff line
@@ -12,4 +12,7 @@ extern int synthesize_trace_kprobe_event(struct probe_point *pp);
extern void add_trace_kprobe_events(struct probe_point *probes, int nr_probes);
extern void show_perf_probe_events(void);

/* Maximum index number of event-name postfix */
#define MAX_EVENT_INDEX	1024

#endif /*_PROBE_EVENT_H */