Răsfoiți Sursa

perf tools: Handle kernels that don't support attr.exclude_{guest,host}

Just fall back to resetting those fields, if set, warning the user that
that feature is not available.

If guest samples appear they will just be discarded because no struct
machine will be found and thus the event will be accounted as not
handled and dropped, see 0c09571.

Reported-by: Namhyung Kim <namhyung@gmail.com>
Tested-by: Joerg Roedel <joerg.roedel@amd.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Joerg Roedel <joerg.roedel@amd.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-vuwxig36mzprl5n7nzvnxxsh@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Arnaldo Carvalho de Melo 13 ani în urmă
părinte
comite
bc76efe645
4 a modificat fișierele cu 39 adăugiri și 15 ștergeri
  1. 20 9
      tools/perf/builtin-record.c
  2. 17 6
      tools/perf/builtin-top.c
  3. 1 0
      tools/perf/perf.h
  4. 1 0
      tools/perf/util/top.h

+ 20 - 9
tools/perf/builtin-record.c

@@ -204,6 +204,9 @@ static void perf_record__open(struct perf_record *rec)
 
 
 		if (opts->group && pos != first)
 		if (opts->group && pos != first)
 			group_fd = first->fd;
 			group_fd = first->fd;
+fallback_missing_features:
+		if (opts->exclude_guest_missing)
+			attr->exclude_guest = attr->exclude_host = 0;
 retry_sample_id:
 retry_sample_id:
 		attr->sample_id_all = opts->sample_id_all_avail ? 1 : 0;
 		attr->sample_id_all = opts->sample_id_all_avail ? 1 : 0;
 try_again:
 try_again:
@@ -217,15 +220,23 @@ try_again:
 			} else if (err ==  ENODEV && opts->cpu_list) {
 			} else if (err ==  ENODEV && opts->cpu_list) {
 				die("No such device - did you specify"
 				die("No such device - did you specify"
 					" an out-of-range profile CPU?\n");
 					" an out-of-range profile CPU?\n");
-			} else if (err == EINVAL && opts->sample_id_all_avail) {
-				/*
-				 * Old kernel, no attr->sample_id_type_all field
-				 */
-				opts->sample_id_all_avail = false;
-				if (!opts->sample_time && !opts->raw_samples && !time_needed)
-					attr->sample_type &= ~PERF_SAMPLE_TIME;
-
-				goto retry_sample_id;
+			} else if (err == EINVAL) {
+				if (!opts->exclude_guest_missing &&
+				    (attr->exclude_guest || attr->exclude_host)) {
+					pr_debug("Old kernel, cannot exclude "
+						 "guest or host samples.\n");
+					opts->exclude_guest_missing = true;
+					goto fallback_missing_features;
+				} else if (opts->sample_id_all_avail) {
+					/*
+					 * Old kernel, no attr->sample_id_type_all field
+					 */
+					opts->sample_id_all_avail = false;
+					if (!opts->sample_time && !opts->raw_samples && !time_needed)
+						attr->sample_type &= ~PERF_SAMPLE_TIME;
+
+					goto retry_sample_id;
+				}
 			}
 			}
 
 
 			/*
 			/*

+ 17 - 6
tools/perf/builtin-top.c

@@ -857,6 +857,9 @@ static void perf_top__start_counters(struct perf_top *top)
 		attr->mmap = 1;
 		attr->mmap = 1;
 		attr->comm = 1;
 		attr->comm = 1;
 		attr->inherit = top->inherit;
 		attr->inherit = top->inherit;
+fallback_missing_features:
+		if (top->exclude_guest_missing)
+			attr->exclude_guest = attr->exclude_host = 0;
 retry_sample_id:
 retry_sample_id:
 		attr->sample_id_all = top->sample_id_all_avail ? 1 : 0;
 		attr->sample_id_all = top->sample_id_all_avail ? 1 : 0;
 try_again:
 try_again:
@@ -868,12 +871,20 @@ try_again:
 			if (err == EPERM || err == EACCES) {
 			if (err == EPERM || err == EACCES) {
 				ui__error_paranoid();
 				ui__error_paranoid();
 				goto out_err;
 				goto out_err;
-			} else if (err == EINVAL && top->sample_id_all_avail) {
-				/*
-				 * Old kernel, no attr->sample_id_type_all field
-				 */
-				top->sample_id_all_avail = false;
-				goto retry_sample_id;
+			} else if (err == EINVAL) {
+				if (!top->exclude_guest_missing &&
+				    (attr->exclude_guest || attr->exclude_host)) {
+					pr_debug("Old kernel, cannot exclude "
+						 "guest or host samples.\n");
+					top->exclude_guest_missing = true;
+					goto fallback_missing_features;
+				} else if (top->sample_id_all_avail) {
+					/*
+					 * Old kernel, no attr->sample_id_type_all field
+					 */
+					top->sample_id_all_avail = false;
+					goto retry_sample_id;
+				}
 			}
 			}
 			/*
 			/*
 			 * If it's cycles then fall back to hrtimer
 			 * If it's cycles then fall back to hrtimer

+ 1 - 0
tools/perf/perf.h

@@ -199,6 +199,7 @@ struct perf_record_opts {
 	bool	     sample_address;
 	bool	     sample_address;
 	bool	     sample_time;
 	bool	     sample_time;
 	bool	     sample_id_all_avail;
 	bool	     sample_id_all_avail;
+	bool	     exclude_guest_missing;
 	bool	     system_wide;
 	bool	     system_wide;
 	bool	     period;
 	bool	     period;
 	unsigned int freq;
 	unsigned int freq;

+ 1 - 0
tools/perf/util/top.h

@@ -34,6 +34,7 @@ struct perf_top {
 	bool		   inherit;
 	bool		   inherit;
 	bool		   group;
 	bool		   group;
 	bool		   sample_id_all_avail;
 	bool		   sample_id_all_avail;
+	bool		   exclude_guest_missing;
 	bool		   dump_symtab;
 	bool		   dump_symtab;
 	const char	   *cpu_list;
 	const char	   *cpu_list;
 	struct hist_entry  *sym_filter_entry;
 	struct hist_entry  *sym_filter_entry;