Re: [PATCH v3 2/3] perf: Userspace event

2014-11-04 Thread Namhyung Kim


Hi Peter and Pawel,

On Tue, 4 Nov 2014 19:40:31 +0100, Peter Zijlstra wrote:
> On Tue, Nov 04, 2014 at 04:42:11PM +, Pawel Moll wrote:
>> 
>> 1. I'm wrong and the record doesn't have to be padded to make it 8 bytes
>> aligned. Then I can drop the additional size field.
>
> No, you're right, we're supposed to stay 8 byte aligned.
>
>> 2. I could impose a limitation on the prctl API that the data size must
>> be 8 bytes aligned. Bad idea in my opinion, I'd rather not.
>
> Agreed.
>
>> 3. The additional size (for the data part) field stays. Notice that
>> PERF_SAMPLE_RAW has it as well :-)
>
> Right, with binary data there is no other day. With \0 terminated
> strings there won't be a problem, but I think we decided we wanted to
> allow any binary blow.

Ah, I missed that.  Thank you guys for explanation.

Thanks,
Namhyung

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


Re: [PATCH v3 2/3] perf: Userspace event

2014-11-04 Thread Peter Zijlstra
On Tue, Nov 04, 2014 at 04:42:11PM +, Pawel Moll wrote:
> 
> 1. I'm wrong and the record doesn't have to be padded to make it 8 bytes
> aligned. Then I can drop the additional size field.

No, you're right, we're supposed to stay 8 byte aligned.

> 2. I could impose a limitation on the prctl API that the data size must
> be 8 bytes aligned. Bad idea in my opinion, I'd rather not.

Agreed.

> 3. The additional size (for the data part) field stays. Notice that
> PERF_SAMPLE_RAW has it as well :-)

Right, with binary data there is no other day. With \0 terminated
strings there won't be a problem, but I think we decided we wanted to
allow any binary blow.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 2/3] perf: Userspace event

2014-11-04 Thread Pawel Moll
On Tue, 2014-11-04 at 06:33 +, Namhyung Kim wrote:
> Hi Pawel,
> 
> On Tue,  4 Nov 2014 00:28:37 +, Pawel Moll wrote:
> > +   /*
> > +* Data in userspace event record is transparent for the kernel
> > +*
> > +* Userspace perf tool code maintains a list of known types with
> > +* reference implementations of parsers for the data field.
> > +*
> > +* Overall size of the record (including type and size fields)
> > +* is always aligned to 8 bytes by adding padding after the data.
> > +*
> > +* struct {
> > +*  struct perf_event_headerheader;
> > +*  u32 type;
> > +*  u32 size;
> 
> The struct perf_event_header also has 'size' field and it has the entire
> length of the record so it's redundant. 

Well, is it? Correct me if I'm wrong, but as far as I remember the
record size must be always aligned to 8 bytes. Thus you can't reliably
derive the data size from it - if I my data is 3 bytes long, I have to
add 5 bytes of padding thus making the header.size = 24 (I'm ignoring
sample_id here), right? So now, decoding the record, all I can do is:
header.size - sizeof(header) - sizeof(type) - sizeof(size) = 24 - 8 - 8
= 8. So, basing on the header.size the data is 8 bytes long. But only 3
first bytes are valid...

To summarize, there are three options:

1. I'm wrong and the record doesn't have to be padded to make it 8 bytes
aligned. Then I can drop the additional size field.

2. I could impose a limitation on the prctl API that the data size must
be 8 bytes aligned. Bad idea in my opinion, I'd rather not.

3. The additional size (for the data part) field stays. Notice that
PERF_SAMPLE_RAW has it as well :-)

>  Also there's 'misc' field in the
> perf_event_header and I guess it can be used as 'type' info as it's
> mostly for cpumode and we are in user mode by definition.

Hm. First of all, I don't really like the idea of "overloading" the misc
meaning. It's a set of flags and I'd rather see it staying like this.

Secondly, I'm not sure that it can be reused - we are in user mode,
true, but it can be either PERF_RECORD_MISC_USER or
PERF_RECORD_MISC_GUEST_USER.

Thirdly, misc is "only" 16 bits wide, and someone even asked for the
type to be 64 bit long! (I suspect he wanted to use it in some special,
hacky way though :-) 32 bit length seems like a reasonable choice,
though.

Do you feel that the "unnecessary" type field is a big problem?

Thanks for your time!

Pawel

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


Re: [PATCH v3 2/3] perf: Userspace event

2014-11-03 Thread Namhyung Kim
Hi Pawel,

On Tue,  4 Nov 2014 00:28:37 +, Pawel Moll wrote:
> + /*
> +  * Data in userspace event record is transparent for the kernel
> +  *
> +  * Userspace perf tool code maintains a list of known types with
> +  * reference implementations of parsers for the data field.
> +  *
> +  * Overall size of the record (including type and size fields)
> +  * is always aligned to 8 bytes by adding padding after the data.
> +  *
> +  * struct {
> +  *  struct perf_event_headerheader;
> +  *  u32 type;
> +  *  u32 size;

The struct perf_event_header also has 'size' field and it has the entire
length of the record so it's redundant.  Also there's 'misc' field in the
perf_event_header and I guess it can be used as 'type' info as it's
mostly for cpumode and we are in user mode by definition.

Thanks,
Namhyung


> +  *  chardata[size];
> +  *  char__padding[-size & 7];
> +  *  struct sample_idsample_id;
> +  * };
> +  */
> + PERF_RECORD_UEVENT  = 11,
> +
>   PERF_RECORD_MAX,/* non-ABI */
>  };
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 2/3] perf: Userspace event

