From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BCCE4324B33 for ; Mon, 30 Mar 2026 14:52:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774882354; cv=none; b=Pduip7pdDpIqg5sslvJczItvm7MrE3SvBAo3PaGlvVtNh86vBBRaZFrBPmtEnLl2WPoywuP+NKPhCv4NMMa6rTdnbB0UxTkU0O8VmWS6hYQmDMUT7xJAthpend2KAbW5TLCaTppMC/5DD/wYIXDodFE5JQx2rKdcCn7eOLSOscs= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774882354; c=relaxed/simple; bh=Dr49MJN7Xs6KFA9MCEfc/ZihEyIU2Q6UOjgd46I42Fo=; h=From:Date:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=USfleYbTiCzE94bQwgOgQI2izq1zS5/VCPKRiDGkkqAi1WmTlJDIHlRqH6BXspVl+4jhbJBa3tVRCcQxfCLvBpTq2JVCNOMq9jQyBJYah4Eu/AoVWEhSd0RU3N1Ab/5veEJx8DuMbWTIn02VfR15ZVvNSRly2OXifRmlptV3HTI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=pOKvv2rc; arc=none smtp.client-ip=209.85.128.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="pOKvv2rc" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-48704db565eso59923845e9.1 for ; Mon, 30 Mar 2026 07:52:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774882351; x=1775487151; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:date:from:from:to:cc:subject:date:message-id:reply-to; bh=5eASIWITpIttTu7/75f4mcjIFMWWKY22XxTe2Uo0MgI=; b=pOKvv2rc1BrF03h411f4YQQDXlMki2qu+cmk60aLWx5vizfDvTF/Wfpt672laLEmM4 VFLHk3oeGbVZw47hJxfPF+oC2X7MXT2f6ga5wZRdD/UJ5KrXkMB/5vjOwvdz6g0ESAmn HCpfAKEo/O4c0bjbNXRxLhtpgjSX5Op0O9+n7A+bgn5svT4akPrER6Oka4/KEHcOdjPe tDg98OWOXp1TDgR8O79guHkzg3TnKhm/xAJz0pC0ebBaJw0BTC8ZxS2l4NhVDj4VUJlz OMLy10zCO6gpimNXUiK2UGt0Dokn5EZBzJ7ecjZZis69n7kiYLQJbLiNon16YNdzPTYh Xe6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774882351; x=1775487151; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:date:from:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5eASIWITpIttTu7/75f4mcjIFMWWKY22XxTe2Uo0MgI=; b=UwvwZ6jQKGdezH/h166BZtcM+IM3lquqHJKlRiXJe+oaa/D4jW2U+zT4W1Pve5XQHn YDfxVzeMlHlQapybQOpNcQfN1+O5uV/Xs02I+Yx8wgNqnEYPzio3Mx24g4L+GDTJUnzB sK8iDDLUkZd7Vic6brgWYaAKSf8znd4gEL+oYqFbFieDdxj9z8SoH9wdzO8ktAyEO2Cb Us6NSjCN5BVAlo2s4uQ2KqYejSoNQsVD48E0mEjPlfFR6R809eskaF0tJiB4RlHqzHik wmKf0gF0S1vx/Gh/xE8/5p6XLxT5Qygm+ZulUyR7JPYJVlQ/aomsLyk3uoKgVnkRe+0h nj2w== X-Forwarded-Encrypted: i=1; AJvYcCUSHTEDwLvteII7bnaS9hMvUIbLhZ75ijpsdSqDfDNo97yQQHREZQuLMYVp2JTrpO+fkn8+TRJ9T3jaoiE=@vger.kernel.org X-Gm-Message-State: AOJu0YwMPP2jHNi9ReZIPOeOUABcqa9Gdjv8AF2knSvFDp2DVLzqnq1M SZ6pLfAn0ntn+oIXVFrTXzzxbUHX1W9TbY/p4rTZ3oNtu34lzq8HBwSM X-Gm-Gg: ATEYQzz46QASymsbdQaHsd6PL8qpGSV83rILDK+pCu+5c0ev15ZrbEbZsUI0p8Ug2UW AthspBCF5ZQ/aP6JhfaG7fbOfuHH5rehugbtlBF08HguIO8wUnvBAS/J/M774K6+jhWhxYxO8Lx 2njMN0w+Pcsrs8y3L7Z2fitEjJFwx01WZP7ZcdHKAcz+5GZK4Y4ylLqMgGSoUw2uedJgBnorZtv 7vCbvHHqcVCDG1WcPCuFQAHtWHJTS2KygJixBQwKYrYv1PlGm5gNyLURk8o0P27TGWmEqIuLnzq boCxC/c2jrrXHbDgDKn2p90kl4/UTTTbPNFVMVw3nhjAUB9ufIsZoRwp35PXpC4IemsZs+uPPXC N9wfdak4X6G0WvUzThVWCB6shDx32l2m6W6BHh9f+c07ys4PmeupLX7hgjLA8hrOEoLIMu0tMdk PijLO6tOd9Fx4cbGlr7Djf0lhTyqZGoyWJHFAAqa5mACkEfCOmT0WnNsAAi6ztPNzvlkIi X-Received: by 2002:a05:6000:18a3:b0:43c:fe66:43fb with SMTP id ffacd0b85a97d-43cfe66466emr7307517f8f.17.1774882350832; Mon, 30 Mar 2026 07:52:30 -0700 (PDT) Received: from krava (cust-west-par-46-193-1-135.cust.wifirst.net. [46.193.1.135]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43cf21e265fsm20300486f8f.1.2026.03.30.07.52.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Mar 2026 07:52:30 -0700 (PDT) From: Jiri Olsa X-Google-Original-From: Jiri Olsa Date: Mon, 30 Mar 2026 16:52:27 +0200 To: Varun R Mallya Cc: andrii@kernel.org, alan.maguire@oracle.com, yonghong.song@linux.dev, song@kernel.org, bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net, memxor@gmail.com, eddyz87@gmail.com, martin.lau@linux.dev, menglong8.dong@gmail.com, puranjay@kernel.org, bjorn@kernel.org, leon.hwang@linux.dev, linux-kernel@vger.kernel.org Subject: Re: [RFC PATCH bpf-next v2 1/3] libbpf: Auto-upgrade uprobes to multi-uprobes when supported Message-ID: References: <20260330110019.549079-1-varunrmallya@gmail.com> <20260330110019.549079-2-varunrmallya@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260330110019.549079-2-varunrmallya@gmail.com> On Mon, Mar 30, 2026 at 04:30:17PM +0530, Varun R Mallya wrote: > This patch modifies libbpf to automatically "upgrade" standard > SEC("uprobe") and SEC("uretprobe") programs to use the multi-uprobe > infrastructure (BPF_TRACE_UPROBE_MULTI) at load time if the kernel > supports it, making them compatible with BPF tokens. > > To maintain backward compatibility and handle rare cases where singular > uprobes are required, new SEC("uprobe.single") and SEC("uretprobe.single") > section types are introduced. These force libbpf to use the legacy > perf_event_open() attachment path. > > tools/testing/selftests/bpf/progs/test_fill_link_info.c has been > modified to use SEC("uprobe.single") as it asserts the program type to be > `BPF_LINK_TYPE_PERF_EVENT` and checks properties related to uprobes that > use perf. > > Signed-off-by: Varun R Mallya > --- > tools/lib/bpf/libbpf.c | 53 +++++++++++++++++-- > .../selftests/bpf/progs/test_fill_link_info.c | 2 +- > 2 files changed, 51 insertions(+), 4 deletions(-) > > diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c > index 1eaa7527d4da..bd7b6f486430 100644 > --- a/tools/lib/bpf/libbpf.c > +++ b/tools/lib/bpf/libbpf.c > @@ -8248,6 +8248,23 @@ static int bpf_object_prepare_progs(struct bpf_object *obj) > > for (i = 0; i < obj->nr_programs; i++) { > prog = &obj->programs[i]; > + > + if (kernel_supports(obj, FEAT_UPROBE_MULTI_LINK)) { > + const char *sec_name = prog->sec_name; > + /* Here, we filter out for u[ret]probe or "u[ret]probe/" > + * but we leave out anything with an '@' > + * in it as uprobe_multi does not support versioned > + * symbols yet, so we don't upgrade. > + */ nice, I missed that uprobe.multi does not support versioned symbols, I guess we should fix that > + if (((strncmp(sec_name, "uprobe", 6) == 0 && str_has_pfx ? > + (sec_name[6] == '/' || sec_name[6] == '\0')) || > + (strncmp(sec_name, "uretprobe", 9) == 0 && > + (sec_name[9] == '/' || sec_name[9] == '\0'))) && > + !strchr(sec_name, '@')) { > + prog->expected_attach_type = BPF_TRACE_UPROBE_MULTI; > + } > + } > + > err = bpf_object__sanitize_prog(obj, prog); > if (err) > return err; > @@ -9909,9 +9926,11 @@ static const struct bpf_sec_def section_defs[] = { > SEC_DEF("kprobe+", KPROBE, 0, SEC_NONE, attach_kprobe), > SEC_DEF("uprobe+", KPROBE, 0, SEC_NONE, attach_uprobe), > SEC_DEF("uprobe.s+", KPROBE, 0, SEC_SLEEPABLE, attach_uprobe), > + SEC_DEF("uprobe.single+", KPROBE, 0, SEC_NONE, attach_uprobe), should we add sleepable counterparts? > SEC_DEF("kretprobe+", KPROBE, 0, SEC_NONE, attach_kprobe), > SEC_DEF("uretprobe+", KPROBE, 0, SEC_NONE, attach_uprobe), > SEC_DEF("uretprobe.s+", KPROBE, 0, SEC_SLEEPABLE, attach_uprobe), > + SEC_DEF("uretprobe.single+", KPROBE, 0, SEC_NONE, attach_uprobe), just an idea for discussion.. I wonder if it'd be better to add new uprobe section that will upgrade itself to uprobe.multi if it's present, instead of changing the existing (expected) type but I guess we want existing uprobe programs to benefit from that and there's not really a reason anyone would want perf based uprobe when uprobe_multi is supported ok I talked myself out of it ;-) > SEC_DEF("kprobe.multi+", KPROBE, BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi), > SEC_DEF("kretprobe.multi+", KPROBE, BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi), > SEC_DEF("kprobe.session+", KPROBE, BPF_TRACE_KPROBE_SESSION, SEC_NONE, attach_kprobe_session), > @@ -12737,6 +12756,32 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid, > func_offset += sym_off; > } > > + /* This provides backwards compatibility to programs using uprobe, but > + * have been auto-upgraded to multi uprobe. > + */ > + if (prog->expected_attach_type == BPF_TRACE_UPROBE_MULTI) { > + LIBBPF_OPTS(bpf_uprobe_multi_opts, multi_opts); > + unsigned long offsets[1] = {func_offset}; > + __u64 bpf_cookie; > + > + multi_opts.retprobe = OPTS_GET(opts, retprobe, false); > + if (offsets[0] || func_name) { > + multi_opts.offsets = offsets; could we do the same as for ref_ctr_off case and drop the offsets array? multi_opts.offsets = &func_offset; > + multi_opts.cnt = 1; > + } > + if (ref_ctr_off) { > + multi_opts.ref_ctr_offsets = &ref_ctr_off; > + multi_opts.cnt = 1; > + } > + bpf_cookie = OPTS_GET(opts, bpf_cookie, 0); > + if (bpf_cookie) { > + multi_opts.cookies = &bpf_cookie; > + multi_opts.cnt = 1; I think it's better just to set multi_opts.cnt = 1 once outside those if conditions > + } > + > + return bpf_program__attach_uprobe_multi(prog, pid, binary_path, > + NULL, &multi_opts); > + } > legacy = determine_uprobe_perf_type() < 0; > switch (attach_mode) { > case PROBE_ATTACH_MODE_LEGACY: > @@ -12830,6 +12875,7 @@ static int attach_uprobe(const struct bpf_program *prog, long cookie, struct bpf > char *probe_type = NULL, *binary_path = NULL, *func_name = NULL, *func_off; > int n, c, ret = -EINVAL; > long offset = 0; > + bool is_retprobe; > > *link = NULL; > > @@ -12856,13 +12902,14 @@ static int attach_uprobe(const struct bpf_program *prog, long cookie, struct bpf > else > offset = 0; > } > - opts.retprobe = strcmp(probe_type, "uretprobe") == 0 || > - strcmp(probe_type, "uretprobe.s") == 0; > - if (opts.retprobe && offset != 0) { > + is_retprobe = strcmp(probe_type, "uretprobe") == 0 || > + strcmp(probe_type, "uretprobe.s") == 0; > + if (is_retprobe && offset != 0) { > pr_warn("prog '%s': uretprobes do not support offset specification\n", > prog->name); > break; > } > + opts.retprobe = is_retprobe; is there any functional change above? looks like just opts.retprobe is replaced with is_retprobe ? jirka