lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1437035170-12911-3-git-send-email-kan.liang@intel.com>
Date:	Thu, 16 Jul 2015 04:26:08 -0400
From:	kan.liang@...el.com
To:	acme@...nel.org, jolsa@...nel.org
Cc:	namhyung@...nel.org, ak@...ux.intel.com,
	linux-kernel@...r.kernel.org, Kan Liang <kan.liang@...el.com>
Subject: [PATCH RFC V4 2/4] perf,tool: per-event time support

From: Kan Liang <kan.liang@...el.com>

This patchkit adds the ability to turn off time stamps per event.
One usable case of partial time is to work with per-event callgraph to
enable "PEBS threshold > 1" (https://lkml.org/lkml/2015/5/10/196), which
can significantly reduce the sampling overhead.
The event samples with time stamps off will not be ordered.

Signed-off-by: Kan Liang <kan.liang@...el.com>
---
 tools/perf/Documentation/perf-record.txt |  4 +++-
 tools/perf/builtin-record.c              |  7 ++++++-
 tools/perf/builtin-trace.c               |  1 +
 tools/perf/util/evsel.c                  | 30 ++++++++++++++++++++++++++++--
 tools/perf/util/parse-events.c           | 11 +++++++++++
 tools/perf/util/parse-events.h           |  3 +++
 tools/perf/util/parse-events.l           |  1 +
 tools/perf/util/pmu.c                    |  2 +-
 8 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 5b47b2c..df47907 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -49,7 +49,9 @@ OPTIONS
 	  These params can be used to set event defaults.
 	  Here is a list of the params.
 	  - 'period': Set event sampling period
-
+	  - 'time': Disable/enable time stamping. Acceptable values are 1 for
+		    enabling time stamping. 0 for disabling time stamping.
+		    The default is 1.
 	  Note: If user explicitly sets options which conflict with the params,
 	  the value set by the params will be overridden.
 
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 1d40be9..46ebd92 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -953,7 +953,6 @@ const char * const *record_usage = __record_usage;
  */
 static struct record record = {
 	.opts = {
-		.sample_time	     = true,
 		.mmap_pages	     = UINT_MAX,
 		.user_freq	     = UINT_MAX,
 		.user_interval	     = ULLONG_MAX,
@@ -1136,6 +1135,12 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
 		goto out_symbol_exit;
 	}
 
+	/* If no one set time, let time = true as default */
+	if (!rec->opts.sample_time_set && !time_term_detected) {
+		rec->opts.sample_time = true;
+		rec->opts.sample_time_set = true;
+	}
+
 	if (rec->opts.target.tid && !rec->opts.no_inherit_set)
 		rec->opts.no_inherit = true;
 
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 0ebf55b..469d316 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2899,6 +2899,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 	if (trace.trace_pgfaults) {
 		trace.opts.sample_address = true;
 		trace.opts.sample_time = true;
+		trace.opts.sample_time_set = true;
 	}
 
 	if (trace.evlist->nr_entries > 0)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 83c0803..34f9cfd 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -619,10 +619,35 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 	struct perf_event_attr *attr = &evsel->attr;
 	int track = evsel->tracking;
 	bool per_cpu = opts->target.default_per_cpu && !opts->target.per_thread;
+	bool sample_time = opts->sample_time;
 
 	attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1;
 	attr->inherit	    = !opts->no_inherit;
 
+	/*
+	 * If user doesn't explicitly set time option,
+	 * let event attribute decide.
+	 */
+
+	if (!opts->sample_time_set) {
+		if (attr->sample_type & PERF_SAMPLE_TIME)
+			sample_time = true;
+		else
+			sample_time = false;
+	}
+
+	/*
+	 * Event parsing doesn't check the availability
+	 * Clear the bit which event parsing may be set.
+	 * Let following code check and reset if available
+	 *
+	 * Also, the sample size may be caculated mistakenly,
+	 * because event parsing may set the PERF_SAMPLE_TIME.
+	 * Remove the size which add in perf_evsel__init
+	 */
+	if (attr->sample_type & PERF_SAMPLE_TIME)
+		perf_evsel__reset_sample_bit(evsel, TIME);
+
 	perf_evsel__set_sample_bit(evsel, IP);
 	perf_evsel__set_sample_bit(evsel, TID);
 
@@ -705,14 +730,15 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 	/*
 	 * When the user explicitely disabled time don't force it here.
 	 */
-	if (opts->sample_time &&
+	if (sample_time &&
 	    (!perf_missing_features.sample_id_all &&
 	    (!opts->no_inherit || target__has_cpu(&opts->target) || per_cpu ||
 	     opts->sample_time_set)))
 		perf_evsel__set_sample_bit(evsel, TIME);
 
 	if (opts->raw_samples && !evsel->no_aux_samples) {
-		perf_evsel__set_sample_bit(evsel, TIME);
+		if (sample_time)
+			perf_evsel__set_sample_bit(evsel, TIME);
 		perf_evsel__set_sample_bit(evsel, RAW);
 		perf_evsel__set_sample_bit(evsel, CPU);
 	}
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index a71eeb2..c9981df 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -25,6 +25,9 @@
 #ifdef PARSER_DEBUG
 extern int parse_events_debug;
 #endif
+
+bool time_term_detected = false;
+
 int parse_events_parse(void *data, void *scanner);
 
 static struct perf_pmu_event_symbol *perf_pmu_events_list;
@@ -598,6 +601,14 @@ do {									   \
 		 * attr->branch_sample_type = term->val.num;
 		 */
 		break;
+	case PARSE_EVENTS__TERM_TYPE_TIME:
+		CHECK_TYPE_VAL(NUM);
+		if (term->val.num > 1)
+			return -EINVAL;
+		time_term_detected = true;
+		if (term->val.num == 1)
+			attr->sample_type |= PERF_SAMPLE_TIME;
+		 break;
 	case PARSE_EVENTS__TERM_TYPE_NAME:
 		CHECK_TYPE_VAL(STR);
 		break;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index 131f29b..1083478 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -22,6 +22,8 @@ struct tracepoint_path {
 	struct tracepoint_path *next;
 };
 
+extern bool time_term_detected;
+
 extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
 extern struct tracepoint_path *tracepoint_name_to_path(const char *name);
 extern bool have_tracepoints(struct list_head *evlist);
@@ -62,6 +64,7 @@ enum {
 	PARSE_EVENTS__TERM_TYPE_NAME,
 	PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD,
 	PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE,
+	PARSE_EVENTS__TERM_TYPE_TIME,
 };
 
 struct parse_events_term {
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 13cef3c..f542750 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -183,6 +183,7 @@ config2			{ return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); }
 name			{ return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); }
 period			{ return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
 branch_type		{ return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
+time			{ return term(yyscanner, PARSE_EVENTS__TERM_TYPE_TIME); }
 ,			{ return ','; }
 "/"			{ BEGIN(INITIAL); return '/'; }
 {name_minus}		{ return str(yyscanner, PE_NAME); }
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 7bcb8c3..b615cdf 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -607,7 +607,7 @@ static char *formats_error_string(struct list_head *formats)
 {
 	struct perf_pmu_format *format;
 	char *err, *str;
-	static const char *static_terms = "config,config1,config2,name,period,branch_type\n";
+	static const char *static_terms = "config,config1,config2,name,period,branch_type,time\n";
 	unsigned i = 0;
 
 	if (!asprintf(&str, "valid terms:"))
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