All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Stephane Eranian <eranian@google.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>,
	David Ahern <dsahern@gmail.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Jiri Olsa <jolsa@redhat.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	LKML <linux-kernel@vger.kernel.org>,
	John Stultz <john.stultz@linaro.org>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Ingo Molnar <mingo@kernel.org>
Subject: Re: [PATCH] perf, record: Add clockid parameter
Date: Sat, 28 Mar 2015 08:55:49 +0100	[thread overview]
Message-ID: <20150328075549.GG27490@worktop.programming.kicks-ass.net> (raw)
In-Reply-To: <CABPqkBR_ou8E01kRmDOBb72ngcdzBkfVPNUj71XWnsYE6i0Bdg@mail.gmail.com>

On Fri, Mar 27, 2015 at 03:37:47PM -0700, Stephane Eranian wrote:
> > +       OPT_INTEGER('k', "clockid", &record.opts.clockid,
> > +                   "clockid to use for events"),
> 
> I think you'd want a symbolic name for the clock to make this easier
> on the user.

Sure, here goes.

--
Subject: perf, record: Add clockid parameter
From: Peter Zijlstra <peterz@infradead.org>
Date: Fri, 27 Mar 2015 15:32:01 +0100

Teach perf-record about the new perf_event_attr::{use_clockid, clockid}
fields. Add a simple parameter to set the clock (if any) to be used for
the events to be recorded into the data file.

Since we store the entire perf_event_attr in the EVENT_DESC section we
also already store the used clockid in the data file.

Cc: acme@redhat.com
Cc: jolsa@redhat.com
Cc: eranian@google.com
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 tools/perf/Documentation/perf-record.txt |    7 ++
 tools/perf/builtin-record.c              |   73 +++++++++++++++++++++++++++++++
 tools/perf/perf.h                        |    1 
 tools/perf/util/evsel.c                  |   44 ++++++++++++++++--
 4 files changed, 121 insertions(+), 4 deletions(-)

--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -250,6 +250,13 @@ is off by default.
 --running-time::
 Record running and enabled time for read events (:S)
 
+-k::
+--clockid::
+Sets the clock id to use for the various time fields in the perf_event_type
+records. See clock_gettime(). In particular CLOCK_MONOTONIC and
+CLOCK_MONOTONIC_RAW are supported, some events might also allow
+CLOCK_BOOTTIME, CLOCK_REALTIME and CLOCK_TAI.
+
 SEE ALSO
 --------
 linkperf:perf-stat[1], linkperf:perf-list[1]
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -711,6 +711,75 @@ static int perf_record_config(const char
 	return perf_default_config(var, value, cb);
 }
 
+struct clockid_map {
+	const char *name;
+	int clockid;
+};
+
+#define CLOCKID_MAP(n, c)	\
+	{ .name = n, .clockid = (c), }
+
+#define CLOCKID_END	{ .name = NULL, }
+
+/*
+ * Doesn't appear to have made it into userspace so define here if missing.
+ */
+#ifndef CLOCK_TAI
+#define CLOCK_TAI 11
+#endif
+
+static const struct clockid_map clockids[] = {
+	/* available for all events, NMI safe */
+	CLOCKID_MAP("monotonic", CLOCK_MONOTONIC),
+	CLOCKID_MAP("monotonic_raw", CLOCK_MONOTONIC_RAW),
+	CLOCKID_MAP("raw", CLOCK_MONOTONIC_RAW),
+
+	/* available for some events */
+	CLOCKID_MAP("realtime", CLOCK_REALTIME),
+	CLOCKID_MAP("boottime", CLOCK_BOOTTIME),
+	CLOCKID_MAP("tai", CLOCK_TAI),
+
+	CLOCKID_END,
+};
+
+static int parse_clockid(const struct option *opt, const char *str, int unset)
+{
+	clockid_t *clk = (clockid_t *)opt->value;
+	const struct clockid_map *cm;
+	const char *ostr = str;
+
+	if (unset) {
+		*clk = -1;
+		return 0;
+	}
+
+	/* no arg passed */
+	if (!str)
+		return 0;
+
+	/* no setting it twice */
+	if (*clk != -1)
+		return -1;
+
+	/* if its a number, we're done */
+	if (sscanf(str, "%d", clk) == 1)
+		return 0;
+
+	/* allow a "CLOCK_" prefix to the name */
+	if (!strncasecmp(str, "CLOCK_", 6))
+		str += 6;
+
+	for (cm = clockids; cm->name; cm++) {
+		if (!strcasecmp(str, cm->name)) {
+			*clk = cm->clockid;
+			return 0;
+		}
+	}
+
+	ui__warning("unknown clockid %s, check man page\n", ostr);
+	return -1;
+}
+
 static const char * const __record_usage[] = {
 	"perf record [<options>] [<command>]",
 	"perf record [<options>] -- <command> [<options>]",
@@ -739,6 +808,7 @@ static struct record record = {
 			.uses_mmap   = true,
 			.default_per_cpu = true,
 		},
+		.clockid             = -1,
 	},
 	.tool = {
 		.sample		= process_sample_event,
@@ -842,6 +912,9 @@ struct option __record_options[] = {
 		    "Sample machine registers on interrupt"),
 	OPT_BOOLEAN(0, "running-time", &record.opts.running_time,
 		    "Record running/enabled time of read (:S) events"),
+	OPT_CALLBACK('k', "clockid", &record.opts.clockid,
+		    "clockid", "clockid to use for events, see clock_gettime()",
+		    parse_clockid),
 	OPT_END()
 };
 
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -62,6 +62,7 @@ struct record_opts {
 	u64	     user_interval;
 	bool	     sample_transaction;
 	unsigned     initial_delay;
+	clockid_t    clockid;
 };
 
 struct option;
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -32,6 +32,7 @@ static struct {
 	bool exclude_guest;
 	bool mmap2;
 	bool cloexec;
+	bool clockid;
 } perf_missing_features;
 
 static int perf_evsel__no_extra_init(struct perf_evsel *evsel __maybe_unused)
