Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1946054AbbGQKqc (ORCPT ); Fri, 17 Jul 2015 06:46:32 -0400 Received: from szxga03-in.huawei.com ([119.145.14.66]:16741 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757723AbbGQKpX (ORCPT ); Fri, 17 Jul 2015 06:45:23 -0400 From: kaixu xia To: , , , , , , CC: , , , , Subject: [RFC PATCH 5/6] bpf: Implement function bpf_read_pmu() that get the selected hardware PMU conuter Date: Fri, 17 Jul 2015 18:43:35 +0800 Message-ID: <1437129816-13176-6-git-send-email-xiakaixu@huawei.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1437129816-13176-1-git-send-email-xiakaixu@huawei.com> References: <1437129816-13176-1-git-send-email-xiakaixu@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.110.52.33] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020205.55A8DCC0.0059,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-05-26 15:14:31, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: fdc532c1722a5a1e10ef7002edc814a9 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3253 Lines: 101 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. Signed-off-by: kaixu xia --- include/linux/bpf.h | 2 ++ include/uapi/linux/bpf.h | 2 ++ kernel/bpf/helpers.c | 27 +++++++++++++++++++++++++++ kernel/trace/bpf_trace.c | 2 ++ 4 files changed, 33 insertions(+) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 31a93fc..6efff20 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -190,6 +190,8 @@ extern const struct bpf_func_proto bpf_map_lookup_elem_proto; extern const struct bpf_func_proto bpf_map_update_elem_proto; extern const struct bpf_func_proto bpf_map_delete_elem_proto; +extern const struct bpf_func_proto bpf_read_pmu_proto; + extern const struct bpf_func_proto bpf_get_prandom_u32_proto; extern const struct bpf_func_proto bpf_get_smp_processor_id_proto; extern const struct bpf_func_proto bpf_tail_call_proto; diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 47d8516..1431ec6 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -263,6 +263,8 @@ enum bpf_func_id { * Return: 0 on success */ BPF_FUNC_get_current_comm, + + BPF_FUNC_read_pmu, /* u64 bpf_read_pmu(&value) */ __BPF_FUNC_MAX_ID, }; diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 1447ec0..6a0ed1b 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -16,6 +16,7 @@ #include #include #include +#include /* If kernel subsystem is allowing eBPF programs to call this function, * inside its own verifier_ops->get_func_proto() callback it should return @@ -182,3 +183,29 @@ const struct bpf_func_proto bpf_get_current_comm_proto = { .arg1_type = ARG_PTR_TO_STACK, .arg2_type = ARG_CONST_STACK_SIZE, }; + +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; +} + +const struct bpf_func_proto bpf_read_pmu_proto = { + .func = bpf_read_pmu, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_MAP_PERF_EVENT_VALUE, +}; diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 88a041a..2343159 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -183,6 +183,8 @@ static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id func return bpf_get_trace_printk_proto(); case BPF_FUNC_get_smp_processor_id: return &bpf_get_smp_processor_id_proto; + case BPF_FUNC_read_pmu: + return &bpf_read_pmu_proto; default: return NULL; } -- 1.7.10.4 -- 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/