linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] perf: Introduce function to report unsupported syscall attribute flags
@ 2012-09-12 11:01 Robert Richter
  2012-09-12 11:20 ` Peter Zijlstra
  0 siblings, 1 reply; 5+ messages in thread
From: Robert Richter @ 2012-09-12 11:01 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Ingo Molnar, Stephane Eranian, LKML, Robert Richter

Often a syscall fails with

   Error: sys_perf_event_open() syscall returned with 95 (Operation not supported).  /bin/dmesg may provide additional information.

but no additional information.

This patch adds some macro magic and a helper function to check and
report unsupported syscall attribute flags:

 has_unsupported_flags(attr1, attr2);
 has_unsupported_flag(attr, flag);
 __has_unsupported_flags(const struct perf_event_attr *attr,
                         u64 notsup);

E.g. dmesg reports the following (checking for the exclude_guest
flag):

 perf: unsupported attribute flags: 0000000000100000

or (checking precise modifier :ppp):

 perf: unsupported attribute flags: 0000000000018000

Signed-off-by: Robert Richter <robert.richter@amd.com>
---
 arch/x86/kernel/cpu/perf_event.c         |   19 ++++++++++---------
 arch/x86/kernel/cpu/perf_event_amd_ibs.c |    3 ++-
 include/linux/perf_event.h               |   23 +++++++++++++++++++++++
 kernel/events/core.c                     |    2 +-
 4 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 915b876..9ae8676 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -336,7 +336,7 @@ int x86_setup_perfctr(struct perf_event *event)
 			return -EOPNOTSUPP;
 
 		/* BTS is currently only allowed for user-mode. */
-		if (!attr->exclude_kernel)
+		if (has_unsupported_flag(attr, exclude_kernel))
 			return -EOPNOTSUPP;
 	}
 
@@ -389,8 +389,11 @@ int x86_pmu_hw_config(struct perf_event *event)
 				precise++;
 		}
 
-		if (event->attr.precise_ip > precise)
+		if (event->attr.precise_ip > precise) {
+			has_unsupported_flag(&event->attr, precise_ip);
 			return -EOPNOTSUPP;
+		}
+
 		/*
 		 * check that PEBS LBR correction does not conflict with
 		 * whatever the user is asking with attr->branch_sample_type
@@ -398,13 +401,7 @@ int x86_pmu_hw_config(struct perf_event *event)
 		if (event->attr.precise_ip > 1) {
 			u64 *br_type = &event->attr.branch_sample_type;
 
-			if (has_branch_stack(event)) {
-				if (!precise_br_compat(event))
-					return -EOPNOTSUPP;
-
-				/* branch_sample_type is compatible */
-
-			} else {
+			if (!has_branch_stack(event)) {
 				/*
 				 * user did not specify  branch_sample_type
 				 *
@@ -419,7 +416,11 @@ int x86_pmu_hw_config(struct perf_event *event)
 
 				if (!event->attr.exclude_kernel)
 					*br_type |= PERF_SAMPLE_BRANCH_KERNEL;
+			} else if (!precise_br_compat(event)) {
+				has_unsupported_flag(&event->attr, precise_ip);
+				return -EOPNOTSUPP;
 			}
+			/* else: branch_sample_type is compatible */
 		}
 	}
 
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
index 4af8275..fc145b0 100644
--- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c
+++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
@@ -186,6 +186,7 @@ static int perf_ibs_precise_event(struct perf_event *event, u64 *config)
 	case 2:
 		break;
 	default:
+		has_unsupported_flag(&event->attr, precise_ip);
 		return -EOPNOTSUPP;
 	}
 
@@ -243,7 +244,7 @@ static int perf_ibs_init(struct perf_event *event)
 	if (event->pmu != &perf_ibs->pmu)
 		return -ENOENT;
 
-	if (perf_flags(&event->attr) & perf_flags(&ibs_notsupp))
+	if (has_unsupported_flags(&event->attr, &ibs_notsupp))
 		return -EINVAL;
 
 	if (config & ~perf_ibs->config_mask)
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index c36a04f..eb247a5 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -305,6 +305,14 @@ struct perf_event_attr {
 };
 
 #define perf_flags(attr)	(*(&(attr)->read_format + 1))
+#define perf_flags_init(flag) ({					\
+	volatile __u64	flags = 0;					\
+	struct perf_event_attr *attr;					\
+	attr = (void *)((char *)&flags -				\
+			(char *)&perf_flags((struct perf_event_attr *)(0))); \
+	if (!WARN_ON(&perf_flags(attr) != &flags)) 			\
+		attr->flag = ~0;					\
+	flags;})
 
 /*
  * Ioctls that can be done on a perf event fd:
@@ -1208,6 +1216,21 @@ extern int perf_event_overflow(struct perf_event *event,
 				 struct perf_sample_data *data,
 				 struct pt_regs *regs);
 
+static inline bool __has_unsupported_flags(const struct perf_event_attr *attr,
+					   u64 notsup)
+{
+	notsup &= perf_flags(attr);
+	if (notsup)
+		pr_warn("perf: unsupported attribute flags: %016llx\n", notsup);
+	return notsup != 0;
+}
+
+#define has_unsupported_flags(attr1, attr2) \
+	__has_unsupported_flags((attr1), perf_flags(attr2))
+/* flag is the name of the member in struct perf_event_attr: */
+#define has_unsupported_flag(attr, flag) \
+	__has_unsupported_flags((attr), perf_flags_init(flag))
+
 static inline bool is_sampling_event(struct perf_event *event)
 {
 	return event->attr.sample_period != 0;
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 2ba8904..2667ef6 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6291,7 +6291,7 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr,
 	if (ret)
 		return -EFAULT;
 
-	if (attr->__reserved_1)
+	if (has_unsupported_flag(attr, __reserved_1))
 		return -EINVAL;
 
 	if (attr->sample_type & ~(PERF_SAMPLE_MAX-1))
-- 
1.7.8.6



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] perf: Introduce function to report unsupported syscall attribute flags
  2012-09-12 11:01 [PATCH] perf: Introduce function to report unsupported syscall attribute flags Robert Richter
@ 2012-09-12 11:20 ` Peter Zijlstra
  2012-09-12 13:02   ` Robert Richter
  2012-09-12 14:26   ` Andi Kleen
  0 siblings, 2 replies; 5+ messages in thread
