From patchwork Wed Nov 24 08:41:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 12636367 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9FD25C4332F for ; Wed, 24 Nov 2021 08:42:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241479AbhKXIp4 (ORCPT ); Wed, 24 Nov 2021 03:45:56 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:43811 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241506AbhKXIoj (ORCPT ); Wed, 24 Nov 2021 03:44:39 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1637743289; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VouSXcSjiyGYNn3FCu9sQIbouxSYrC5qt0JuJCkXXDo=; b=G7QK1EE+MM5gsltQZSYTxew7jy+43Vq0bKWebgnH+v0kV0O0P8hRaVT4k9sz1l9rG5TkIB h8/p2eeiXqtYe/PDXIpU038DZRtH+GwUdpR5JMTT+gAOY1IJkY5kcYo6LYbyO8aguYkeav OgEqrLdrvwngFgb8lM7VV+xHJo/xTTY= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-603-eKg1sA97PkGghIIzJKWt2Q-1; Wed, 24 Nov 2021 03:41:28 -0500 X-MC-Unique: eKg1sA97PkGghIIzJKWt2Q-1 Received: by mail-wr1-f72.google.com with SMTP id u4-20020a5d4684000000b0017c8c1de97dso288664wrq.16 for ; Wed, 24 Nov 2021 00:41:28 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=VouSXcSjiyGYNn3FCu9sQIbouxSYrC5qt0JuJCkXXDo=; b=4iPv8Isk7ZKpltVEwWmYGw1tncPglwtVt3vCQbvsUmLxYCeipAkFe2kLV56gt33mQZ HGiPI/jqa0uZ8h4W/EcrlmOFKX386SrGg3j35U9LXB73vrFDsfD/2al1w+LyEtJa6uNL xJ8gRHYtQ0+F1HXgqLp4K/BRZY2sBV3GeG66qzSZkCH7CRatRRjsRe6UOQhLd/A1o4Bg vxtCeHRf5eHnIM68hlNZEWuES/TQ/69A8Qjtgoeecd8qwFoPdoYlV+LR0LA0jt+eFhOZ p81uzAnMR1wnhUGR5QqcZQUT0VyLXLl3vsldzvQaO8Z7hCoMMK8F6PbiiZYEJhySNAh9 BAMg== X-Gm-Message-State: AOAM533D6T5j2r7vwF3MiwhpGoMN3d/Nos6AHDmR64YEFrRaxm9QK4AA nIqVLBN9dbDE0VHHM5JsUeuh7H/3uGuBqzMt8+AyvCH97nanG8mRzG/mAQnoxvwNBHQYm6OH0AE t/GMjDqZELRovsyVo X-Received: by 2002:a05:600c:1ca0:: with SMTP id k32mr12939330wms.74.1637743286925; Wed, 24 Nov 2021 00:41:26 -0800 (PST) X-Google-Smtp-Source: ABdhPJzHrRPatgHKWjJef4sF+8GTkchQ05vfLoS9QW9gWF0BXYJdsxh+4676H3EyepKA6yptDaAT1Q== X-Received: by 2002:a05:600c:1ca0:: with SMTP id k32mr12939289wms.74.1637743286687; Wed, 24 Nov 2021 00:41:26 -0800 (PST) Received: from krava.redhat.com (nat-pool-brq-u.redhat.com. [213.175.37.12]) by smtp.gmail.com with ESMTPSA id o12sm20473649wrc.85.2021.11.24.00.41.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 00:41:26 -0800 (PST) From: Jiri Olsa X-Google-Original-From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Arnaldo Carvalho de Melo , Peter Zijlstra , Masami Hiramatsu , Steven Rostedt Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, lkml , Ingo Molnar , Mark Rutland , Martin KaFai Lau , Alexander Shishkin , Song Liu , Yonghong Song , John Fastabend , KP Singh , Ravi Bangoria Subject: [PATCH 1/8] perf/kprobe: Add support to create multiple probes Date: Wed, 24 Nov 2021 09:41:12 +0100 Message-Id: <20211124084119.260239-2-jolsa@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124084119.260239-1-jolsa@kernel.org> References: <20211124084119.260239-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Adding support to create multiple probes within single perf event. This way we can associate single bpf program with multiple kprobes, because bpf program gets associated with the perf event. The perf_event_attr is not extended, current fields for kprobe attachment are used for multi attachment. For current kprobe atachment we use either: kprobe_func (in config1) + probe_offset (in config2) to define kprobe by function name with offset, or: kprobe_addr (in config2) to define kprobe with direct address value. For multi probe attach the same fields point to array of values with the same semantic. Each probe is defined as set of values with the same array index (idx) as: kprobe_func[idx] + probe_offset[idx] to define kprobe by function name with offset, or: kprobe_addr[idx] to define kprobe with direct address value. The number of probes is passed in probe_cnt value, which shares the union with wakeup_events/wakeup_watermark values which are not used for kprobes. Since [1] it's possible to stack multiple probes events under one head event. Using the same code to allow that for probes defined under perf kprobe interface. [1] https://lore.kernel.org/lkml/156095682948.28024.14190188071338900568.stgit@devnote2/ Signed-off-by: Jiri Olsa --- include/uapi/linux/perf_event.h | 1 + kernel/trace/trace_event_perf.c | 106 ++++++++++++++++++++++++++++---- kernel/trace/trace_kprobe.c | 47 ++++++++++++-- kernel/trace/trace_probe.c | 2 +- kernel/trace/trace_probe.h | 3 +- 5 files changed, 138 insertions(+), 21 deletions(-) diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index bd8860eeb291..eea80709d1ed 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -414,6 +414,7 @@ struct perf_event_attr { union { __u32 wakeup_events; /* wakeup every n events */ __u32 wakeup_watermark; /* bytes before wakeup */ + __u32 probe_cnt; /* number of [k,u] probes */ }; __u32 bp_type; diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index a114549720d6..26078e40c299 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -245,23 +245,27 @@ void perf_trace_destroy(struct perf_event *p_event) } #ifdef CONFIG_KPROBE_EVENTS -int perf_kprobe_init(struct perf_event *p_event, bool is_retprobe) +static struct trace_event_call* +kprobe_init(bool is_retprobe, u64 kprobe_func, u64 kprobe_addr, + u64 probe_offset, struct trace_event_call *old) { int ret; char *func = NULL; struct trace_event_call *tp_event; - if (p_event->attr.kprobe_func) { + if (kprobe_func) { func = kzalloc(KSYM_NAME_LEN, GFP_KERNEL); if (!func) - return -ENOMEM; + return ERR_PTR(-ENOMEM); ret = strncpy_from_user( - func, u64_to_user_ptr(p_event->attr.kprobe_func), + func, u64_to_user_ptr(kprobe_func), KSYM_NAME_LEN); if (ret == KSYM_NAME_LEN) ret = -E2BIG; - if (ret < 0) - goto out; + if (ret < 0) { + kfree(func); + return ERR_PTR(ret); + } if (func[0] == '\0') { kfree(func); @@ -270,20 +274,96 @@ int perf_kprobe_init(struct perf_event *p_event, bool is_retprobe) } tp_event = create_local_trace_kprobe( - func, (void *)(unsigned long)(p_event->attr.kprobe_addr), - p_event->attr.probe_offset, is_retprobe); - if (IS_ERR(tp_event)) { - ret = PTR_ERR(tp_event); - goto out; + func, (void *)(unsigned long)(kprobe_addr), + probe_offset, is_retprobe, old); + kfree(func); + return tp_event; +} + +static struct trace_event_call* +kprobe_init_multi(struct perf_event *p_event, bool is_retprobe) +{ + void __user *kprobe_func = u64_to_user_ptr(p_event->attr.kprobe_func); + void __user *kprobe_addr = u64_to_user_ptr(p_event->attr.kprobe_addr); + u64 *funcs = NULL, *addrs = NULL, *offs = NULL; + struct trace_event_call *tp_event, *tp_old = NULL; + u32 i, cnt = p_event->attr.probe_cnt; + int ret = -EINVAL; + size_t size; + + if (!cnt) + return ERR_PTR(-EINVAL); + + size = cnt * sizeof(u64); + if (kprobe_func) { + ret = -ENOMEM; + funcs = kmalloc(size, GFP_KERNEL); + if (!funcs) + goto out; + ret = -EFAULT; + if (copy_from_user(funcs, kprobe_func, size)) + goto out; + } + + if (kprobe_addr) { + ret = -ENOMEM; + addrs = kmalloc(size, GFP_KERNEL); + if (!addrs) + goto out; + ret = -EFAULT; + if (copy_from_user(addrs, kprobe_addr, size)) + goto out; + /* addresses and ofsets share the same array */ + offs = addrs; } + for (i = 0; i < cnt; i++) { + tp_event = kprobe_init(is_retprobe, funcs ? funcs[i] : 0, + addrs ? addrs[i] : 0, offs ? offs[i] : 0, + tp_old); + if (IS_ERR(tp_event)) { + if (tp_old) + destroy_local_trace_kprobe(tp_old); + ret = PTR_ERR(tp_event); + goto out; + } + if (!tp_old) + tp_old = tp_event; + } + ret = 0; +out: + kfree(funcs); + kfree(addrs); + return ret ? ERR_PTR(ret) : tp_old; +} + +static struct trace_event_call* +kprobe_init_single(struct perf_event *p_event, bool is_retprobe) +{ + struct perf_event_attr *attr = &p_event->attr; + + return kprobe_init(is_retprobe, attr->kprobe_func, attr->kprobe_addr, + attr->probe_offset, NULL); +} + +int perf_kprobe_init(struct perf_event *p_event, bool is_retprobe) +{ + struct trace_event_call *tp_event; + int ret; + + if (p_event->attr.probe_cnt) + tp_event = kprobe_init_multi(p_event, is_retprobe); + else + tp_event = kprobe_init_single(p_event, is_retprobe); + + if (IS_ERR(tp_event)) + return PTR_ERR(tp_event); + mutex_lock(&event_mutex); ret = perf_trace_event_init(tp_event, p_event); if (ret) destroy_local_trace_kprobe(tp_event); mutex_unlock(&event_mutex); -out: - kfree(func); return ret; } diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 33272a7b6912..86a7aada853a 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -237,13 +237,18 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs); static int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs); +static void __free_trace_kprobe(struct trace_kprobe *tk) +{ + kfree(tk->symbol); + free_percpu(tk->nhit); + kfree(tk); +} + static void free_trace_kprobe(struct trace_kprobe *tk) { if (tk) { trace_probe_cleanup(&tk->tp); - kfree(tk->symbol); - free_percpu(tk->nhit); - kfree(tk); + __free_trace_kprobe(tk); } } @@ -1796,7 +1801,7 @@ static int unregister_kprobe_event(struct trace_kprobe *tk) /* create a trace_kprobe, but don't add it to global lists */ struct trace_event_call * create_local_trace_kprobe(char *func, void *addr, unsigned long offs, - bool is_return) + bool is_return, struct trace_event_call *old) { enum probe_print_type ptype; struct trace_kprobe *tk; @@ -1820,6 +1825,28 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs, return ERR_CAST(tk); } + if (old) { + struct trace_kprobe *tk_old; + + tk_old = trace_kprobe_primary_from_call(old); + if (!tk_old) { + ret = -EINVAL; + goto error; + } + + /* Append to existing event */ + ret = trace_probe_append(&tk->tp, &tk_old->tp); + if (ret) + goto error; + + /* Register k*probe */ + ret = __register_trace_kprobe(tk); + if (ret) + goto error; + + return trace_probe_event_call(&tk->tp); + } + init_trace_event_call(tk); ptype = trace_kprobe_is_return(tk) ? @@ -1841,6 +1868,8 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs, void destroy_local_trace_kprobe(struct trace_event_call *event_call) { + struct trace_probe_event *event; + struct trace_probe *pos, *tmp; struct trace_kprobe *tk; tk = trace_kprobe_primary_from_call(event_call); @@ -1852,9 +1881,15 @@ void destroy_local_trace_kprobe(struct trace_event_call *event_call) return; } - __unregister_trace_kprobe(tk); + event = tk->tp.event; + list_for_each_entry_safe(pos, tmp, &event->probes, list) { + tk = container_of(pos, struct trace_kprobe, tp); + list_del_init(&pos->list); + __unregister_trace_kprobe(tk); + __free_trace_kprobe(tk); + } - free_trace_kprobe(tk); + trace_probe_event_free(event); } #endif /* CONFIG_PERF_EVENTS */ diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 3ed2a3f37297..2dff85aa21e9 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -974,7 +974,7 @@ int traceprobe_define_arg_fields(struct trace_event_call *event_call, return 0; } -static void trace_probe_event_free(struct trace_probe_event *tpe) +void trace_probe_event_free(struct trace_probe_event *tpe) { kfree(tpe->class.system); kfree(tpe->call.name); diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index 99e7a5df025e..ba8e46c7efe8 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -333,6 +333,7 @@ int trace_probe_init(struct trace_probe *tp, const char *event, const char *group, bool alloc_filter); void trace_probe_cleanup(struct trace_probe *tp); int trace_probe_append(struct trace_probe *tp, struct trace_probe *to); +void trace_probe_event_free(struct trace_probe_event *tpe); void trace_probe_unlink(struct trace_probe *tp); int trace_probe_register_event_call(struct trace_probe *tp); int trace_probe_add_file(struct trace_probe *tp, struct trace_event_file *file); @@ -377,7 +378,7 @@ extern int traceprobe_set_print_fmt(struct trace_probe *tp, enum probe_print_typ #ifdef CONFIG_PERF_EVENTS extern struct trace_event_call * create_local_trace_kprobe(char *func, void *addr, unsigned long offs, - bool is_return); + bool is_return, struct trace_event_call *old); extern void destroy_local_trace_kprobe(struct trace_event_call *event_call); extern struct trace_event_call * From patchwork Wed Nov 24 08:41:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 12636369 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 47053C433EF for ; Wed, 24 Nov 2021 08:42:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241513AbhKXIqF (ORCPT ); Wed, 24 Nov 2021 03:46:05 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:27817 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241518AbhKXIoq (ORCPT ); Wed, 24 Nov 2021 03:44:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1637743296; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TEGty5S/MnI3NiIWNNHzLjNLkbyjP+A5VllGm4cA+aw=; b=M3Ip/qr4fU1qDP5i2jOxl8DKQmS9wNwNHSU1YaMpu6yohyYSiSSR0RbS0KF+CXgwrLty86 kH2iAQiBNrb/N5gLJdjBBT5fbBqeRPQk7FQAlkno8PfLb36h7eG76KmKtJmKDE3NwFmQ5M 9dOZxhGZGV91y0GwwoAZ5YJ0gsnKAeM= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-311-VTEK9yhLOLuDjCZFLXRIaA-1; Wed, 24 Nov 2021 03:41:35 -0500 X-MC-Unique: VTEK9yhLOLuDjCZFLXRIaA-1 Received: by mail-wm1-f69.google.com with SMTP id 187-20020a1c02c4000000b003335872db8dso973028wmc.2 for ; Wed, 24 Nov 2021 00:41:35 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=TEGty5S/MnI3NiIWNNHzLjNLkbyjP+A5VllGm4cA+aw=; b=l4y2j6Jnxgl5hE63p5erg3apB1+lUufVqX11Dnb9a13sGyN1LwAYyjTvefvxNfFtdl KpmDaZtgX5JSFfxGiTjtQdFgWFsFZZu2cFuqgghpuFCDorMDfoytbw3uWuYRo3XVVk41 SyU7Lfm998aw6zl1X8v5ZVUER7d5pwQR5D4idzvkB7mMVT92b5pg+C72M1L7fYHKW7DI ZWgi+X36TomKTMS+BB5V6iZ2ygFw7/r9z3n3an/r70yhx9UbOoPkQPGDOWOIa7bdZ3zT cGFb8vyWDBJ8fXWH4ab5WR/3umE0sNRzZl2Jh/W1VGSqObTbtOrDi+LW0mdR0pvC913/ wbtQ== X-Gm-Message-State: AOAM532TrGQXi9u+02SDjTboUy5otYaeLtYTWaYWRsb1BMcEtRh1PzIu brRak1K76KkzzH7+vZXUExN52Lhy92XC7ERSWsolgcrtC6Sf5EvsXTHyEkF7gqJ8itkqLE8NmkK xQS2Fm5YqRDemi/8Q X-Received: by 2002:a5d:4ecd:: with SMTP id s13mr17159656wrv.400.1637743293202; Wed, 24 Nov 2021 00:41:33 -0800 (PST) X-Google-Smtp-Source: ABdhPJwI7+MCbH/0LRtHQRj1Ak5dKI/T/EbW7gnhXeM+Qj2gSXz4xXENHoxa80KTXP2iFAtxZHClfQ== X-Received: by 2002:a5d:4ecd:: with SMTP id s13mr17159619wrv.400.1637743292936; Wed, 24 Nov 2021 00:41:32 -0800 (PST) Received: from krava.redhat.com (nat-pool-brq-u.redhat.com. [213.175.37.12]) by smtp.gmail.com with ESMTPSA id c6sm5096710wmq.46.2021.11.24.00.41.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 00:41:32 -0800 (PST) From: Jiri Olsa X-Google-Original-From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Arnaldo Carvalho de Melo , Peter Zijlstra , Masami Hiramatsu , Steven Rostedt Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, lkml , Ingo Molnar , Mark Rutland , Martin KaFai Lau , Alexander Shishkin , Song Liu , Yonghong Song , John Fastabend , KP Singh , Ravi Bangoria Subject: [PATCH 2/8] perf/uprobe: Add support to create multiple probes Date: Wed, 24 Nov 2021 09:41:13 +0100 Message-Id: <20211124084119.260239-3-jolsa@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124084119.260239-1-jolsa@kernel.org> References: <20211124084119.260239-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Adding support to create multiple probes within single perf event. This way we can associate single bpf program with multiple uprobes, because bpf program gets associated with the perf event. The perf_event_attr is not extended, current fields for uprobe attachment are used for multi attachment. For current uprobe atachment we use: uprobe_path (in config1) + probe_offset (in config2) to define kprobe by executable path with offset. For multi probe attach the same fields point to array of values with the same semantic. Each probe is defined as set of values with the same array index (idx) as: uprobe_path[idx] (in config1) + probe_offset[idx] (in config2) to define uprobe executable path with offset. The number of probes is passed in probe_cnt value, which shares the union with wakeup_events/wakeup_watermark values which are not used for uprobes. Since [1] it's possible to stack multiple probes events under one head event. Using the same code to allow that for probes defined under perf uprobe interface. [1] https://lore.kernel.org/lkml/156095682948.28024.14190188071338900568.stgit@devnote2/ Signed-off-by: Jiri Olsa --- kernel/trace/trace_event_perf.c | 108 +++++++++++++++++++++++++++----- kernel/trace/trace_probe.h | 3 +- kernel/trace/trace_uprobe.c | 43 +++++++++++-- 3 files changed, 133 insertions(+), 21 deletions(-) diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 26078e40c299..fb5db6a43d37 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -379,34 +379,114 @@ void perf_kprobe_destroy(struct perf_event *p_event) #endif /* CONFIG_KPROBE_EVENTS */ #ifdef CONFIG_UPROBE_EVENTS -int perf_uprobe_init(struct perf_event *p_event, - unsigned long ref_ctr_offset, bool is_retprobe) +static struct trace_event_call* +uprobe_init(u64 uprobe_path, u64 probe_offset, unsigned long ref_ctr_offset, + bool is_retprobe, struct trace_event_call *old) { int ret; char *path = NULL; struct trace_event_call *tp_event; - if (!p_event->attr.uprobe_path) - return -EINVAL; + if (!uprobe_path) + return ERR_PTR(-EINVAL); - path = strndup_user(u64_to_user_ptr(p_event->attr.uprobe_path), + path = strndup_user(u64_to_user_ptr(uprobe_path), PATH_MAX); if (IS_ERR(path)) { ret = PTR_ERR(path); - return (ret == -EINVAL) ? -E2BIG : ret; + return ERR_PTR((ret == -EINVAL) ? -E2BIG : ret); } if (path[0] == '\0') { - ret = -EINVAL; - goto out; + kfree(path); + return ERR_PTR(-EINVAL); } - tp_event = create_local_trace_uprobe(path, p_event->attr.probe_offset, - ref_ctr_offset, is_retprobe); - if (IS_ERR(tp_event)) { - ret = PTR_ERR(tp_event); - goto out; + tp_event = create_local_trace_uprobe(path, probe_offset, + ref_ctr_offset, is_retprobe, old); + kfree(path); + return tp_event; +} + +static struct trace_event_call* +uprobe_init_multi(struct perf_event *p_event, unsigned long ref_ctr_offset, + bool is_retprobe) +{ + void __user *probe_offset = u64_to_user_ptr(p_event->attr.probe_offset); + void __user *uprobe_path = u64_to_user_ptr(p_event->attr.uprobe_path); + struct trace_event_call *tp_event, *tp_old = NULL; + u32 i, cnt = p_event->attr.probe_cnt; + u64 *paths = NULL, *offs = NULL; + int ret = -EINVAL; + size_t size; + + if (!cnt) + return ERR_PTR(-EINVAL); + + size = cnt * sizeof(u64); + if (uprobe_path) { + ret = -ENOMEM; + paths = kmalloc(size, GFP_KERNEL); + if (!paths) + goto out; + ret = -EFAULT; + if (copy_from_user(paths, uprobe_path, size)) + goto out; } + if (probe_offset) { + ret = -ENOMEM; + offs = kmalloc(size, GFP_KERNEL); + if (!offs) + goto out; + ret = -EFAULT; + if (copy_from_user(offs, probe_offset, size)) + goto out; + } + + for (i = 0; i < cnt; i++) { + tp_event = uprobe_init(paths ? paths[i] : 0, offs ? offs[i] : 0, + ref_ctr_offset, is_retprobe, tp_old); + if (IS_ERR(tp_event)) { + if (tp_old) + destroy_local_trace_uprobe(tp_old); + ret = PTR_ERR(tp_event); + goto out; + } + if (!tp_old) + tp_old = tp_event; + } + ret = 0; + +out: + kfree(paths); + kfree(offs); + return ret ? ERR_PTR(ret) : tp_old; +} + +static struct trace_event_call* +uprobe_init_single(struct perf_event *p_event, unsigned long ref_ctr_offset, + bool is_retprobe) +{ + struct perf_event_attr *attr = &p_event->attr; + + return uprobe_init(attr->uprobe_path, attr->probe_offset, + ref_ctr_offset, is_retprobe, NULL); +} + +int perf_uprobe_init(struct perf_event *p_event, + unsigned long ref_ctr_offset, bool is_retprobe) +{ + struct trace_event_call *tp_event; + int ret; + + if (p_event->attr.probe_cnt) + tp_event = uprobe_init_multi(p_event, ref_ctr_offset, is_retprobe); + else + tp_event = uprobe_init_single(p_event, ref_ctr_offset, is_retprobe); + + if (IS_ERR(tp_event)) + return PTR_ERR(tp_event); + /* * local trace_uprobe need to hold event_mutex to call * uprobe_buffer_enable() and uprobe_buffer_disable(). @@ -417,8 +497,6 @@ int perf_uprobe_init(struct perf_event *p_event, if (ret) destroy_local_trace_uprobe(tp_event); mutex_unlock(&event_mutex); -out: - kfree(path); return ret; } diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h index ba8e46c7efe8..6c81926874ff 100644 --- a/kernel/trace/trace_probe.h +++ b/kernel/trace/trace_probe.h @@ -383,7 +383,8 @@ extern void destroy_local_trace_kprobe(struct trace_event_call *event_call); extern struct trace_event_call * create_local_trace_uprobe(char *name, unsigned long offs, - unsigned long ref_ctr_offset, bool is_return); + unsigned long ref_ctr_offset, bool is_return, + struct trace_event_call *old); extern void destroy_local_trace_uprobe(struct trace_event_call *event_call); #endif extern int traceprobe_define_arg_fields(struct trace_event_call *event_call, diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index f5f0039d31e5..ca76f9ab6811 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -358,15 +358,20 @@ alloc_trace_uprobe(const char *group, const char *event, int nargs, bool is_ret) return ERR_PTR(ret); } +static void __free_trace_uprobe(struct trace_uprobe *tu) +{ + path_put(&tu->path); + kfree(tu->filename); + kfree(tu); +} + static void free_trace_uprobe(struct trace_uprobe *tu) { if (!tu) return; - path_put(&tu->path); trace_probe_cleanup(&tu->tp); - kfree(tu->filename); - kfree(tu); + __free_trace_uprobe(tu); } static struct trace_uprobe *find_probe_event(const char *event, const char *group) @@ -1584,7 +1589,8 @@ static int unregister_uprobe_event(struct trace_uprobe *tu) #ifdef CONFIG_PERF_EVENTS struct trace_event_call * create_local_trace_uprobe(char *name, unsigned long offs, - unsigned long ref_ctr_offset, bool is_return) + unsigned long ref_ctr_offset, bool is_return, + struct trace_event_call *old) { enum probe_print_type ptype; struct trace_uprobe *tu; @@ -1619,6 +1625,24 @@ create_local_trace_uprobe(char *name, unsigned long offs, tu->path = path; tu->ref_ctr_offset = ref_ctr_offset; tu->filename = kstrdup(name, GFP_KERNEL); + + if (old) { + struct trace_uprobe *tu_old; + + tu_old = trace_uprobe_primary_from_call(old); + if (!tu_old) { + ret = -EINVAL; + goto error; + } + + /* Append to existing event */ + ret = trace_probe_append(&tu->tp, &tu_old->tp); + if (ret) + goto error; + + return trace_probe_event_call(&tu->tp); + } + init_trace_event_call(tu); ptype = is_ret_probe(tu) ? PROBE_PRINT_RETURN : PROBE_PRINT_NORMAL; @@ -1635,11 +1659,20 @@ create_local_trace_uprobe(char *name, unsigned long offs, void destroy_local_trace_uprobe(struct trace_event_call *event_call) { + struct trace_probe_event *event; + struct trace_probe *pos, *tmp; struct trace_uprobe *tu; tu = trace_uprobe_primary_from_call(event_call); - free_trace_uprobe(tu); + event = tu->tp.event; + list_for_each_entry_safe(pos, tmp, &event->probes, list) { + tu = container_of(pos, struct trace_uprobe, tp); + list_del_init(&pos->list); + __free_trace_uprobe(tu); + } + + trace_probe_event_free(event); } #endif /* CONFIG_PERF_EVENTS */ From patchwork Wed Nov 24 08:41:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 12636371 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8A9B1C433FE for ; Wed, 24 Nov 2021 08:43:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241533AbhKXIqJ (ORCPT ); Wed, 24 Nov 2021 03:46:09 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:23628 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241542AbhKXIov (ORCPT ); Wed, 24 Nov 2021 03:44:51 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1637743302; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VUpNCIf6I4xx/xoebeS2tiWidAHCtrV6dZkFUmxD4cc=; b=FgoVu18gtjma/DGnyax3NdOfNuUcsnEIs3pT65b9wgdTNw5I1QIW8uZesEQtCb8MFUEg3r xR+iWGT7iZEbcwqQuqXq8UsepfcVcSSTolbs5mRVNyGYpBLVJ+KZ40G0ELE2o1pFTJWfQJ foCezp3zf4yzFTe4PwF5KDNmicv7B9E= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-326-w1Z5Lz-lMkiQGiMGHlifEg-1; Wed, 24 Nov 2021 03:41:40 -0500 X-MC-Unique: w1Z5Lz-lMkiQGiMGHlifEg-1 Received: by mail-wm1-f69.google.com with SMTP id p12-20020a05600c1d8c00b0033a22e48203so1017736wms.6 for ; Wed, 24 Nov 2021 00:41:40 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=VUpNCIf6I4xx/xoebeS2tiWidAHCtrV6dZkFUmxD4cc=; b=yYCh59fcp58jF0ewpjrRM/LxlzLbbuEvsh1u4KVoUmeUR/mybAUogqPUmUnDhHe+RR OymLrAm5achPB9uWOchWvso3U/o5fsyIqDEpy7biSUnFYoUIcP0gSzZTnL9K6uEURosj kR7LOJdeQuUwaVy8fh/ykpmwkeqwTQWdgchL/HJjb7aV2OtjnqfEHU5sJZIyAxRdAl0L WduqPOG3Q61HnhcSVWZZeBPl1EbnPCtiPUik+QkZu8nPr3vZxvk0SsfY48gcTQ+FRxOM XKh0KiiqYDUS2EIKbi1otPkC4AWUyZ9xRJOG1NCOp8/1pUuCUyf16NJ6IUQCIyFxJmmW OupQ== X-Gm-Message-State: AOAM533yJ4ZW7RPHCRE815WukcXmVsrmdUAk9lJIUSIASGFg8ROLNPgb C9GlT3BaHXmPg2OeNitqMnSG7FXCeD4dDSPJYT/oBSCDP+aFeVQMi36K8hJrH4z0/FtPzxRUxA8 czBeTCRCbzbVwfI1t X-Received: by 2002:a5d:548f:: with SMTP id h15mr16213863wrv.99.1637743299421; Wed, 24 Nov 2021 00:41:39 -0800 (PST) X-Google-Smtp-Source: ABdhPJyz1415SFxfiE43cMAnbGJQqe7kyuGSNL3YexfDBsTFRpB49fmucVAQmngtlVjsFf5uIYlC/A== X-Received: by 2002:a5d:548f:: with SMTP id h15mr16213828wrv.99.1637743299253; Wed, 24 Nov 2021 00:41:39 -0800 (PST) Received: from krava.redhat.com (nat-pool-brq-u.redhat.com. [213.175.37.12]) by smtp.gmail.com with ESMTPSA id x4sm3649097wmi.3.2021.11.24.00.41.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 00:41:38 -0800 (PST) From: Jiri Olsa X-Google-Original-From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Arnaldo Carvalho de Melo , Peter Zijlstra , Masami Hiramatsu , Steven Rostedt Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, lkml , Ingo Molnar , Mark Rutland , Martin KaFai Lau , Alexander Shishkin , Song Liu , Yonghong Song , John Fastabend , KP Singh , Ravi Bangoria Subject: [PATCH 3/8] libbpf: Add libbpf__kallsyms_parse function Date: Wed, 24 Nov 2021 09:41:14 +0100 Message-Id: <20211124084119.260239-4-jolsa@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124084119.260239-1-jolsa@kernel.org> References: <20211124084119.260239-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Move the kallsyms parsing in internal libbpf__kallsyms_parse function, so it can be used from other places. It will be used in following changes. Signed-off-by: Jiri Olsa --- tools/lib/bpf/libbpf.c | 62 ++++++++++++++++++++------------- tools/lib/bpf/libbpf_internal.h | 5 +++ 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index af405c38aadc..b55c0fbfcc03 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -6950,12 +6950,10 @@ static int bpf_object__sanitize_maps(struct bpf_object *obj) return 0; } -static int bpf_object__read_kallsyms_file(struct bpf_object *obj) +int libbpf__kallsyms_parse(void *arg, kallsyms_cb_t cb) { char sym_type, sym_name[500]; unsigned long long sym_addr; - const struct btf_type *t; - struct extern_desc *ext; int ret, err = 0; FILE *f; @@ -6974,35 +6972,51 @@ static int bpf_object__read_kallsyms_file(struct bpf_object *obj) if (ret != 3) { pr_warn("failed to read kallsyms entry: %d\n", ret); err = -EINVAL; - goto out; + break; } - ext = find_extern_by_name(obj, sym_name); - if (!ext || ext->type != EXT_KSYM) - continue; - - t = btf__type_by_id(obj->btf, ext->btf_id); - if (!btf_is_var(t)) - continue; - - if (ext->is_set && ext->ksym.addr != sym_addr) { - pr_warn("extern (ksym) '%s' resolution is ambiguous: 0x%llx or 0x%llx\n", - sym_name, ext->ksym.addr, sym_addr); - err = -EINVAL; - goto out; - } - if (!ext->is_set) { - ext->is_set = true; - ext->ksym.addr = sym_addr; - pr_debug("extern (ksym) %s=0x%llx\n", sym_name, sym_addr); - } + err = cb(arg, sym_addr, sym_type, sym_name); + if (err) + break; } -out: fclose(f); return err; } +static int kallsyms_cb(void *arg, unsigned long long sym_addr, + char sym_type, const char *sym_name) +{ + struct bpf_object *obj = arg; + const struct btf_type *t; + struct extern_desc *ext; + + ext = find_extern_by_name(obj, sym_name); + if (!ext || ext->type != EXT_KSYM) + return 0; + + t = btf__type_by_id(obj->btf, ext->btf_id); + if (!btf_is_var(t)) + return 0; + + if (ext->is_set && ext->ksym.addr != sym_addr) { + pr_warn("extern (ksym) '%s' resolution is ambiguous: 0x%llx or 0x%llx\n", + sym_name, ext->ksym.addr, sym_addr); + return -EINVAL; + } + if (!ext->is_set) { + ext->is_set = true; + ext->ksym.addr = sym_addr; + pr_debug("extern (ksym) %s=0x%llx\n", sym_name, sym_addr); + } + return 0; +} + +static int bpf_object__read_kallsyms_file(struct bpf_object *obj) +{ + return libbpf__kallsyms_parse(obj, kallsyms_cb); +} + static int find_ksym_btf_id(struct bpf_object *obj, const char *ksym_name, __u16 kind, struct btf **res_btf, struct module_btf **res_mod_btf) diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h index f7ac349650a1..511cb09f593f 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -406,6 +406,11 @@ __s32 btf__find_by_name_kind_own(const struct btf *btf, const char *type_name, extern enum libbpf_strict_mode libbpf_mode; +typedef int (*kallsyms_cb_t)(void *arg, unsigned long long sym_addr, + char sym_type, const char *sym_name); + +int libbpf__kallsyms_parse(void *arg, kallsyms_cb_t cb); + /* handle direct returned errors */ static inline int libbpf_err(int ret) { From patchwork Wed Nov 24 08:41:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 12636373 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 884A8C4332F for ; Wed, 24 Nov 2021 08:43:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241457AbhKXIqX (ORCPT ); Wed, 24 Nov 2021 03:46:23 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:23384 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241441AbhKXIo5 (ORCPT ); Wed, 24 Nov 2021 03:44:57 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1637743308; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mSbLxSzQQlSj2l2ivmebco5pJQPSDB4IoLoCnSyzCyI=; b=hLVoGQIB5w3VUlfaejALPn+wH/si+iB1nWfZ1GeHvt9WCGVjsHZUFgn/BGRORDh2lkmpeE 7GBZcnz0379PYy3QoRPwsqy/FTQWZ7wnrO3L8dazcupwcz9jG2X0vIkKBiiDZ13RjtzuYy 3yR5Rb4Jd9OFM4UY67JQe4N/qyG97aE= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-187-Z0_n0WptPU6eAszXS-jPYw-1; Wed, 24 Nov 2021 03:41:47 -0500 X-MC-Unique: Z0_n0WptPU6eAszXS-jPYw-1 Received: by mail-wm1-f70.google.com with SMTP id ay34-20020a05600c1e2200b00337fd217772so1024910wmb.4 for ; Wed, 24 Nov 2021 00:41:46 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mSbLxSzQQlSj2l2ivmebco5pJQPSDB4IoLoCnSyzCyI=; b=W2eOP5UpnI9MhAjKUYPFf5uKBCgm4Khbaw2ybpi009NY3bcOf/h2BypilX6GtVvAT9 g9zLFGGFpcoDwR4n96E64pCenK8vUfvdQgFTEDPxaV2ZzDY0vD/RnilRnSkeHeLKLl7S lM2mBJM8fhk9YnwNlkm6PqVkh81b73EOIpH3ff1QsIQz1FiJyXbsdpgkhuLaxGFG5PYU JSeRRtKdBnnxw+tTOMJ07mcqmMVzHCO2yIuo2t1jOV3NoGSLtQaKv8ztmKZ94sDwSiUj q8RWgjMGMwL6IOjh3oaGq8d6jWEX5OUB4Vr67nmPXach2EW0z8vXsoK4qpLBBCiKDd31 X6Rg== X-Gm-Message-State: AOAM533idOWXIQ/HGQ0mhmi4vZbgCg+aB0jDFGp63k51lf3ad384Dxrb ZiAwQGdovTmWL2S+0GuWlfGEpH6iKBebcJAODtX4P+905F31qifCcLOykc2TBUQyTr7myhT0BRY zZDiNfWxL7ItlI5Ft X-Received: by 2002:a05:600c:a0b:: with SMTP id z11mr12965526wmp.147.1637743305724; Wed, 24 Nov 2021 00:41:45 -0800 (PST) X-Google-Smtp-Source: ABdhPJymrcuFByLsguSft6KExGLu1wEeNTSixB9Q5EfKs0oZ76e3br1ZPdJy/9cjaU2K/51mela6sg== X-Received: by 2002:a05:600c:a0b:: with SMTP id z11mr12965499wmp.147.1637743305551; Wed, 24 Nov 2021 00:41:45 -0800 (PST) Received: from krava.redhat.com (nat-pool-brq-u.redhat.com. [213.175.37.12]) by smtp.gmail.com with ESMTPSA id d1sm13789041wrz.92.2021.11.24.00.41.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 00:41:45 -0800 (PST) From: Jiri Olsa X-Google-Original-From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Arnaldo Carvalho de Melo , Peter Zijlstra , Masami Hiramatsu , Steven Rostedt Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, lkml , Ingo Molnar , Mark Rutland , Martin KaFai Lau , Alexander Shishkin , Song Liu , Yonghong Song , John Fastabend , KP Singh , Ravi Bangoria Subject: [PATCH 4/8] libbpf: Add struct perf_event_open_args Date: Wed, 24 Nov 2021 09:41:15 +0100 Message-Id: <20211124084119.260239-5-jolsa@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124084119.260239-1-jolsa@kernel.org> References: <20211124084119.260239-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Adding struct perf_event_open_args to hold arguments for perf_event_open_probe, because there's already 6 arguments and more will come in following changes. Signed-off-by: Jiri Olsa --- tools/lib/bpf/libbpf.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index b55c0fbfcc03..34219a0c39a7 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -9625,11 +9625,20 @@ static int determine_uprobe_retprobe_bit(void) #define PERF_UPROBE_REF_CTR_OFFSET_BITS 32 #define PERF_UPROBE_REF_CTR_OFFSET_SHIFT 32 -static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name, - uint64_t offset, int pid, size_t ref_ctr_off) +struct perf_event_open_args { + bool retprobe; + const char *name; + uint64_t offset; + int pid; + size_t ref_ctr_off; +}; + +static int perf_event_open_probe(bool uprobe, struct perf_event_open_args *args) { + size_t ref_ctr_off = args->ref_ctr_off; struct perf_event_attr attr = {}; char errmsg[STRERR_BUFSIZE]; + int pid = args->pid; int type, pfd, err; if (ref_ctr_off >= (1ULL << PERF_UPROBE_REF_CTR_OFFSET_BITS)) @@ -9643,7 +9652,7 @@ static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name, libbpf_strerror_r(type, errmsg, sizeof(errmsg))); return type; } - if (retprobe) { + if (args->retprobe) { int bit = uprobe ? determine_uprobe_retprobe_bit() : determine_kprobe_retprobe_bit(); @@ -9658,8 +9667,8 @@ static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name, attr.size = sizeof(attr); attr.type = type; attr.config |= (__u64)ref_ctr_off << PERF_UPROBE_REF_CTR_OFFSET_SHIFT; - attr.config1 = ptr_to_u64(name); /* kprobe_func or uprobe_path */ - attr.config2 = offset; /* kprobe_addr or probe_offset */ + attr.config1 = ptr_to_u64(args->name); /* kprobe_func or uprobe_path */ + attr.config2 = args->offset; /* kprobe_addr or probe_offset */ /* pid filter is meaningful only for uprobes */ pfd = syscall(__NR_perf_event_open, &attr, @@ -9791,9 +9800,15 @@ bpf_program__attach_kprobe_opts(const struct bpf_program *prog, legacy = determine_kprobe_perf_type() < 0; if (!legacy) { - pfd = perf_event_open_probe(false /* uprobe */, retprobe, - func_name, offset, - -1 /* pid */, 0 /* ref_ctr_off */); + struct perf_event_open_args args = { + .retprobe = retprobe, + .name = func_name, + .offset = offset, + .pid = -1, + .ref_ctr_off = 0, + }; + + pfd = perf_event_open_probe(false /* uprobe */, &args); } else { char probe_name[256]; @@ -9984,8 +9999,15 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid, legacy = determine_uprobe_perf_type() < 0; if (!legacy) { - pfd = perf_event_open_probe(true /* uprobe */, retprobe, binary_path, - func_offset, pid, ref_ctr_off); + struct perf_event_open_args args = { + .retprobe = retprobe, + .name = binary_path, + .offset = func_offset, + .pid = pid, + .ref_ctr_off = ref_ctr_off, + }; + + pfd = perf_event_open_probe(true /* uprobe */, &args); } else { char probe_name[512]; From patchwork Wed Nov 24 08:41:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 12636375 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C649C433EF for ; Wed, 24 Nov 2021 08:43:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241595AbhKXIqZ (ORCPT ); Wed, 24 Nov 2021 03:46:25 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:44948 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241435AbhKXIpH (ORCPT ); Wed, 24 Nov 2021 03:45:07 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1637743317; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=miD27XMNAQX20tQlwxUdiFwuYzd6DEbiAXCQZyLHmF0=; b=YNU0bO0eo8wLFvUiHuoA902StIYQe72UGaI39BIOLiwpYmEZss3b81ElrcnAl5x2y4CkD9 52rhn1VGWj9FYs2UfbXq6knpNXQi0kOCasebmlzyRjSij1OtCcnhGmVYLGntrZKNeQRozv 0JW/+CybzwsH3XiKf10+D0HvKKYVfmY= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-286-B21hozlANPORcVfzQAkenA-1; Wed, 24 Nov 2021 03:41:53 -0500 X-MC-Unique: B21hozlANPORcVfzQAkenA-1 Received: by mail-wr1-f70.google.com with SMTP id h7-20020adfaa87000000b001885269a937so290002wrc.17 for ; Wed, 24 Nov 2021 00:41:53 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=miD27XMNAQX20tQlwxUdiFwuYzd6DEbiAXCQZyLHmF0=; b=jCn9gws2czm/zFWoiL/TihedmY1v2bQN4qbMh1VZzEcN7DVeNQcFAtzXbTd/Eysthn ufIylTZU+LpimIVdFoN64CAU4TR1sKk4+VN4SuXNeVnSk+qjBIlMXvCxHsueqMhDYAa2 SnbeTxSt9IJWSvua+QvikTWJr0SwXH4Vuls9loIV+CCcRaGcwCu9xO0eAp72qF/W/oxJ 231/9s40FHQl8q7K9LA7ErAKWPyx9rUBgzPH6nP3DEItpVAkppIyLS53BZOc5B7ZwYsB pbqKpDkZfcfaFptWSfLUcuMPPG9FXZ755V70H2dFpnCYm0pBwYserj80xExRcAc51dNm tHHQ== X-Gm-Message-State: AOAM533VHodFy+HEx7f9nRsUIq1pcRy6CcsNv4gfAEfFLXekoQ2xujQC J1bXTNANKRzsxErmBsKDpYMotJYWMmwUqLo3V+GOokBH+RjO8+FvgPCn4q6eNazFvOvgcvrM30l vuyQ0jPpEcLWXlBHt X-Received: by 2002:a7b:c119:: with SMTP id w25mr12662426wmi.70.1637743311870; Wed, 24 Nov 2021 00:41:51 -0800 (PST) X-Google-Smtp-Source: ABdhPJys9b9shmlC+yWyQlkAXSnONwW8ns8tn4LbW4PScL3CEQ4SJ7TleKl0TMJaBFZl8dBf5EvPjA== X-Received: by 2002:a7b:c119:: with SMTP id w25mr12662393wmi.70.1637743311648; Wed, 24 Nov 2021 00:41:51 -0800 (PST) Received: from krava.redhat.com (nat-pool-brq-u.redhat.com. [213.175.37.12]) by smtp.gmail.com with ESMTPSA id b6sm3955860wmq.45.2021.11.24.00.41.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 00:41:51 -0800 (PST) From: Jiri Olsa X-Google-Original-From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Arnaldo Carvalho de Melo , Peter Zijlstra , Masami Hiramatsu , Steven Rostedt Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, lkml , Ingo Molnar , Mark Rutland , Martin KaFai Lau , Alexander Shishkin , Song Liu , Yonghong Song , John Fastabend , KP Singh , Ravi Bangoria Subject: [PATCH 5/8] libbpf: Add support to attach multiple [ku]probes Date: Wed, 24 Nov 2021 09:41:16 +0100 Message-Id: <20211124084119.260239-6-jolsa@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124084119.260239-1-jolsa@kernel.org> References: <20211124084119.260239-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Adding support to attach multiple [ku]probes. Extending both bpf_kprobe_opts and bpf_uprobe_opts structs with config values to define multiple probes within single bpf_program__attach_[ku]probe_opts call. For mutiple probes in bpf_program__attach_kprobe_opts function the 'func_name' argument is ignored and probes are defined in bpf_kprobe_opts struct with: struct { /* probes count */ __u32 cnt; /* function names array */ char **funcs; /* address/offset values array */ union { __u64 *addrs; __u64 *offs; }; } multi; For mutiple probes in bpf_program__attach_uprobe_opts function both 'binary_path' and 'func_offset' arguments are ignored and probes are defined in bpf_kprobe_opts struct with: /* multi uprobe values */ struct { /* probes count */ __u32 cnt; /* paths names array */ const char **paths; /* offsets values array */ __u64 *offs; } multi; The multiple probes attachment is enabled when multi.cnt != 0. Signed-off-by: Jiri Olsa --- tools/include/uapi/linux/perf_event.h | 1 + tools/lib/bpf/libbpf.c | 30 +++++++++++++++++++++++++-- tools/lib/bpf/libbpf.h | 25 ++++++++++++++++++++-- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h index bd8860eeb291..eea80709d1ed 100644 --- a/tools/include/uapi/linux/perf_event.h +++ b/tools/include/uapi/linux/perf_event.h @@ -414,6 +414,7 @@ struct perf_event_attr { union { __u32 wakeup_events; /* wakeup every n events */ __u32 wakeup_watermark; /* bytes before wakeup */ + __u32 probe_cnt; /* number of [k,u] probes */ }; __u32 bp_type; diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 34219a0c39a7..b570e93de735 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -9631,6 +9631,11 @@ struct perf_event_open_args { uint64_t offset; int pid; size_t ref_ctr_off; + struct { + __u32 probe_cnt; + __u64 config1; + __u64 config2; + } multi; }; static int perf_event_open_probe(bool uprobe, struct perf_event_open_args *args) @@ -9667,8 +9672,15 @@ static int perf_event_open_probe(bool uprobe, struct perf_event_open_args *args) attr.size = sizeof(attr); attr.type = type; attr.config |= (__u64)ref_ctr_off << PERF_UPROBE_REF_CTR_OFFSET_SHIFT; - attr.config1 = ptr_to_u64(args->name); /* kprobe_func or uprobe_path */ - attr.config2 = args->offset; /* kprobe_addr or probe_offset */ + + if (args->multi.probe_cnt) { + attr.probe_cnt = args->multi.probe_cnt; + attr.config1 = args->multi.config1; + attr.config2 = args->multi.config2; + } else { + attr.config1 = ptr_to_u64(args->name); /* kprobe_func or uprobe_path */ + attr.config2 = args->offset; /* kprobe_addr or probe_offset */ + } /* pid filter is meaningful only for uprobes */ pfd = syscall(__NR_perf_event_open, &attr, @@ -9807,7 +9819,14 @@ bpf_program__attach_kprobe_opts(const struct bpf_program *prog, .pid = -1, .ref_ctr_off = 0, }; + __u32 probe_cnt = OPTS_GET(opts, multi.cnt, false); + if (probe_cnt) { + args.multi.probe_cnt = probe_cnt; + args.multi.config1 = ptr_to_u64(OPTS_GET(opts, multi.funcs, false)); + /* multi.addrs and multi.offs share the same array */ + args.multi.config2 = ptr_to_u64(OPTS_GET(opts, multi.addrs, false)); + } pfd = perf_event_open_probe(false /* uprobe */, &args); } else { char probe_name[256]; @@ -10006,6 +10025,13 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid, .pid = pid, .ref_ctr_off = ref_ctr_off, }; + __u32 probe_cnt = OPTS_GET(opts, multi.cnt, false); + + if (probe_cnt) { + args.multi.probe_cnt = probe_cnt; + args.multi.config1 = ptr_to_u64(OPTS_GET(opts, multi.paths, false)); + args.multi.config2 = ptr_to_u64(OPTS_GET(opts, multi.offs, false)); + } pfd = perf_event_open_probe(true /* uprobe */, &args); } else { diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index d02139fec4ac..ae072882b5dd 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -321,9 +321,21 @@ struct bpf_kprobe_opts { size_t offset; /* kprobe is return probe */ bool retprobe; + /* multi kprobe values */ + struct { + /* probes count */ + __u32 cnt; + /* function names array */ + char **funcs; + /* address/offset values array */ + union { + __u64 *addrs; + __u64 *offs; + }; + } multi; size_t :0; }; -#define bpf_kprobe_opts__last_field retprobe +#define bpf_kprobe_opts__last_field multi.addrs LIBBPF_API struct bpf_link * bpf_program__attach_kprobe(const struct bpf_program *prog, bool retprobe, @@ -344,9 +356,18 @@ struct bpf_uprobe_opts { __u64 bpf_cookie; /* uprobe is return probe, invoked at function return time */ bool retprobe; + /* multi uprobe values */ + struct { + /* probes count */ + __u32 cnt; + /* paths names array */ + const char **paths; + /* offsets values array */ + __u64 *offs; + } multi; size_t :0; }; -#define bpf_uprobe_opts__last_field retprobe +#define bpf_uprobe_opts__last_field multi.offs LIBBPF_API struct bpf_link * bpf_program__attach_uprobe(const struct bpf_program *prog, bool retprobe, From patchwork Wed Nov 24 08:41:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 12636377 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8112DC4332F for ; Wed, 24 Nov 2021 08:43:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231881AbhKXIq1 (ORCPT ); Wed, 24 Nov 2021 03:46:27 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:42687 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241546AbhKXIpK (ORCPT ); Wed, 24 Nov 2021 03:45:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1637743320; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=shseh34EZ8lSWaWuyg5bZ/fi6QGZqSZDZrwtCV/PRmY=; b=Qrb4A4AJaE1RX60AeKZfSbcqmatHDgYE9smOrw0aQtASSAt/SmymQxQ6tj3+lT8cYmyzW4 H+e+LEGXU6jk4mHX2zJsly0TXgDwabvE5hRCYNMIkijyTfqByocPUcLjoLLEzxqrvBmT19 ZaujiDnsplZlk5d9nzthyQITdVMAMMI= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-241-jaNwOYi7N2ulyJMDEHcE2g-1; Wed, 24 Nov 2021 03:41:59 -0500 X-MC-Unique: jaNwOYi7N2ulyJMDEHcE2g-1 Received: by mail-wr1-f70.google.com with SMTP id q17-20020adff791000000b00183e734ba48so290957wrp.8 for ; Wed, 24 Nov 2021 00:41:59 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=shseh34EZ8lSWaWuyg5bZ/fi6QGZqSZDZrwtCV/PRmY=; b=Q0EofmJNxkJ9sLs5RqVCplVY0VpFtHW9pR5E5IMzl2FCwC8WQUgCNmfvu3FZA2HEj9 w4h2lLUAdwfCgRUwrTHPjNgAgaHOZIMNEVfcI8V3eOskafRsL41b4gcK+8FNc3+KHNez DWTOeGb3G9u4H1ov1LpBbPcJL8SG5K1iIxNYqWWEss29ghILvNC52SV9NgC04NgOV8t7 BqTZgHY2CKX9WBjrwkOVI0limN6BXofE9DR+NdVfjZXvi+fOrJPCqLPNS8xplrMStMzE DQvdXQrlCJYYr77Cfc0tg9EM/uagy7zrvvTMXt/HjNngBwU1zGaYxmkDdBHBA9eBMxOQ fhNQ== X-Gm-Message-State: AOAM530nCrV6btSo6mk3R/JCjE4Hu1Me5H3RxqCOXcA70BZCEa6L2nwJ KG6xxp/5vOGCrcrPDBmROitbPjkgZR3BOzSya3F3RjUfOt1ILFy+t0MrxIHkWJHgWLRW1/tkdQF kR0+V4P49mt+jIama X-Received: by 2002:a5d:6691:: with SMTP id l17mr16604539wru.227.1637743318107; Wed, 24 Nov 2021 00:41:58 -0800 (PST) X-Google-Smtp-Source: ABdhPJwOpcUZpBeEIVgbyAADajoY2+vGJmyxlVWkqXGkoDZ+BH/JclGr6tlUHTrebAx650ScyDsOnQ== X-Received: by 2002:a5d:6691:: with SMTP id l17mr16604499wru.227.1637743317902; Wed, 24 Nov 2021 00:41:57 -0800 (PST) Received: from krava.redhat.com (nat-pool-brq-u.redhat.com. [213.175.37.12]) by smtp.gmail.com with ESMTPSA id f7sm4771235wmg.6.2021.11.24.00.41.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 00:41:57 -0800 (PST) From: Jiri Olsa X-Google-Original-From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Arnaldo Carvalho de Melo , Peter Zijlstra , Masami Hiramatsu , Steven Rostedt Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, lkml , Ingo Molnar , Mark Rutland , Martin KaFai Lau , Alexander Shishkin , Song Liu , Yonghong Song , John Fastabend , KP Singh , Ravi Bangoria Subject: [PATCH 6/8] libbpf: Add support for k[ret]probe.multi program section Date: Wed, 24 Nov 2021 09:41:17 +0100 Message-Id: <20211124084119.260239-7-jolsa@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124084119.260239-1-jolsa@kernel.org> References: <20211124084119.260239-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Adding new sections kprobe.multi/kretprobe.multi for multi kprobe programs. It's now possible to define kprobe/kretprobe program like: SEC("kprobe.multi/bpf_fentry_test*") and it will be automatically attached to bpf_fentry_test* functions. Signed-off-by: Jiri Olsa --- tools/lib/bpf/libbpf.c | 105 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index b570e93de735..c1feb5f389a0 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -8348,6 +8348,7 @@ int bpf_program__set_flags(struct bpf_program *prog, __u32 flags) } static struct bpf_link *attach_kprobe(const struct bpf_program *prog, long cookie); +static struct bpf_link *attach_kprobe_multi(const struct bpf_program *prog, long cookie); static struct bpf_link *attach_tp(const struct bpf_program *prog, long cookie); static struct bpf_link *attach_raw_tp(const struct bpf_program *prog, long cookie); static struct bpf_link *attach_trace(const struct bpf_program *prog, long cookie); @@ -8362,6 +8363,8 @@ static const struct bpf_sec_def section_defs[] = { SEC_DEF("uprobe/", KPROBE, 0, SEC_NONE), SEC_DEF("kretprobe/", KPROBE, 0, SEC_NONE, attach_kprobe), SEC_DEF("uretprobe/", KPROBE, 0, SEC_NONE), + SEC_DEF("kprobe.multi/", KPROBE, 0, SEC_NONE, attach_kprobe_multi), + SEC_DEF("kretprobe.multi/", KPROBE, 0, SEC_NONE, attach_kprobe_multi), SEC_DEF("tc", SCHED_CLS, 0, SEC_NONE), SEC_DEF("classifier", SCHED_CLS, 0, SEC_NONE | SEC_SLOPPY_PFX), SEC_DEF("action", SCHED_ACT, 0, SEC_NONE | SEC_SLOPPY_PFX), @@ -9918,6 +9921,108 @@ static struct bpf_link *attach_kprobe(const struct bpf_program *prog, long cooki return link; } +struct kprobe_resolve_multi { + const char *name; + char **funcs; + __u32 alloc; + __u32 cnt; +}; + +static bool glob_matches(const char *glob, const char *s) +{ + int n = strlen(glob); + + if (n == 1 && glob[0] == '*') + return true; + + if (glob[0] == '*' && glob[n - 1] == '*') { + const char *subs; + /* substring match */ + + /* this is hacky, but we don't want to allocate + * for no good reason + */ + ((char *)glob)[n - 1] = '\0'; + subs = strstr(s, glob + 1); + ((char *)glob)[n - 1] = '*'; + + return subs != NULL; + } else if (glob[0] == '*') { + size_t nn = strlen(s); + /* suffix match */ + + /* too short for a given suffix */ + if (nn < n - 1) + return false; + return strcmp(s + nn - (n - 1), glob + 1) == 0; + } else if (glob[n - 1] == '*') { + /* prefix match */ + return strncmp(s, glob, n - 1) == 0; + } else { + /* exact match */ + return strcmp(glob, s) == 0; + } +} + +static int kprobe_resolve_multi_cb(void *arg, unsigned long long sym_addr, + char sym_type, const char *sym_name) +{ + struct kprobe_resolve_multi *res = arg; + char **p, *sym; + + if (!glob_matches(res->name, sym_name)) + return 0; + + if (res->cnt == res->alloc) { + res->alloc = max((__u32) 16, res->alloc * 3 / 2); + p = libbpf_reallocarray(res->funcs, res->alloc, sizeof(__u32)); + if (!p) + return -ENOMEM; + res->funcs = p; + } + sym = strdup(sym_name); + if (!sym) + return -ENOMEM; + res->funcs[res->cnt++] = sym; + return 0; +} + +static void free_str_array(char **func, __u32 cnt) +{ + __u32 i; + + for (i = 0; i < cnt; i++) + free(func[i]); + free(func); +} + +static struct bpf_link *attach_kprobe_multi(const struct bpf_program *prog, long cookie) +{ + DECLARE_LIBBPF_OPTS(bpf_kprobe_opts, opts); + struct kprobe_resolve_multi res = { }; + struct bpf_link *link; + int err; + + opts.retprobe = str_has_pfx(prog->sec_name, "kretprobe.multi/"); + if (opts.retprobe) + res.name = prog->sec_name + sizeof("kretprobe.multi/") - 1; + else + res.name = prog->sec_name + sizeof("kprobe.multi/") - 1; + + err = libbpf__kallsyms_parse(&res, kprobe_resolve_multi_cb); + if (err) { + free_str_array(res.funcs, res.cnt); + return libbpf_err_ptr(err); + } + if (!res.cnt) + return libbpf_err_ptr(-ENOENT); + opts.multi.cnt = res.cnt; + opts.multi.funcs = res.funcs; + link = bpf_program__attach_kprobe_opts(prog, NULL, &opts); + free_str_array(res.funcs, res.cnt); + return link; +} + static void gen_uprobe_legacy_event_name(char *buf, size_t buf_sz, const char *binary_path, uint64_t offset) { From patchwork Wed Nov 24 08:41:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 12636379 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD8A7C433F5 for ; Wed, 24 Nov 2021 08:43:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241611AbhKXIqc (ORCPT ); Wed, 24 Nov 2021 03:46:32 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:22785 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241549AbhKXIpQ (ORCPT ); Wed, 24 Nov 2021 03:45:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1637743327; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XE2SVTrDU43kAFgXUbiTJeyLZudA8SDW3kmGcRKb0Vw=; b=PAj6FqcVSK+qWYru73oNDmpVge3CMaWZMfRbKD72WnWacez/c3KO+vq+bz/+P4jN4FYn+L Web7x1K9BmO3HfDY37cj+940ypO4iaWRcyPlaneL8K0CJaEFcUnCMxWSuyWuZcD730yH5d SzaFNr4HTO441nwmovrvL/1q7s4fjQ4= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-509-LCvw2lHdOjqluZfd-5UPEA-1; Wed, 24 Nov 2021 03:42:05 -0500 X-MC-Unique: LCvw2lHdOjqluZfd-5UPEA-1 Received: by mail-wm1-f69.google.com with SMTP id g11-20020a1c200b000000b003320d092d08so948478wmg.9 for ; Wed, 24 Nov 2021 00:42:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XE2SVTrDU43kAFgXUbiTJeyLZudA8SDW3kmGcRKb0Vw=; b=6w99QksqRUcKL8EsNW40OTiN4TVUVOAMNdi9I3mvvcdYHvNAFXvRMk+VKhYWqZIOLB M1g3Og8HOAfps2Qj30X5h1hOfq+B3rk+etmPvtaDmY25q6jcURr1/7ZV4Fe5ij9ACyr4 p04WgqPa+K76k7Chla444Wh41W5rLBO5xd5rgpM5Q8TX9qKqz4J8BAAaWLwCKwD6/d0G MbYVEX9LwZJTO1GP+kcIkfqIMzLBKINi3vTGgLAqeJIOEBqgICy4fPJwxg5DF04FoCDb owZ/+81dtTX8EzQM+Ykj9dPPF5qbUFeUXVBMOfH1SWBPhE4yssknsRSC0goGN2KcgzbW uZjg== X-Gm-Message-State: AOAM531YhX5BmM/qMWGCgOqjZsGpvpbIcgfJJwv2dJmeO91gwUUm1eP4 792w3tWsAsy9u8lsXhFMBX/xSboeZ8FUhld5ktFbE5eBBeDVOjEsX2T38NwPXrIO8nPs5sslmX+ yUPRBLs6935Up9jz1 X-Received: by 2002:a7b:cf18:: with SMTP id l24mr13013264wmg.145.1637743324587; Wed, 24 Nov 2021 00:42:04 -0800 (PST) X-Google-Smtp-Source: ABdhPJwI2m6uwjDLqQTtYRIdkFde1rsCNcXtW90vlfMyykQKNBK2ibWnzj4IPWNvsza0uD6UQJjz1w== X-Received: by 2002:a7b:cf18:: with SMTP id l24mr13013193wmg.145.1637743324248; Wed, 24 Nov 2021 00:42:04 -0800 (PST) Received: from krava.redhat.com (nat-pool-brq-u.redhat.com. [213.175.37.12]) by smtp.gmail.com with ESMTPSA id 10sm19080756wrb.75.2021.11.24.00.42.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 00:42:04 -0800 (PST) From: Jiri Olsa X-Google-Original-From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Arnaldo Carvalho de Melo , Peter Zijlstra , Masami Hiramatsu , Steven Rostedt Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, lkml , Ingo Molnar , Mark Rutland , Martin KaFai Lau , Alexander Shishkin , Song Liu , Yonghong Song , John Fastabend , KP Singh , Ravi Bangoria Subject: [PATCH 7/8] selftest/bpf: Add kprobe multi attach test Date: Wed, 24 Nov 2021 09:41:18 +0100 Message-Id: <20211124084119.260239-8-jolsa@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124084119.260239-1-jolsa@kernel.org> References: <20211124084119.260239-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Adding kprobe multi attach test that uses new interface to attach multiple probes within single perf event. The test is attaching to bpf_fentry_test* functions and single trampoline program to use bpf_prog_test_run to trigger bpf_fentry_test* functions. Signed-off-by: Jiri Olsa --- .../bpf/prog_tests/multi_kprobe_test.c | 83 +++++++++++++++++++ .../selftests/bpf/progs/multi_kprobe.c | 58 +++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/multi_kprobe_test.c create mode 100644 tools/testing/selftests/bpf/progs/multi_kprobe.c diff --git a/tools/testing/selftests/bpf/prog_tests/multi_kprobe_test.c b/tools/testing/selftests/bpf/prog_tests/multi_kprobe_test.c new file mode 100644 index 000000000000..4aae472f9c16 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/multi_kprobe_test.c @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include "multi_kprobe.skel.h" +#include "trace_helpers.h" + +static void test_funcs_api(void) +{ + struct multi_kprobe *skel = NULL; + __u32 duration = 0, retval; + int err, prog_fd; + + skel = multi_kprobe__open_and_load(); + if (!ASSERT_OK_PTR(skel, "fentry_multi_skel_load")) + goto cleanup; + + err = multi_kprobe__attach(skel); + if (!ASSERT_OK(err, "fentry_attach")) + goto cleanup; + + prog_fd = bpf_program__fd(skel->progs.test1); + err = bpf_prog_test_run(prog_fd, 1, NULL, 0, + NULL, NULL, &retval, &duration); + ASSERT_OK(err, "test_run"); + ASSERT_EQ(retval, 0, "test_run"); + + ASSERT_EQ(skel->bss->test2_result, 8, "test2_result"); + ASSERT_EQ(skel->bss->test3_result, 8, "test3_result"); + +cleanup: + multi_kprobe__destroy(skel); +} + +static void test_addrs_api(void) +{ + struct bpf_link *link1 = NULL, *link2 = NULL; + DECLARE_LIBBPF_OPTS(bpf_kprobe_opts, opts); + struct multi_kprobe *skel = NULL; + __u32 duration = 0, retval; + int err, prog_fd; + __u64 addrs[8]; + + skel = multi_kprobe__open_and_load(); + if (!ASSERT_OK_PTR(skel, "fentry_multi_skel_load")) + goto cleanup; + + kallsyms_find("bpf_fentry_test1", &addrs[0]); + kallsyms_find("bpf_fentry_test2", &addrs[1]); + kallsyms_find("bpf_fentry_test3", &addrs[2]); + kallsyms_find("bpf_fentry_test4", &addrs[3]); + kallsyms_find("bpf_fentry_test5", &addrs[4]); + kallsyms_find("bpf_fentry_test6", &addrs[5]); + kallsyms_find("bpf_fentry_test7", &addrs[6]); + kallsyms_find("bpf_fentry_test8", &addrs[7]); + + opts.multi.cnt = 8; + opts.multi.addrs = (__u64 *) &addrs; + link1 = bpf_program__attach_kprobe_opts(skel->progs.test2, NULL, &opts); + if (!ASSERT_OK_PTR(link1, "link1")) + goto cleanup; + + link2 = bpf_program__attach_kprobe_opts(skel->progs.test3, NULL, &opts); + if (!ASSERT_OK_PTR(link1, "link1")) + goto cleanup; + + prog_fd = bpf_program__fd(skel->progs.test1); + err = bpf_prog_test_run(prog_fd, 1, NULL, 0, + NULL, NULL, &retval, &duration); + ASSERT_OK(err, "test_run"); + ASSERT_EQ(retval, 0, "test_run"); + + ASSERT_EQ(skel->bss->test2_result, 8, "test2_result"); + ASSERT_EQ(skel->bss->test3_result, 8, "test3_result"); + +cleanup: + bpf_link__destroy(link1); + bpf_link__destroy(link2); + multi_kprobe__destroy(skel); +} +void test_multi_kprobe_test(void) +{ + test_funcs_api(); + test_addrs_api(); +} diff --git a/tools/testing/selftests/bpf/progs/multi_kprobe.c b/tools/testing/selftests/bpf/progs/multi_kprobe.c new file mode 100644 index 000000000000..67fe4c2486fc --- /dev/null +++ b/tools/testing/selftests/bpf/progs/multi_kprobe.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + +char _license[] SEC("license") = "GPL"; + +extern const void bpf_fentry_test1 __ksym; +extern const void bpf_fentry_test2 __ksym; +extern const void bpf_fentry_test3 __ksym; +extern const void bpf_fentry_test4 __ksym; +extern const void bpf_fentry_test5 __ksym; +extern const void bpf_fentry_test6 __ksym; +extern const void bpf_fentry_test7 __ksym; +extern const void bpf_fentry_test8 __ksym; + +/* No tests, just to trigger bpf_fentry_test* through tracing test_run */ +SEC("fentry/bpf_modify_return_test") +int BPF_PROG(test1) +{ + return 0; +} + +__u64 test2_result = 0; + +SEC("kprobe.multi/bpf_fentry_test*") +int test2(struct pt_regs *ctx) +{ + __u64 addr = bpf_get_func_ip(ctx); + + test2_result += (const void *) addr == &bpf_fentry_test1 || + (const void *) addr == &bpf_fentry_test2 || + (const void *) addr == &bpf_fentry_test3 || + (const void *) addr == &bpf_fentry_test4 || + (const void *) addr == &bpf_fentry_test5 || + (const void *) addr == &bpf_fentry_test6 || + (const void *) addr == &bpf_fentry_test7 || + (const void *) addr == &bpf_fentry_test8; + return 0; +} + +__u64 test3_result = 0; + +SEC("kretprobe.multi/bpf_fentry_test*") +int test3(struct pt_regs *ctx) +{ + __u64 addr = bpf_get_func_ip(ctx); + + test3_result += (const void *) addr == &bpf_fentry_test1 || + (const void *) addr == &bpf_fentry_test2 || + (const void *) addr == &bpf_fentry_test3 || + (const void *) addr == &bpf_fentry_test4 || + (const void *) addr == &bpf_fentry_test5 || + (const void *) addr == &bpf_fentry_test6 || + (const void *) addr == &bpf_fentry_test7 || + (const void *) addr == &bpf_fentry_test8; + return 0; +} From patchwork Wed Nov 24 08:41:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Olsa X-Patchwork-Id: 12636381 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3D687C433EF for ; Wed, 24 Nov 2021 08:43:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241637AbhKXIqi (ORCPT ); Wed, 24 Nov 2021 03:46:38 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:46759 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236264AbhKXIpW (ORCPT ); Wed, 24 Nov 2021 03:45:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1637743333; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PVPX1C8DkAsQL3LcqECKnIevVpxJ6A8wbBxNyLDX/uc=; b=iSfJrEe4vp2c54+oEA0SMoHVQdO3Njpl92JCwOgkvg2+FwbDdPZJnOXz5Px2X8I/10tF3I kMbwXGsoK7945HWH8iia43SBH+tDbd/Qab7z3RGXXmi8JVeIiSDqcctrLnik9VFtwbiE8m CFB8NMPucnl2gxHynpLUf0kr+vpXPEQ= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-517-7lNuhmotNQWiDF537zKz1A-1; Wed, 24 Nov 2021 03:42:12 -0500 X-MC-Unique: 7lNuhmotNQWiDF537zKz1A-1 Received: by mail-wm1-f70.google.com with SMTP id 69-20020a1c0148000000b0033214e5b021so969417wmb.3 for ; Wed, 24 Nov 2021 00:42:11 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PVPX1C8DkAsQL3LcqECKnIevVpxJ6A8wbBxNyLDX/uc=; b=tRuMUxEaLCwl9RDVAsL2AKyHpYgU8NvatyZJUQm46FArVmB0nrxlRrS2rKdJaTu6Cs 2/aUHy2p4IN9ep9FNYrAya9lV4J4LrA9tzNLdm+EOXRSSGZEHdXTfPWVN2E4zYLbqovm HiSAN9Ds5797g9Ka7FqfAa5NTtuilrZ4XZEbTwWyGGwF7qSVOwT2KZwcRYtFRq/lBCif SiDqaWaxTzGMNKSRmsgZtbtoh10XVcJbBQT3htFlXLGkjSL6iOKvVaSS4OAvYZCD259f 8ZCW3KUvGMaIPfJFHZVS//uAQ4CWvJAt33fL8JCw3nOEvj+YsOZFmyhkQTMq0Gqf3stH jsTQ== X-Gm-Message-State: AOAM530BQeaOik3VCDgEGuJjXNUeuJcJ42UMpLMX1NzQRV/PXLZXkr6v yJVHhd1lV9B0JM6FtAWcU1mD14BYhw3MFcdrWk3+jafxzHp6VBktHsO2emyM0Rt2b5T9sTPO7MV mUqlw098O4XHZ X-Received: by 2002:a5d:508d:: with SMTP id a13mr16396288wrt.41.1637743330683; Wed, 24 Nov 2021 00:42:10 -0800 (PST) X-Google-Smtp-Source: ABdhPJz6/WR79tvkz0a/wesKRWwrirlPIfewyeSdc0r7FwkTqiU7DqPNa47T69UwS0Hg8oKZU/6+Ag== X-Received: by 2002:a5d:508d:: with SMTP id a13mr16396251wrt.41.1637743330451; Wed, 24 Nov 2021 00:42:10 -0800 (PST) Received: from krava.redhat.com (nat-pool-brq-u.redhat.com. [213.175.37.12]) by smtp.gmail.com with ESMTPSA id h27sm4322402wmc.43.2021.11.24.00.42.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 24 Nov 2021 00:42:10 -0800 (PST) From: Jiri Olsa X-Google-Original-From: Jiri Olsa To: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Arnaldo Carvalho de Melo , Peter Zijlstra , Masami Hiramatsu , Steven Rostedt Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, lkml , Ingo Molnar , Mark Rutland , Martin KaFai Lau , Alexander Shishkin , Song Liu , Yonghong Song , John Fastabend , KP Singh , Ravi Bangoria Subject: [PATCH 8/8] selftest/bpf: Add uprobe multi attach test Date: Wed, 24 Nov 2021 09:41:19 +0100 Message-Id: <20211124084119.260239-9-jolsa@kernel.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211124084119.260239-1-jolsa@kernel.org> References: <20211124084119.260239-1-jolsa@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Adding uprobe multi attach test that uses new interface to attach multiple probes within single perf event. Signed-off-by: Jiri Olsa --- .../bpf/prog_tests/multi_uprobe_test.c | 97 +++++++++++++++++++ .../selftests/bpf/progs/multi_uprobe.c | 26 +++++ 2 files changed, 123 insertions(+) create mode 100644 tools/testing/selftests/bpf/prog_tests/multi_uprobe_test.c create mode 100644 tools/testing/selftests/bpf/progs/multi_uprobe.c diff --git a/tools/testing/selftests/bpf/prog_tests/multi_uprobe_test.c b/tools/testing/selftests/bpf/prog_tests/multi_uprobe_test.c new file mode 100644 index 000000000000..0f939893ef45 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/multi_uprobe_test.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include "multi_uprobe.skel.h" + +/* this is how USDT semaphore is actually defined, except volatile modifier */ +extern volatile unsigned short uprobe_ref_ctr; + +/* attach points */ +static void method0(void) { return ; } +static void method1(void) { return ; } +static void method2(void) { return ; } +static void method3(void) { return ; } +static void method4(void) { return ; } +static void method5(void) { return ; } +static void method6(void) { return ; } +static void method7(void) { return ; } + +void test_multi_uprobe_test(void) +{ + DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts); + struct bpf_link *uretprobe_link = NULL; + struct bpf_link *uprobe_link = NULL; + ssize_t base_addr, ref_ctr_offset; + struct multi_uprobe *skel; + const char *paths[8]; + int duration = 0; + __u64 offs[8]; + + skel = multi_uprobe__open_and_load(); + if (CHECK(!skel, "skel_open", "failed to open skeleton\n")) + return; + + base_addr = get_base_addr(); + if (CHECK(base_addr < 0, "get_base_addr", + "failed to find base addr: %zd", base_addr)) + return; + + ref_ctr_offset = get_rel_offset((uintptr_t)&uprobe_ref_ctr); + if (!ASSERT_GE(ref_ctr_offset, 0, "ref_ctr_offset")) + return; + +#define INIT(__i) \ + do { \ + paths[__i] = (const char *) "/proc/self/exe"; \ + offs[__i] = get_uprobe_offset(&method ## __i, base_addr); \ + } while (0) + + INIT(0); + INIT(1); + INIT(2); + INIT(3); + INIT(4); + INIT(5); + INIT(6); + INIT(7); + +#undef INIT + + uprobe_opts.multi.paths = paths; + uprobe_opts.multi.offs = offs; + + uprobe_opts.multi.cnt = 8; + + uprobe_opts.retprobe = false; + uprobe_opts.ref_ctr_offset = ref_ctr_offset; + uprobe_link = bpf_program__attach_uprobe_opts(skel->progs.handle_uprobe, + 0 /* self pid */, + NULL, 0, + &uprobe_opts); + if (!ASSERT_OK_PTR(uprobe_link, "attach_uprobe")) + goto cleanup; + + uprobe_opts.retprobe = true; + uretprobe_link = bpf_program__attach_uprobe_opts(skel->progs.handle_uretprobe, + -1 /* any pid */, + NULL, 0, + &uprobe_opts); + if (!ASSERT_OK_PTR(uretprobe_link, "attach_uretprobe")) + goto cleanup; + + method0(); + method1(); + method2(); + method3(); + method4(); + method5(); + method6(); + method7(); + + ASSERT_EQ(skel->bss->test_uprobe_result, 8, "test_uprobe_result"); + ASSERT_EQ(skel->bss->test_uretprobe_result, 8, "test_uretprobe_result"); + +cleanup: + bpf_link__destroy(uretprobe_link); + bpf_link__destroy(uprobe_link); + multi_uprobe__destroy(skel); +} diff --git a/tools/testing/selftests/bpf/progs/multi_uprobe.c b/tools/testing/selftests/bpf/progs/multi_uprobe.c new file mode 100644 index 000000000000..831f7b98baef --- /dev/null +++ b/tools/testing/selftests/bpf/progs/multi_uprobe.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include + +__u64 test_uprobe_result = 0; + +SEC("uprobe/trigger_func") +int handle_uprobe(struct pt_regs *ctx) +{ + test_uprobe_result++; + return 0; +} + +__u64 test_uretprobe_result = 0; + +SEC("uretprobe/trigger_func") +int handle_uretprobe(struct pt_regs *ctx) +{ + test_uretprobe_result++; + return 0; +} + +char _license[] SEC("license") = "GPL";