@@ -761,6 +762,11 @@ void perf_evsel__config(struct perf_evse
 		attr->disabled = 0;
 		attr->enable_on_exec = 0;
 	}
+
+	if (opts->clockid >= 0) {
+		attr->use_clockid = 1;
+		attr->clockid = opts->clockid;
+	}
 }
 
 static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
@@ -1036,7 +1042,6 @@ static size_t perf_event_attr__fprintf(s
 	ret += PRINT_ATTR2(exclude_user, exclude_kernel);
 	ret += PRINT_ATTR2(exclude_hv, exclude_idle);
 	ret += PRINT_ATTR2(mmap, comm);
-	ret += PRINT_ATTR2(mmap2, comm_exec);
 	ret += PRINT_ATTR2(freq, inherit_stat);
 	ret += PRINT_ATTR2(enable_on_exec, task);
 	ret += PRINT_ATTR2(watermark, precise_ip);
@@ -1044,6 +1049,8 @@ static size_t perf_event_attr__fprintf(s
 	ret += PRINT_ATTR2(exclude_host, exclude_guest);
 	ret += PRINT_ATTR2N("excl.callchain_kern", exclude_callchain_kernel,
 			    "excl.callchain_user", exclude_callchain_user);
+	ret += PRINT_ATTR2(mmap2, comm_exec);
+	ret += __PRINT_ATTR("%u",,use_clockid);
 
 	ret += PRINT_ATTR_U32(wakeup_events);
 	ret += PRINT_ATTR_U32(wakeup_watermark);
@@ -1055,6 +1062,7 @@ static size_t perf_event_attr__fprintf(s
 	ret += PRINT_ATTR_X64(branch_sample_type);
 	ret += PRINT_ATTR_X64(sample_regs_user);
 	ret += PRINT_ATTR_U32(sample_stack_user);
+	ret += PRINT_ATTR_U32(clockid);
 	ret += PRINT_ATTR_X64(sample_regs_intr);
 
 	ret += fprintf(fp, "%.60s\n", graph_dotted_line);
@@ -1085,6 +1093,8 @@ static int __perf_evsel__open(struct per
 	}
 
 fallback_missing_features:
+	if (perf_missing_features.clockid)
+		evsel->attr.use_clockid = 0;
 	if (perf_missing_features.cloexec)
 		flags &= ~(unsigned long)PERF_FLAG_FD_CLOEXEC;
 	if (perf_missing_features.mmap2)
@@ -1122,6 +1132,16 @@ static int __perf_evsel__open(struct per
 				goto try_fallback;
 			}
 			set_rlimit = NO_CHANGE;
+
+			/*
+			 * If we succeeded but had to kill clockid, fail and
+			 * have perf_evsel__open_strerror() print us a nice
+			 * error.
+			 */
+			if (perf_missing_features.clockid) {
+				err = -EINVAL;
+				goto out_close;
+			}
 		}
 	}
 
@@ -1155,7 +1175,10 @@ static int __perf_evsel__open(struct per
 	if (err != -EINVAL || cpu > 0 || thread > 0)
 		goto out_close;
 
-	if (!perf_missing_features.cloexec && (flags & PERF_FLAG_FD_CLOEXEC)) {
+	if (!perf_missing_features.clockid && evsel->attr.use_clockid) {
+		perf_missing_features.clockid = true;
+		goto fallback_missing_features;
+	} else if (!perf_missing_features.cloexec && (flags & PERF_FLAG_FD_CLOEXEC)) {
 		perf_missing_features.cloexec = true;
 		goto fallback_missing_features;
 	} else if (!perf_missing_features.mmap2 && evsel->attr.mmap2) {
@@ -2063,9 +2086,7 @@ int perf_evsel__fprintf(struct perf_evse
 		if_print(exclude_hv);
 		if_print(exclude_idle);
 		if_print(mmap);
-		if_print(mmap2);
 		if_print(comm);
-		if_print(comm_exec);
 		if_print(freq);
 		if_print(inherit_stat);
 		if_print(enable_on_exec);
@@ -2076,10 +2097,19 @@ int perf_evsel__fprintf(struct perf_evse
 		if_print(sample_id_all);
 		if_print(exclude_host);
 		if_print(exclude_guest);
+		if_print(exclude_callchain_kernel);
+		if_print(exclude_callchain_user);
+		if_print(mmap2);
+		if_print(comm_exec);
+		if_print(use_clockid);
 		if_print(__reserved_1);
 		if_print(wakeup_events);
 		if_print(bp_type);
 		if_print(branch_sample_type);
+		if_print(sample_regs_user);
+		if_print(sample_stack_user);
+		if_print(clockid);
+		if_print(sample_regs_intr);
 	}
 out:
 	fputc('\n', fp);
@@ -2158,6 +2188,12 @@ int perf_evsel__open_strerror(struct per
 	"The PMU counters are busy/taken by another profiler.\n"
 	"We found oprofile daemon running, please stop it and try again.");
 		break;
+
+	case EINVAL:
+		if (perf_missing_features.clockid)
+			return scnprintf(msg, size, "%s", "clockid not supported.");
+		break;
+
 	default:
 		break;
 	}

  reply	other threads:[~2015-03-28  7:56 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <tip-34f439278cef7b1177f8ce24f9fc81dfc6221d3b@git.kernel.org>
2015-03-27 14:32 ` [PATCH] perf, record: Add clockid parameter Peter Zijlstra
2015-03-27 17:11   ` David Ahern
2015-03-27 17:20     ` Peter Zijlstra
2015-03-27 17:35       ` David Ahern
2015-03-27 20:15         ` Arnaldo Carvalho de Melo
2015-03-27 21:59           ` Peter Zijlstra
2015-03-27 22:37             ` Stephane Eranian
2015-03-28  7:55               ` Peter Zijlstra [this message]
2015-03-30  1:00                 ` David Ahern
2015-03-30  8:24                   ` Peter Zijlstra
2015-03-30 17:11                     ` David Ahern
2015-03-30  9:17                 ` Peter Zijlstra
2015-03-30 17:17                   ` David Ahern
2015-03-30 19:32                     ` Peter Zijlstra
2015-03-30 19:39                       ` David Ahern
2015-03-30 17:24                 ` David Ahern
2015-03-30 19:33                   ` Peter Zijlstra
2015-03-30 19:41                     ` David Ahern
2015-03-30 19:43                       ` Stephane Eranian
2015-03-31  8:19                       ` Peter Zijlstra
2015-03-31 10:46                         ` [RFC][PATCH] perf tools: unify perf_event_attr printing Peter Zijlstra
2015-04-01 16:26                           ` Peter Zijlstra
2015-04-01 16:52                             ` Jiri Olsa
2015-04-02  9:01                               ` Adrian Hunter
2015-04-02 11:59                                 ` Peter Zijlstra
2015-04-02 12:54                                   ` Adrian Hunter
2015-04-03 16:11                                   ` Arnaldo Carvalho de Melo
2015-04-03 16:14                                     ` Arnaldo Carvalho de Melo
2015-04-02  8:12                             ` Ingo Molnar
2015-04-02 22:28                               ` Arnaldo Carvalho de Melo
2015-04-02  9:19                             ` Jiri Olsa
2015-03-30 17:33                 ` [PATCH] perf, record: Add clockid parameter David Ahern
2015-03-30 19:34                   ` Peter Zijlstra
2015-03-30 19:46                     ` David Ahern
2015-03-27 23:07           ` Stephane Eranian
2015-03-27 16:31 ` [tip:perf/timer] perf: Add per event clockid support Stephane Eranian
2015-03-27 16:35   ` Peter Zijlstra
2015-03-27 16:52     ` Stephane Eranian
2015-03-27 16:57       ` Peter Zijlstra
2015-03-27 17:00         ` Stephane Eranian

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=20150328075549.GG27490@worktop.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=acme@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=dsahern@gmail.com \
    --cc=eranian@google.com \
    --cc=hpa@zytor.com \
    --cc=john.stultz@linaro.org \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.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.