diff mbox

[v2,net-next,1/3] perf, bpf: Add BPF support to all perf_event types

Message ID 20170526055549.557818-2-ast@fb.com
State Changes Requested, archived
Delegated to: David Miller
Headers show

Commit Message

Alexei Starovoitov May 26, 2017, 5:55 a.m. UTC
From: Teng Qin <qinteng@fb.com>

Allow BPF program to attach to all perf_event types supported
by the current bpf and perf code logic, including HW_CACHE, RAW,
and dynamic pmu events.

Also add support for reading these event counters using
bpf_perf_event_read() helper.

Signed-off-by: Teng Qin <qinteng@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
---
 kernel/bpf/arraymap.c    | 26 +++++++++++---------------
 kernel/events/core.c     |  6 +-----
 kernel/trace/bpf_trace.c |  4 ++--
 3 files changed, 14 insertions(+), 22 deletions(-)

Comments

kernel test robot May 26, 2017, 11:04 a.m. UTC | #1
Hi Teng,

[auto build test ERROR on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Alexei-Starovoitov/bpf-Add-BPF-support-to-all-perf_event/20170526-171542
config: ia64-allmodconfig (attached as .config)
compiler: ia64-linux-gcc (GCC) 6.2.0
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=ia64 

All errors (new ones prefixed by >>):

   kernel//bpf/arraymap.c: In function 'perf_event_fd_array_get_ptr':
>> kernel//bpf/arraymap.c:466:11: error: 'struct perf_event' has no member named 'attach_state'
     if (event->attach_state & PERF_ATTACH_TASK)
              ^~

vim +466 kernel//bpf/arraymap.c

   460		if (IS_ERR(perf_file))
   461			return perf_file;
   462	
   463		event = perf_file->private_data;
   464		ee = ERR_PTR(-EINVAL);
   465		/* Per-task events are not supported */
 > 466		if (event->attach_state & PERF_ATTACH_TASK)
   467			goto err_out;
   468	
   469		attr = perf_event_attrs(event);

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
David Miller May 26, 2017, 2:55 p.m. UTC | #2
From: Alexei Starovoitov <ast@fb.com>
Date: Thu, 25 May 2017 22:55:47 -0700

> +	if (event->attach_state & PERF_ATTACH_TASK)
> +		goto err_out;

The attach_state member only exists when PERF_EVENTS is enabled.
Peter Zijlstra May 29, 2017, 9:12 a.m. UTC | #3
On Thu, May 25, 2017 at 10:55:47PM -0700, Alexei Starovoitov wrote:

> +++ b/kernel/bpf/arraymap.c
> @@ -462,26 +462,22 @@ static void *perf_event_fd_array_get_ptr(struct bpf_map *map,
>  
>  	event = perf_file->private_data;
>  	ee = ERR_PTR(-EINVAL);
> +	/* Per-task events are not supported */
> +	if (event->attach_state & PERF_ATTACH_TASK)
> +		goto err_out;
>  
>  	attr = perf_event_attrs(event);
>  	if (IS_ERR(attr) || attr->inherit)
>  		goto err_out;

> +	/* TRACEPOINT and BREAKPOINT not supported in perf_event_read_local */

I cannot find reason for this comment. That is, why would
perf_event_read_local() not support those two types?

> +	if (attr->type == PERF_TYPE_TRACEPOINT ||
> +	    attr->type == PERF_TYPE_BREAKPOINT)
> +		goto err_out;
>  
> +	ee = bpf_event_entry_gen(perf_file, map_file);
> +	if (ee)
> +		return ee;
> +	ee = ERR_PTR(-ENOMEM);
>  
>  err_out:
>  	fput(perf_file);
diff mbox

Patch

diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index 5e00b2333c26..55ffa9949128 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -462,26 +462,22 @@  static void *perf_event_fd_array_get_ptr(struct bpf_map *map,
 
 	event = perf_file->private_data;
 	ee = ERR_PTR(-EINVAL);
+	/* Per-task events are not supported */
+	if (event->attach_state & PERF_ATTACH_TASK)
+		goto err_out;
 
 	attr = perf_event_attrs(event);
 	if (IS_ERR(attr) || attr->inherit)
 		goto err_out;
+	/* TRACEPOINT and BREAKPOINT not supported in perf_event_read_local */
+	if (attr->type == PERF_TYPE_TRACEPOINT ||
+	    attr->type == PERF_TYPE_BREAKPOINT)
+		goto err_out;
 
-	switch (attr->type) {
-	case PERF_TYPE_SOFTWARE:
-		if (attr->config != PERF_COUNT_SW_BPF_OUTPUT)
-			goto err_out;
-		/* fall-through */
-	case PERF_TYPE_RAW:
-	case PERF_TYPE_HARDWARE:
-		ee = bpf_event_entry_gen(perf_file, map_file);
-		if (ee)
-			return ee;
-		ee = ERR_PTR(-ENOMEM);
-		/* fall-through */
-	default:
-		break;
-	}
+	ee = bpf_event_entry_gen(perf_file, map_file);
+	if (ee)
+		return ee;
+	ee = ERR_PTR(-ENOMEM);
 
 err_out:
 	fput(perf_file);
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 6e75a5c9412d..52f667046599 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -8037,12 +8037,8 @@  static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd)
 	bool is_kprobe, is_tracepoint;
 	struct bpf_prog *prog;
 
-	if (event->attr.type == PERF_TYPE_HARDWARE ||
-	    event->attr.type == PERF_TYPE_SOFTWARE)
-		return perf_event_set_bpf_handler(event, prog_fd);
-
 	if (event->attr.type != PERF_TYPE_TRACEPOINT)
-		return -EINVAL;
+		return perf_event_set_bpf_handler(event, prog_fd);
 
 	if (event->tp_event->prog)
 		return -EEXIST;
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 460a031c77e5..8425bf193f39 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -248,8 +248,8 @@  BPF_CALL_2(bpf_perf_event_read, struct bpf_map *, map, u64, flags)
 		return -ENOENT;
 
 	event = ee->event;
-	if (unlikely(event->attr.type != PERF_TYPE_HARDWARE &&
-		     event->attr.type != PERF_TYPE_RAW))
+	if (unlikely(event->attr.type == PERF_TYPE_SOFTWARE &&
+		     event->attr.config == PERF_COUNT_SW_BPF_OUTPUT))
 		return -EINVAL;
 
 	/* make sure event is local and doesn't have pmu::count */