From patchwork Sun Sep 6 07:13:38 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Nan X-Patchwork-Id: 53177 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f71.google.com (mail-la0-f71.google.com [209.85.215.71]) by patches.linaro.org (Postfix) with ESMTPS id 0419D22B05 for ; Sun, 6 Sep 2015 07:16:33 +0000 (UTC) Received: by lamp12 with SMTP id p12sf17909080lam.2 for ; Sun, 06 Sep 2015 00:16:32 -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=CwEV+GSFO6ICvJjPfCzwCy8Cbf+/PkgisXK1lZJL00s=; b=gAZLM099L3e/6hfDC2l2U9Q17SsjBBIEKqOUt7pqUgo7733F5W3WhODGkdcKZVVa/a IwbCM+A3eajxRVQPO16CvhOluJlMVOEbajXIXVQBr6sXMoHpNVqtrn2siS92WU3yldqC dfWPFa0B3o5bfaw/MVvzoRwfEcT4DDQtEs9c2VWfUv/oaQJn8bJ4oWtskyDE0O9IYjGh cchxoxVSjC32SeAPpb4G2ce+JS+0wd/9xn/JUu+sDM2SeWSLJSg5rwX5Qyid0C2iNUIP BmU7UG9D+Yu3s8fNbqmghSFcMHyGJDIP3HCK7pI1l+TTBYtKUKd3l/HF+wlo9wLhPcmd TDiQ== X-Gm-Message-State: ALoCoQkAcUR5sRftVvNnJ+Ckzlnhv/4RXYbgiqCjzRcODFFZqOZHkWC4K1q60AnBcdgP5SWXGKWf X-Received: by 10.112.149.39 with SMTP id tx7mr3334876lbb.11.1441523792037; Sun, 06 Sep 2015 00:16:32 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.153.4.43 with SMTP id cb11ls125310lad.65.gmail; Sun, 06 Sep 2015 00:16:31 -0700 (PDT) X-Received: by 10.152.22.99 with SMTP id c3mr11836179laf.32.1441523791864; Sun, 06 Sep 2015 00:16:31 -0700 (PDT) Received: from mail-la0-f43.google.com (mail-la0-f43.google.com. [209.85.215.43]) by mx.google.com with ESMTPS id k3si7215391laf.118.2015.09.06.00.16.31 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 06 Sep 2015 00:16:31 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.43 as permitted sender) client-ip=209.85.215.43; Received: by lanb10 with SMTP id b10so35237243lan.3 for ; Sun, 06 Sep 2015 00:16:31 -0700 (PDT) X-Received: by 10.152.43.198 with SMTP id y6mr11301153lal.41.1441523791746; Sun, 06 Sep 2015 00:16:31 -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.164.42 with SMTP id yn10csp843840lbb; Sun, 6 Sep 2015 00:16:30 -0700 (PDT) X-Received: by 10.68.106.197 with SMTP id gw5mr30595836pbb.1.1441523790567; Sun, 06 Sep 2015 00:16:30 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n7si13809000pap.9.2015.09.06.00.16.29; Sun, 06 Sep 2015 00:16:30 -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 S1752634AbbIFHQO (ORCPT + 28 others); Sun, 6 Sep 2015 03:16:14 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:7777 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751547AbbIFHOu (ORCPT ); Sun, 6 Sep 2015 03:14:50 -0400 Received: from 172.24.1.48 (EHLO SZXEML423-HUB.china.huawei.com) ([172.24.1.48]) by szxrg01-dlp.huawei.com (MOS 4.3.7-GA FastPath queued) with ESMTP id CUK94074; Sun, 06 Sep 2015 15:14:25 +0800 (CST) Received: from linux-4hy3.site (10.107.193.248) by SZXEML423-HUB.china.huawei.com (10.82.67.154) with Microsoft SMTP Server id 14.3.235.1; Sun, 6 Sep 2015 15:14:15 +0800 From: Wang Nan To: , , , CC: , , , , , , , , , , , Subject: [PATCH 22/27] perf tools: Use same BPF program if arguments are identical Date: Sun, 6 Sep 2015 07:13:38 +0000 Message-ID: <1441523623-152703-23-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1441523623-152703-1-git-send-email-wangnan0@huawei.com> References: <1441523623-152703-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.107.193.248] X-CFilter-Loop: Reflected 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: wangnan0@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.215.43 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 allows creating only one BPF program for different 'probe_trace_event'(tev) generated by one 'perf_probe_event'(pev), if their prologues are identical. This is done by comparing argument list of different tev, and maps type of prologue and tev using a mapping array. This patch utilizes qsort to sort tevs. After sorting, tevs with identical argument list will group together. Signed-off-by: Wang Nan Cc: Alexei Starovoitov Cc: Brendan Gregg Cc: Daniel Borkmann Cc: David Ahern Cc: He Kuang Cc: Jiri Olsa Cc: Kaixu Xia Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Zefan Li Cc: pi3orama@163.com Cc: Arnaldo Carvalho de Melo Link: http://lkml.kernel.org/n/1436445342-1402-37-git-send-email-wangnan0@huawei.com --- tools/perf/util/bpf-loader.c | 133 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 126 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c index d3d40f3..67193d2 100644 --- a/tools/perf/util/bpf-loader.c +++ b/tools/perf/util/bpf-loader.c @@ -47,6 +47,8 @@ struct bpf_prog_priv { }; bool need_prologue; struct bpf_insn *insns_buf; + int nr_types; + int *type_mapping; }; static void @@ -71,6 +73,7 @@ bpf_prog_priv__clear(struct bpf_program *prog __maybe_unused, clear_perf_probe_event(&priv->pev); } zfree(&priv->insns_buf); + zfree(&priv->type_mapping); free(priv); } @@ -264,7 +267,7 @@ preproc_gen_prologue(struct bpf_program *prog, int n, struct bpf_prog_priv *priv; struct bpf_insn *buf; size_t prologue_cnt = 0; - int err; + int i, err; err = bpf_program__get_private(prog, (void **)&priv); if (err || !priv || !priv->pev_ready) @@ -272,10 +275,20 @@ preproc_gen_prologue(struct bpf_program *prog, int n, pev = &priv->pev; - if (n < 0 || n >= pev->ntevs) + if (n < 0 || n >= priv->nr_types) goto errout; - tev = &pev->tevs[n]; + /* Find a tev belongs to that type */ + for (i = 0; i < pev->ntevs; i++) + if (priv->type_mapping[i] == n) + break; + + if (i >= pev->ntevs) { + pr_debug("Internal error: prologue type %d not found\n", n); + return -ENOENT; + } + + tev = &pev->tevs[i]; buf = priv->insns_buf; err = bpf__gen_prologue(tev->args, tev->nargs, @@ -306,6 +319,98 @@ errout: return -EINVAL; } +/* + * compare_tev_args is reflexive, transitive and antisymmetric. + * I can show that but this margin is too narrow to contain. + */ +static int compare_tev_args(const void *ptev1, const void *ptev2) +{ + int i, ret; + const struct probe_trace_event *tev1 = + *(const struct probe_trace_event **)ptev1; + const struct probe_trace_event *tev2 = + *(const struct probe_trace_event **)ptev2; + + ret = tev2->nargs - tev1->nargs; + if (ret) + return ret; + + for (i = 0; i < tev1->nargs; i++) { + struct probe_trace_arg *arg1, *arg2; + struct probe_trace_arg_ref *ref1, *ref2; + + arg1 = &tev1->args[i]; + arg2 = &tev2->args[i]; + + ret = strcmp(arg1->value, arg2->value); + if (ret) + return ret; + + ref1 = arg1->ref; + ref2 = arg2->ref; + + while (ref1 && ref2) { + ret = ref2->offset - ref1->offset; + if (ret) + return ret; + + ref1 = ref1->next; + ref2 = ref2->next; + } + + if (ref1 || ref2) + return ref2 ? 1 : -1; + } + + return 0; +} + +static int map_prologue(struct perf_probe_event *pev, int *mapping, + int *nr_types) +{ + int i, type = 0; + struct { + struct probe_trace_event *tev; + int idx; + } *stevs; + size_t array_sz = sizeof(*stevs) * pev->ntevs; + + stevs = malloc(array_sz); + if (!stevs) { + pr_debug("No ehough memory: alloc stevs failed\n"); + return -ENOMEM; + } + + pr_debug("In map_prologue, ntevs=%d\n", pev->ntevs); + for (i = 0; i < pev->ntevs; i++) { + stevs[i].tev = &pev->tevs[i]; + stevs[i].idx = i; + } + qsort(stevs, pev->ntevs, sizeof(*stevs), + compare_tev_args); + + for (i = 0; i < pev->ntevs; i++) { + if (i == 0) { + mapping[stevs[i].idx] = type; + pr_debug("mapping[%d]=%d\n", stevs[i].idx, + type); + continue; + } + + if (compare_tev_args(stevs + i, stevs + i - 1) == 0) + mapping[stevs[i].idx] = type; + else + mapping[stevs[i].idx] = ++type; + + pr_debug("mapping[%d]=%d\n", stevs[i].idx, + mapping[stevs[i].idx]); + } + free(stevs); + *nr_types = type + 1; + + return 0; +} + static int hook_load_preprocessor(struct bpf_program *prog) { struct perf_probe_event *pev; @@ -346,7 +451,19 @@ static int hook_load_preprocessor(struct bpf_program *prog) return -ENOMEM; } - err = bpf_program__set_prep(prog, pev->ntevs, + priv->type_mapping = malloc(sizeof(int) * pev->ntevs); + if (!priv->type_mapping) { + pr_debug("No enough memory: alloc type_mapping failed\n"); + return -ENOMEM; + } + memset(priv->type_mapping, 0xff, + sizeof(int) * pev->ntevs); + + err = map_prologue(pev, priv->type_mapping, &priv->nr_types); + if (err) + return err; + + err = bpf_program__set_prep(prog, priv->nr_types, preproc_gen_prologue); return err; } @@ -489,9 +606,11 @@ int bpf__foreach_tev(bpf_prog_iter_callback_t func, void *arg) for (i = 0; i < pev->ntevs; i++) { tev = &pev->tevs[i]; - if (priv->need_prologue) - fd = bpf_program__nth_fd(prog, i); - else + if (priv->need_prologue) { + int type = priv->type_mapping[i]; + + fd = bpf_program__nth_fd(prog, type); + } else fd = bpf_program__fd(prog); if (fd < 0) {