Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754683AbbGQLdy (ORCPT ); Fri, 17 Jul 2015 07:33:54 -0400 Received: from bombadil.infradead.org ([198.137.202.9]:56532 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751376AbbGQLdw (ORCPT ); Fri, 17 Jul 2015 07:33:52 -0400 Date: Fri, 17 Jul 2015 13:33:40 +0200 From: Peter Zijlstra To: kaixu xia Cc: ast@plumgrid.com, davem@davemloft.net, acme@kernel.org, mingo@redhat.com, masami.hiramatsu.pt@hitachi.com, jolsa@kernel.org, wangnan0@huawei.com, linux-kernel@vger.kernel.org, pi3orama@163.com, hekuang@huawei.com Subject: Re: [RFC PATCH 5/6] bpf: Implement function bpf_read_pmu() that get the selected hardware PMU conuter Message-ID: <20150717113340.GZ18673@twins.programming.kicks-ass.net> References: <1437129816-13176-1-git-send-email-xiakaixu@huawei.com> <1437129816-13176-6-git-send-email-xiakaixu@huawei.com> <20150717110541.GJ12596@twins.programming.kicks-ass.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150717110541.GJ12596@twins.programming.kicks-ass.net> User-Agent: Mutt/1.5.21 (2012-12-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3091 Lines: 94 On Fri, Jul 17, 2015 at 01:05:41PM +0200, Peter Zijlstra wrote: > On Fri, Jul 17, 2015 at 06:43:35PM +0800, kaixu xia wrote: > > The function bpf_read_pmu() can get the specific map key, convert > > the corresponding map value to the pointer to struct perf_event and > > return the Hardware PMU counter value. > > Thanks for having me on Cc :/ > > > Signed-off-by: kaixu xia > > --- > > +static u64 bpf_read_pmu(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) > > +{ > > + void *value = (void *) (unsigned long) r1; > > + struct perf_event *event; > > + u64 count; > > + > > + if (!value || !(*(unsigned long *)value)) > > + return 0; > > + > > + event = (struct perf_event *)(*(unsigned long *)value); > > + > > + if (event->state == PERF_EVENT_STATE_ACTIVE) > > + event->pmu->read(event); > > + > > + count = local64_read(&event->count); > > + > > + return count; > > +} > > Hell no, that's way broken. You want something long these lines.. --- include/linux/perf_event.h | 1 + kernel/events/core.c | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 2027809433b3..6e7be7345511 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -661,6 +661,7 @@ extern void perf_pmu_migrate_context(struct pmu *pmu, int src_cpu, int dst_cpu); extern u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running); +extern u64 perf_event_read(struct perf_event *event); struct perf_sample_data { diff --git a/kernel/events/core.c b/kernel/events/core.c index d3dae3419b99..53521360c13d 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3212,15 +3212,31 @@ static inline u64 perf_event_count(struct perf_event *event) return __perf_event_count(event); } -static u64 perf_event_read(struct perf_event *event) +u64 perf_event_read(struct perf_event *event) { /* * If event is enabled and currently active on a CPU, update the * value in the event structure: */ if (event->state == PERF_EVENT_STATE_ACTIVE) { - smp_call_function_single(event->oncpu, - __perf_event_read, event, 1); + /* + * If the event is for the current task, its guaranteed that we + * never need the cross cpu call, and therefore can allow this + * to be called with IRQs disabled. + * + * Avoids the warning otherwise generated by + * smp_call_function_single(). + */ + if (event->ctx->task == current) { + unsigned long flags; + + local_irq_save(flags); + __perf_event_read(event); + local_irq_restore(flags); + } else { + smp_call_function_single(event->oncpu, + __perf_event_read, event, 1); + } } else if (event->state == PERF_EVENT_STATE_INACTIVE) { struct perf_event_context *ctx = event->ctx; unsigned long flags; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/