From patchwork Wed Apr 15 19:27:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yonghong Song X-Patchwork-Id: 221145 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9AD1FC3815B for ; Wed, 15 Apr 2020 19:29:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 75EA520784 for ; Wed, 15 Apr 2020 19:29:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=fb.com header.i=@fb.com header.b="jYAcn1DS" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2436609AbgDOT3U (ORCPT ); Wed, 15 Apr 2020 15:29:20 -0400 Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:20646 "EHLO mx0b-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2411842AbgDOT23 (ORCPT ); Wed, 15 Apr 2020 15:28:29 -0400 Received: from pps.filterd (m0109332.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 03FJPM7p008538 for ; Wed, 15 Apr 2020 12:28:26 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=facebook; bh=yKfP/7ju0dRYFRdfnVBsgmpyxRc4+rvgre4fkivzezM=; b=jYAcn1DSA/Te2FpBsHgtLKog50HZhxOShumbcFIWqh5quOJUW1yeKrRgdG5Q9Si0+TGB 9oHC2alooBMqgkE5tAH5Ws1qtOmU/dr9hW4rT7FVm8ziiAfm+2oj1y2L8jdfTT6W40sM ZfS8Dlf4Hqul/UA4KPa2ePhV3U/i93hliTs= Received: from mail.thefacebook.com ([163.114.132.120]) by mx0a-00082601.pphosted.com with ESMTP id 30dn7t7m78-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Wed, 15 Apr 2020 12:28:26 -0700 Received: from intmgw004.03.ash8.facebook.com (2620:10d:c085:108::4) by mail.thefacebook.com (2620:10d:c085:21d::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1847.3; Wed, 15 Apr 2020 12:27:56 -0700 Received: by devbig003.ftw2.facebook.com (Postfix, from userid 128203) id 98E1C3700AF5; Wed, 15 Apr 2020 12:27:55 -0700 (PDT) Smtp-Origin-Hostprefix: devbig From: Yonghong Song Smtp-Origin-Hostname: devbig003.ftw2.facebook.com To: Andrii Nakryiko , , Martin KaFai Lau , CC: Alexei Starovoitov , Daniel Borkmann , Smtp-Origin-Cluster: ftw2c04 Subject: [RFC PATCH bpf-next v2 13/17] tools/libbpf: libbpf support for bpfdump Date: Wed, 15 Apr 2020 12:27:55 -0700 Message-ID: <20200415192755.4083842-1-yhs@fb.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200415192740.4082659-1-yhs@fb.com> References: <20200415192740.4082659-1-yhs@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.676 definitions=2020-04-15_07:2020-04-14,2020-04-15 signatures=0 X-Proofpoint-Spam-Details: rule=fb_default_notspam policy=fb_default score=0 clxscore=1015 adultscore=0 phishscore=0 malwarescore=0 impostorscore=0 mlxlogscore=999 bulkscore=0 spamscore=0 priorityscore=1501 suspectscore=2 lowpriorityscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004150143 X-FB-Internal: deliver Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add a few libbpf APIs for bpfdump pin. Also, parse the dump program section name, retrieve the dump target path and open the path to get a fd and assignment to prog->attach_target_fd. The implementation is absolutely minimum and hacky now. Signed-off-by: Yonghong Song --- tools/lib/bpf/bpf.c | 9 +++- tools/lib/bpf/bpf.h | 1 + tools/lib/bpf/libbpf.c | 88 +++++++++++++++++++++++++++++++++++++--- tools/lib/bpf/libbpf.h | 3 ++ tools/lib/bpf/libbpf.map | 2 + 5 files changed, 95 insertions(+), 8 deletions(-) diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index 5cc1b0785d18..b23f11c53109 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -238,10 +238,15 @@ int bpf_load_program_xattr(const struct bpf_load_program_attr *load_attr, if (attr.prog_type == BPF_PROG_TYPE_STRUCT_OPS || attr.prog_type == BPF_PROG_TYPE_LSM) { attr.attach_btf_id = load_attr->attach_btf_id; - } else if (attr.prog_type == BPF_PROG_TYPE_TRACING || - attr.prog_type == BPF_PROG_TYPE_EXT) { + } else if (attr.prog_type == BPF_PROG_TYPE_EXT) { attr.attach_btf_id = load_attr->attach_btf_id; attr.attach_prog_fd = load_attr->attach_prog_fd; + } else if (attr.prog_type == BPF_PROG_TYPE_TRACING) { + attr.attach_btf_id = load_attr->attach_btf_id; + if (attr.expected_attach_type == BPF_TRACE_DUMP) + attr.attach_target_fd = load_attr->attach_target_fd; + else + attr.attach_prog_fd = load_attr->attach_prog_fd; } else { attr.prog_ifindex = load_attr->prog_ifindex; attr.kern_version = load_attr->kern_version; diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index 46d47afdd887..7f8d740afde9 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h @@ -81,6 +81,7 @@ struct bpf_load_program_attr { union { __u32 kern_version; __u32 attach_prog_fd; + __u32 attach_target_fd; }; union { __u32 prog_ifindex; diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index ff9174282a8c..ad7726c0c1dc 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -79,6 +79,7 @@ static struct bpf_program *bpf_object__find_prog_by_idx(struct bpf_object *obj, int idx); static const struct btf_type * skip_mods_and_typedefs(const struct btf *btf, __u32 id, __u32 *res_id); +static int fill_dumper_info(struct bpf_program *prog); static int __base_pr(enum libbpf_print_level level, const char *format, va_list args) @@ -229,6 +230,7 @@ struct bpf_program { enum bpf_attach_type expected_attach_type; __u32 attach_btf_id; __u32 attach_prog_fd; + __u32 attach_target_fd; void *func_info; __u32 func_info_rec_size; __u32 func_info_cnt; @@ -2365,8 +2367,12 @@ static inline bool libbpf_prog_needs_vmlinux_btf(struct bpf_program *prog) /* BPF_PROG_TYPE_TRACING programs which do not attach to other programs * also need vmlinux BTF */ - if (prog->type == BPF_PROG_TYPE_TRACING && !prog->attach_prog_fd) - return true; + if (prog->type == BPF_PROG_TYPE_TRACING) { + if (prog->expected_attach_type == BPF_TRACE_DUMP) + return false; + if (!prog->attach_prog_fd) + return true; + } return false; } @@ -4870,10 +4876,15 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt, if (prog->type == BPF_PROG_TYPE_STRUCT_OPS || prog->type == BPF_PROG_TYPE_LSM) { load_attr.attach_btf_id = prog->attach_btf_id; - } else if (prog->type == BPF_PROG_TYPE_TRACING || - prog->type == BPF_PROG_TYPE_EXT) { + } else if (prog->type == BPF_PROG_TYPE_EXT) { load_attr.attach_prog_fd = prog->attach_prog_fd; load_attr.attach_btf_id = prog->attach_btf_id; + } else if (prog->type == BPF_PROG_TYPE_TRACING) { + load_attr.attach_btf_id = prog->attach_btf_id; + if (load_attr.expected_attach_type == BPF_TRACE_DUMP) + load_attr.attach_target_fd = prog->attach_target_fd; + else + load_attr.attach_prog_fd = prog->attach_prog_fd; } else { load_attr.kern_version = kern_version; load_attr.prog_ifindex = prog->prog_ifindex; @@ -4958,7 +4969,7 @@ int bpf_program__load(struct bpf_program *prog, char *license, __u32 kern_ver) { int err = 0, fd, i, btf_id; - if ((prog->type == BPF_PROG_TYPE_TRACING || + if (((prog->type == BPF_PROG_TYPE_TRACING && prog->expected_attach_type != BPF_TRACE_DUMP) || prog->type == BPF_PROG_TYPE_LSM || prog->type == BPF_PROG_TYPE_EXT) && !prog->attach_btf_id) { btf_id = libbpf_find_attach_btf_id(prog); @@ -5319,6 +5330,7 @@ static int bpf_object__resolve_externs(struct bpf_object *obj, int bpf_object__load_xattr(struct bpf_object_load_attr *attr) { + struct bpf_program *prog; struct bpf_object *obj; int err, i; @@ -5335,7 +5347,17 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr) obj->loaded = true; - err = bpf_object__probe_caps(obj); + err = 0; + bpf_object__for_each_program(prog, obj) { + if (prog->type == BPF_PROG_TYPE_TRACING && + prog->expected_attach_type == BPF_TRACE_DUMP) { + err = fill_dumper_info(prog); + if (err) + break; + } + } + + err = err ? : bpf_object__probe_caps(obj); err = err ? : bpf_object__resolve_externs(obj, obj->kconfig); err = err ? : bpf_object__sanitize_and_load_btf(obj); err = err ? : bpf_object__sanitize_maps(obj); @@ -6322,6 +6344,8 @@ static const struct bpf_sec_def section_defs[] = { .is_attach_btf = true, .expected_attach_type = BPF_LSM_MAC, .attach_fn = attach_lsm), + SEC_DEF("dump/", TRACING, + .expected_attach_type = BPF_TRACE_DUMP), BPF_PROG_SEC("xdp", BPF_PROG_TYPE_XDP), BPF_PROG_SEC("perf_event", BPF_PROG_TYPE_PERF_EVENT), BPF_PROG_SEC("lwt_in", BPF_PROG_TYPE_LWT_IN), @@ -6401,6 +6425,58 @@ static const struct bpf_sec_def *find_sec_def(const char *sec_name) return NULL; } +static int fill_dumper_info(struct bpf_program *prog) +{ + const struct bpf_sec_def *sec; + const char *dump_target; + int fd; + + sec = find_sec_def(bpf_program__title(prog, false)); + if (sec) { + dump_target = bpf_program__title(prog, false) + sec->len; + fd = open(dump_target, O_RDONLY); + if (fd < 0) + return fd; + prog->attach_target_fd = fd; + } + return 0; +} + +int bpf_dump__pin(struct bpf_program *prog, const char *dname) +{ + int len, prog_fd = bpf_program__fd(prog); + const struct bpf_sec_def *sec; + const char *dump_target; + char *name_buf; + int err; + + if (dname[0] == '/') + return bpf_obj_pin(prog_fd, dname); + + sec = find_sec_def(bpf_program__title(prog, false)); + if (!sec) + return bpf_obj_pin(prog_fd, dname); + + dump_target = bpf_program__title(prog, false) + sec->len; + len = strlen(dump_target) + strlen(dname) + 2; + name_buf = malloc(len); + if (!name_buf) + return -ENOMEM; + + strcpy(name_buf, dump_target); + strcat(name_buf, "/"); + strcat(name_buf, dname); + + err = bpf_obj_pin(prog_fd, name_buf); + free(name_buf); + return err; +} + +int bpf_dump__unpin(struct bpf_program *prog, const char *dname) +{ + return -EINVAL; +} + static char *libbpf_get_type_names(bool attach_type) { int i, len = ARRAY_SIZE(section_defs) * MAX_TYPE_NAME_SIZE; diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 44df1d3e7287..e0d31e93d21c 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -217,6 +217,9 @@ LIBBPF_API int bpf_program__pin(struct bpf_program *prog, const char *path); LIBBPF_API int bpf_program__unpin(struct bpf_program *prog, const char *path); LIBBPF_API void bpf_program__unload(struct bpf_program *prog); +LIBBPF_API int bpf_dump__pin(struct bpf_program *prog, const char *dname); +LIBBPF_API int bpf_dump__unpin(struct bpf_program *prog, const char *dname); + struct bpf_link; LIBBPF_API struct bpf_link *bpf_link__open(const char *path); diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index bb8831605b25..0beb70bfe65a 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -238,6 +238,8 @@ LIBBPF_0.0.7 { LIBBPF_0.0.8 { global: + bpf_dump__pin; + bpf_dump__unpin; bpf_link__fd; bpf_link__open; bpf_link__pin;