From patchwork Wed Oct 14 12:37:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kaixu Xia X-Patchwork-Id: 54920 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f199.google.com (mail-wi0-f199.google.com [209.85.212.199]) by patches.linaro.org (Postfix) with ESMTPS id 22D9523012 for ; Wed, 14 Oct 2015 12:38:39 +0000 (UTC) Received: by wicgb1 with SMTP id gb1sf25895727wic.3 for ; Wed, 14 Oct 2015 05:38:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-type:sender:precedence :list-id:x-original-sender:x-original-authentication-results :mailing-list:list-post:list-help:list-archive:list-unsubscribe; bh=5RcT7AXDGBGJj/n5wffeE5bM8mmeC3X3Te/NOsNuFDE=; b=QwhXHXD+RD/rW47ziNnyQeKFsNlvjZxD6PEmnlid+MNKGRdO64ZaTI9hBp++lp1NRo wc1jVW2z0iUVLjf93FHQ1ElASoSfuPK1J+XFh5PifMwNvCV/PNYYozItxvF/jNuSjLte SPgy05oP4QfIKSO3MXH03iTGz3OgdEeWtoB4/xa3TGLTiQhXc4oswRKW2ROaS/1WSyvG LbM2sL2qtII8rrdmzR6bm5VI9aicpFIL0uhnqD9ATKsSJkg9xXVMwR3r4HzxwNyi6gsg gQVPN48S772v0uJLcSrTqfoeYdkgl2wjLB6YvQInIoXqMWDSc5pFEEihH94nhZTQtTmm 4npQ== X-Gm-Message-State: ALoCoQmFimmFKEyUBjPN1D+cnOpMHqlWDrTk+fHM8R9hW+ny8RPotEaUbgDbIOMVm90+QNuU2CnX X-Received: by 10.180.10.135 with SMTP id i7mr827760wib.2.1444826318401; Wed, 14 Oct 2015 05:38:38 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.25.21.42 with SMTP id l42ls26835lfi.96.gmail; Wed, 14 Oct 2015 05:38:38 -0700 (PDT) X-Received: by 10.112.137.105 with SMTP id qh9mr1513663lbb.54.1444826318093; Wed, 14 Oct 2015 05:38:38 -0700 (PDT) Received: from mail-lb0-f171.google.com (mail-lb0-f171.google.com. [209.85.217.171]) by mx.google.com with ESMTPS id n196si5421196lfn.91.2015.10.14.05.38.38 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 14 Oct 2015 05:38:38 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.171 as permitted sender) client-ip=209.85.217.171; Received: by lbbpp2 with SMTP id pp2so15865865lbb.0 for ; Wed, 14 Oct 2015 05:38:37 -0700 (PDT) X-Received: by 10.112.64.72 with SMTP id m8mr1442621lbs.41.1444826317894; Wed, 14 Oct 2015 05:38:37 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp2707646lbq; Wed, 14 Oct 2015 05:38:36 -0700 (PDT) X-Received: by 10.68.242.41 with SMTP id wn9mr3569505pbc.79.1444826316699; Wed, 14 Oct 2015 05:38:36 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id xu3si12969319pab.194.2015.10.14.05.38.36; Wed, 14 Oct 2015 05:38:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753457AbbJNMia (ORCPT + 30 others); Wed, 14 Oct 2015 08:38:30 -0400 Received: from szxga03-in.huawei.com ([119.145.14.66]:26469 "EHLO szxga03-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753094AbbJNMiX (ORCPT ); Wed, 14 Oct 2015 08:38:23 -0400 Received: from 172.24.1.47 (EHLO szxeml426-hub.china.huawei.com) ([172.24.1.47]) by szxrg03-dlp.huawei.com (MOS 4.4.3-GA FastPath queued) with ESMTP id BOX05724; Wed, 14 Oct 2015 20:38:12 +0800 (CST) Received: from euler.hulk-profiling (10.107.193.250) by szxeml426-hub.china.huawei.com (10.82.67.181) with Microsoft SMTP Server id 14.3.235.1; Wed, 14 Oct 2015 20:38:03 +0800 From: Kaixu Xia To: , , , , , , , CC: , , , , , Subject: [PATCH V2 1/2] bpf: control the trace data output on current cpu when perf sampling Date: Wed, 14 Oct 2015 12:37:56 +0000 Message-ID: <1444826277-94060-2-git-send-email-xiakaixu@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1444826277-94060-1-git-send-email-xiakaixu@huawei.com> References: <1444826277-94060-1-git-send-email-xiakaixu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.107.193.250] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020206.561E4CB6.01A6, 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: 3cb8ed2b300517d9a5bc379060682f93 Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: xiakaixu@huawei.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.171 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This patch adds the flag sample_disable to control the trace data output process when perf sampling. By setting this flag and integrating with ebpf, we can control the data output process and get the samples we are most interested in. The bpf helper bpf_perf_event_sample_control() can control the perf_event on current cpu. Signed-off-by: Kaixu Xia --- include/linux/perf_event.h | 1 + include/uapi/linux/bpf.h | 5 +++++ include/uapi/linux/perf_event.h | 3 ++- kernel/bpf/verifier.c | 3 ++- kernel/events/core.c | 13 +++++++++++++ kernel/trace/bpf_trace.c | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 55 insertions(+), 2 deletions(-) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 092a0e8..dcbf7d5 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -472,6 +472,7 @@ struct perf_event { struct irq_work pending; atomic_t event_limit; + atomic_t sample_disable; void (*destroy)(struct perf_event *); struct rcu_head rcu_head; diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 564f1f0..e2c99c6 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -287,6 +287,11 @@ enum bpf_func_id { * Return: realm if != 0 */ BPF_FUNC_get_route_realm, + + /** + * u64 bpf_perf_event_sample_control(&map, index, flag) + */ + BPF_FUNC_perf_event_sample_control, __BPF_FUNC_MAX_ID, }; diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index 2881145..a2b9dd7 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -331,7 +331,8 @@ struct perf_event_attr { comm_exec : 1, /* flag comm events that are due to an exec */ use_clockid : 1, /* use @clockid for time fields */ context_switch : 1, /* context switch data */ - __reserved_1 : 37; + sample_disable : 1, /* don't output data on samples */ + __reserved_1 : 36; union { __u32 wakeup_events; /* wakeup every n events */ diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 1d6b97b..3ffe630 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -245,6 +245,7 @@ static const struct { } func_limit[] = { {BPF_MAP_TYPE_PROG_ARRAY, BPF_FUNC_tail_call}, {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_read}, + {BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_FUNC_perf_event_sample_control}, }; static void print_verifier_state(struct verifier_env *env) @@ -910,7 +911,7 @@ static int check_map_func_compatibility(struct bpf_map *map, int func_id) * don't allow any other map type to be passed into * the special func; */ - if (bool_map != bool_func) + if (bool_func && bool_map != bool_func) return -EINVAL; } diff --git a/kernel/events/core.c b/kernel/events/core.c index b11756f..942351c 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -6337,6 +6337,9 @@ static int __perf_event_overflow(struct perf_event *event, irq_work_queue(&event->pending); } + if (!atomic_read(&event->sample_disable)) + return ret; + if (event->overflow_handler) event->overflow_handler(event, data, regs); else @@ -7709,6 +7712,14 @@ static void account_event(struct perf_event *event) account_event_cpu(event, event->cpu); } +static void perf_event_check_sample_flag(struct perf_event *event) +{ + if (event->attr.sample_disable == 1) + atomic_set(&event->sample_disable, 0); + else + atomic_set(&event->sample_disable, 1); +} + /* * Allocate and initialize a event structure */ @@ -7840,6 +7851,8 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, } } + perf_event_check_sample_flag(event); + return event; err_per_task: diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 0fe96c7..f261333 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -215,6 +215,36 @@ const struct bpf_func_proto bpf_perf_event_read_proto = { .arg2_type = ARG_ANYTHING, }; +static u64 bpf_perf_event_sample_control(u64 r1, u64 index, u64 flag, u64 r4, u64 r5) +{ + struct bpf_map *map = (struct bpf_map *) (unsigned long) r1; + struct bpf_array *array = container_of(map, struct bpf_array, map); + struct perf_event *event; + + if (unlikely(index >= array->map.max_entries)) + return -E2BIG; + + event = (struct perf_event *)array->ptrs[index]; + if (!event) + return -ENOENT; + + if (flag) + atomic_dec(&event->sample_disable); + else + atomic_inc(&event->sample_disable); + + return 0; +} + +const struct bpf_func_proto bpf_perf_event_sample_control_proto = { + .func = bpf_perf_event_sample_control, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_CONST_MAP_PTR, + .arg2_type = ARG_ANYTHING, + .arg3_type = ARG_ANYTHING, +}; + static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id func_id) { switch (func_id) { @@ -242,6 +272,8 @@ static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id func return &bpf_get_smp_processor_id_proto; case BPF_FUNC_perf_event_read: return &bpf_perf_event_read_proto; + case BPF_FUNC_perf_event_sample_control: + return &bpf_perf_event_sample_control_proto; default: return NULL; }