From: Peter Zijlstra @ 2012-09-12 11:20 UTC (permalink / raw)
  To: Robert Richter; +Cc: Ingo Molnar, Stephane Eranian, LKML

On Wed, 2012-09-12 at 13:01 +0200, Robert Richter wrote:
> +       if (notsup)
> +               pr_warn("perf: unsupported attribute flags: %016llx\n", notsup); 

This is a dmesg DoS..

I'm also not sure dmesg is the right way.. could we not somehow change
the attrs to provide better diagnostic?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] perf: Introduce function to report unsupported syscall attribute flags
  2012-09-12 11:20 ` Peter Zijlstra
@ 2012-09-12 13:02   ` Robert Richter
  2012-09-12 14:26   ` Andi Kleen
  1 sibling, 0 replies; 5+ messages in thread
From: Robert Richter @ 2012-09-12 13:02 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Ingo Molnar, Stephane Eranian, LKML, Arnaldo Carvalho de Melo

On 12.09.12 13:20:43, Peter Zijlstra wrote:
> On Wed, 2012-09-12 at 13:01 +0200, Robert Richter wrote:
> > +       if (notsup)
> > +               pr_warn("perf: unsupported attribute flags: %016llx\n", notsup); 
> 
> This is a dmesg DoS..

This could be avoided by introducing a cpuinfo like sysfs file for
each pmu:

 /sys/bus/event_source/devices/*/flags

Then, userspace should know how to correctly setup the syscall. All
supported attributes would be known to perf and messages would thrown
only if something goes unexpected wrong.

I suggested this already here:

 https://lkml.org/lkml/2012/8/3/214
 https://lkml.org/lkml/2012/9/6/472

> I'm also not sure dmesg is the right way.. could we not somehow change
> the attrs to provide better diagnostic?

I found this discussion without a solution for the problem:

 http://lwn.net/Articles/374794/

Other options could be pr_debug() or trace_printk()'s for debugging
purposes. Or an error report in sysfs:

 cat /sys/bus/event_source/devices/*/log

But the pmu type needs to be known for this.

-Robert

-- 
Advanced Micro Devices, Inc.
Operating System Research Center


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] perf: Introduce function to report unsupported syscall attribute flags
  2012-09-12 11:20 ` Peter Zijlstra
  2012-09-12 13:02   ` Robert Richter
@ 2012-09-12 14:26   ` Andi Kleen
  2012-09-12 14:29     ` Peter Zijlstra
  1 sibling, 1 reply; 5+ messages in thread
From: Andi Kleen @ 2012-09-12 14:26 UTC (permalink / raw)
  To: Peter Zijlstra; +Cc: Robert Richter, Ingo Molnar, Stephane Eranian, LKML

Peter Zijlstra <peterz@infradead.org> writes:

> On Wed, 2012-09-12 at 13:01 +0200, Robert Richter wrote:
>> +       if (notsup)
>> +               pr_warn("perf: unsupported attribute flags: %016llx\n", notsup); 
>
> This is a dmesg DoS..
>
> I'm also not sure dmesg is the right way.. could we not somehow change
> the attrs to provide better diagnostic?

Have a output argument for a string, that is then printed by the user tool?

I agree it's a problem today, i usually have to resort to ftrace to
figure out what'swrong.

-Andi

-- 
ak@linux.intel.com -- Speaking for myself only

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] perf: Introduce function to report unsupported syscall attribute flags
  2012-09-12 14:26   ` Andi Kleen
@ 2012-09-12 14:29     ` Peter Zijlstra
  0 siblings, 0 replies; 5+ messages in thread
From: Peter Zijlstra @ 2012-09-12 14:29 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Robert Richter, Ingo Molnar, Stephane Eranian, LKML

On Wed, 2012-09-12 at 07:26 -0700, Andi Kleen wrote:
> Peter Zijlstra <peterz@infradead.org> writes:
> 
> > On Wed, 2012-09-12 at 13:01 +0200, Robert Richter wrote:
> >> +       if (notsup)
> >> +               pr_warn("perf: unsupported attribute flags: %016llx\n", notsup); 
> >
> > This is a dmesg DoS..
> >
> > I'm also not sure dmesg is the right way.. could we not somehow change
> > the attrs to provide better diagnostic?
> 
> Have a output argument for a string, that is then printed by the user tool?
> 
> I agree it's a problem today, i usually have to resort to ftrace to
> figure out what'swrong.

Yeah, its a pain.. something I was thinking of is zero-ing out the
entire perf_event_attr and set the field that caused the fail to all 1s
(for however many bits that field is wide).

It would destroy the user input, but it also would provide better
feedback on what exact field you went astray.



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-09-12 14:29 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-12 11:01 [PATCH] perf: Introduce function to report unsupported syscall attribute flags Robert Richter
2012-09-12 11:20 ` Peter Zijlstra
2012-09-12 13:02   ` Robert Richter
2012-09-12 14:26   ` Andi Kleen
2012-09-12 14:29     ` Peter Zijlstra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).