2014-11-03 Thread Pawel Moll
From: Pawel Moll 

This patch adds a PR_TASK_PERF_UEVENT prctl call which can be used by
any process to inject custom data into perf data stream as a new
PERF_RECORD_UEVENT record, if such process is being observed or if it
is running on a CPU being observed by the perf framework.

The prctl call takes the following arguments:

prctl(PR_TASK_PERF_UEVENT, type, size, data, flags);

- type: a number meaning to describe content of the following data.
  Kernel does not pay attention to it and merely passes it further in
  the perf data, therefore its use must be agreed between the events
  producer (the process being observed) and the consumer (performance
  analysis tool). The perf userspace tool will contain a repository of
  "well known" types and reference implementation of their decoders.
- size: Length in bytes of the data.
- data: Pointer to the data.
- flags: Reserved for future use. Always pass zero.

Perf context that are supposed to receive events generated with the
prctl above must be opened with perf_event_attr.uevent set to 1. The
PERF_RECORD_UEVENT records consist of a standard perf event header,
32-bit type value, 32-bit data size and the data itself, followed by
padding to align the overall record size to 8 bytes and optional,
standard sample_id field.

Example use cases:

- "perf_printf" like mechanism to add logging messages to perf data;
  in the simplest case it can be just

prctl(PR_TASK_PERF_UEVENT, 0, 8, "Message", 0);

- synchronisation of performance data generated in user space with the
  perf stream coming from the kernel. For example, the marker can be
  inserted by a JIT engine after it generated portion of the code, but
  before the code is executed for the first time, allowing the
  post-processor to pick the correct debugging information.

Signed-off-by: Pawel Moll 
---
 include/linux/perf_event.h  |  4 +++
 include/uapi/linux/perf_event.h | 23 -
 include/uapi/linux/prctl.h  | 10 ++
 kernel/events/core.c| 71 +
 kernel/sys.c|  5 +++
 5 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index ba490d5..867415d 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -721,6 +721,8 @@ extern int perf_unregister_guest_info_callbacks(struct 
perf_guest_info_callbacks
 extern void perf_event_exec(void);
 extern void perf_event_comm(struct task_struct *tsk, bool exec);
 extern void perf_event_fork(struct task_struct *tsk);
+extern int perf_uevent(struct task_struct *tsk, u32 type, u32 size,
+  const char __user *data);
 
 /* Callchains */
 DECLARE_PER_CPU(struct perf_callchain_entry, perf_callchain_entry);
@@ -830,6 +832,8 @@ static inline void perf_event_mmap(struct vm_area_struct 
*vma)  { }
 static inline void perf_event_exec(void)   { }
 static inline void perf_event_comm(struct task_struct *tsk, bool exec) { }
 static inline void perf_event_fork(struct task_struct *tsk){ }
+static inline int perf_uevent(struct task_struct *tsk, u32 type, u32 size,
+ const char __user *data)  { 
return -1; };
 static inline void perf_event_init(void)   { }
 static inline int  perf_swevent_get_recursion_context(void){ 
return -1; }
 static inline void perf_swevent_put_recursion_context(int rctx)
{ }
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 9d84540..9a64eb1 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -303,7 +303,8 @@ struct perf_event_attr {
exclude_callchain_user   : 1, /* exclude user 
callchains */
mmap2  :  1, /* include mmap with inode 
data */
comm_exec  :  1, /* flag comm events that 
are due to an exec */
-   __reserved_1   : 39;
+   uevents:  1, /* allow uevents into the 
buffer */
+   __reserved_1   : 38;
 
union {
__u32   wakeup_events;/* wakeup every n events */
@@ -712,6 +713,26 @@ enum perf_event_type {
 */
PERF_RECORD_MMAP2   = 10,
 
+   /*
+* Data in userspace event record is transparent for the kernel
+*
+* Userspace perf tool code maintains a list of known types with
+* reference implementations of parsers for the data field.
+*
+* Overall size of the record (including type and size fields)
+* is always aligned to 8 bytes by adding padding after the data.
+*
+* struct {
+*  struct perf_event_headerheader;
+*  u32 type;
+*