From nobody Sat Apr 4 01:33:03 2026 Received: from mail-pj1-f42.google.com (mail-pj1-f42.google.com [209.85.216.42]) (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 205AD3090C6 for ; Fri, 3 Apr 2026 12:44:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775220285; cv=none; b=YSZnWNxUGpcGuO5Ad6ljdQ4TnI/PkOiXvZnsxHZVeMgVOCMgwMVhqzUnaWaF98bnECOwfGqwSchj9uZIgwQuzzFieJPUoKiUR/wqOqCFSgN2rwLr1yTsUt6JpVaVnyhQrdkDcioxkv4B3d+PiB2YB6EGATqUo14FJibxeaLWhi0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775220285; c=relaxed/simple; bh=eYjKVYfzybQe+jxVsJmjY9ny8NiQl/98X514K3TLT+c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NRVosM09fh6M5R4mLKpjdGeEL3FPYF/ATgFCdp2BbNEp0Ov24xYuBNv3PztVx1Q5dCqj+QqxZZ8RnNqWDr6QdOKMnJAOn1jLKP0Awou3c8CujIW3rUcMaCZGL4VSevNMJLDogA5SBuKU8bSnHD+vCt+YHmR5g0qGCT7rbjmBWMY= 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=s5Tcc1Pw; arc=none smtp.client-ip=209.85.216.42 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="s5Tcc1Pw" Received: by mail-pj1-f42.google.com with SMTP id 98e67ed59e1d1-35da1af3e10so1624431a91.3 for ; Fri, 03 Apr 2026 05:44:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775220282; x=1775825082; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kYq4HbaySt1VUvMx+E+B5KGWRejftYj4KcJChzS3H2o=; b=s5Tcc1PwPhOLpZT0euiiuvGyOJvMX0s1hEVoohnFYNDZXJRe9Le/fzeBPZk3Umr2L7 MD0rzBgc1LBv53Aumag0hbkfcT72kdL7i4ZYmtAUNLJOxX/KYTrERFd4aQ6x2PnAAMVP OExk95mdNMbvvRrjBGm/p8B/1Y3JwjFHZqY3mGA0HCImgCo5fIGH5VYsf4YdqGrBknjW 74G10ZnElkc+/MdxiI+V5GJnxbsyQF9oRRp4KUxJhfIDR4Nt1/o5skY2tfYl6ru33NlX zdIzFx2Ht3ARHMUHFBWE15v9Z+blOhKu5hay7GJC4J7W0j6uJ8+KNDawh9uS4GJajtKE owUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775220282; x=1775825082; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=kYq4HbaySt1VUvMx+E+B5KGWRejftYj4KcJChzS3H2o=; b=IrCbBLGtOeBBdfLKz0bnkUP0lh9Ea0CR4CNSqDQReQ6+1E1p0o/Fc+Ay38xjnxQhj1 I8NBu3SuPXvvaA/w1pXZhgrUsfPMFSuwik3pumR5B1yJTSUrQzA+QMRMympvLiqy0kNc oGyVQakLqYEgoYq28ueKGd26Dfu8xc5D2r8JW2wVr7VK5YIhq5GXgFWkTT8UJEdeKeHO x9ILZBaFUPT4gi/0VR/CEXvjCy12e1noXY0lJwslDD/GW8DIU61lmHMuqvsTzH+5O1L5 pflES6mmq/qr2OWUFGXsymQ00mc1ODSPzaHLfPZwFQxvE5zUNtGNvIV5yITi9KqD6JoD HAeA== X-Forwarded-Encrypted: i=1; AJvYcCXCA+eRjNZ1LndyZ+aBMdWnjiQ9GktCU/nNaPmure7sp50Dt9fh3LKIbx6GhiQUV+dK8I+2nPLDOJmli1k=@vger.kernel.org X-Gm-Message-State: AOJu0Yw0CseTEdhSMHgl0x//O+tLhqwcPg01HcpUIhNZw02E6W0bxSOD q68wff5sjO3yqw7U0oxm7bcgm6IzBxZwHoqFWyN6ESRbSWHMlXH6zkle X-Gm-Gg: AeBDies5T3B8/tPSFWRfMhulsWg9hJGIuY6eTiwjD1TP3STaD28N+Uk7bs2O9gLc4BA rXqeu1r2wnIysm476Uw8bLUnGhaX8CkvtjnJm/SVc24TtTqYrUb7jdC2TmFbgA4v+c3wyUgU29V rz7pBgVhRye3N7LWnbJQQALemP/rM/o+SQRyPz4ERUYw0G0ZgmFN1dqpsXj+/YlXR2gxinug08p woHX/nWf2Ucfjdlg+gxtjuqoNZyAlFrcPTcnV4kdncHZCY3s8pWCmzrzetubmZm5tO4n+7yAX81 h9YBcO6d7AiX8wppZ8bHdTmRfBWOLGCRpJa9yBdS0CAh3QX+H3/zmCWI/7ZChqqGXpUGkfSvbDj Xlmnm7Dm5dzN5mn/zLzi8nqFYcAPlCFVOeZK13n8QKj6+UBqxSAeLHkMRMWtlARGKAxim37jgnj syEDPUmCE5QntMkAUJukfQusPrG4XvJCVc8wPDkNxNC0voki8GCECUguTNez6VVTf/vCvj X-Received: by 2002:a17:90b:4ecc:b0:359:7c55:c166 with SMTP id 98e67ed59e1d1-35de67dcbe1mr2574521a91.7.1775220282341; Fri, 03 Apr 2026 05:44:42 -0700 (PDT) Received: from computer.goose-salary.ts.net ([2a09:bac5:40b2:1a96::2a6:1f]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-35dd35f52c8sm5463525a91.5.2026.04.03.05.44.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 05:44:42 -0700 (PDT) From: Varun R Mallya To: bpf@vger.kernel.org, jolsa@kernel.org, leon.hwang@linux.dev, andrii@kernel.org, alan.maguire@oracle.com Cc: ast@kernel.org, eddyz87@gmail.com, martin.lau@linux.dev, daniel@iogearbox.net, linux-kernel@vger.kernel.org, memxor@gmail.com, song@kernel.org, menglong8.dong@gmail.com, varunrmallya@gmail.com Subject: [RFC PATCH bpf-next v3 1/3] libbpf: Auto-upgrade uprobes to multi-uprobes when supported Date: Fri, 3 Apr 2026 18:14:10 +0530 Message-ID: <20260403124412.37449-2-varunrmallya@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260403124412.37449-1-varunrmallya@gmail.com> References: <20260403124412.37449-1-varunrmallya@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 | 42 ++++++++++++++++++- .../selftests/bpf/progs/test_fill_link_info.c | 2 +- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 9ea41f40dc82..6f56bdc243eb 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -8294,6 +8294,22 @@ static int bpf_object_prepare_progs(struct bpf_objec= t *obj) =20 for (i =3D 0; i < obj->nr_programs; i++) { prog =3D &obj->programs[i]; + + if (kernel_supports(obj, FEAT_UPROBE_MULTI_LINK)) { + const char *sec_name =3D 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. + */ + if ((strcmp(sec_name, "uprobe") =3D=3D 0 || + str_has_pfx(sec_name, "uprobe/") || + strcmp(sec_name, "uretprobe") =3D=3D 0 || + str_has_pfx(sec_name, "uretprobe/")) && + !strchr(sec_name, '@')) + prog->expected_attach_type =3D BPF_TRACE_UPROBE_MULTI; + } + err =3D bpf_object__sanitize_prog(obj, prog); if (err) return err; @@ -9955,9 +9971,11 @@ static const struct bpf_sec_def section_defs[] =3D { 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), 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), 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, att= ach_kprobe_multi), SEC_DEF("kprobe.session+", KPROBE, BPF_TRACE_KPROBE_SESSION, SEC_NONE, at= tach_kprobe_session), @@ -12783,6 +12801,27 @@ bpf_program__attach_uprobe_opts(const struct bpf_p= rogram *prog, pid_t pid, func_offset +=3D sym_off; } =20 + /* This provides backwards compatibility to programs using uprobe, but + * have been auto-upgraded to multi uprobe. + */ + if (prog->expected_attach_type =3D=3D BPF_TRACE_UPROBE_MULTI) { + LIBBPF_OPTS(bpf_uprobe_multi_opts, multi_opts); + __u64 bpf_cookie; + + multi_opts.cnt =3D 1; + multi_opts.retprobe =3D OPTS_GET(opts, retprobe, false); + if (func_offset || func_name) + multi_opts.offsets =3D &func_offset; + if (ref_ctr_off) + multi_opts.ref_ctr_offsets =3D &ref_ctr_off; + + bpf_cookie =3D OPTS_GET(opts, bpf_cookie, 0); + if (bpf_cookie) + multi_opts.cookies =3D &bpf_cookie; + + return bpf_program__attach_uprobe_multi(prog, pid, binary_path, + NULL, &multi_opts); + } legacy =3D determine_uprobe_perf_type() < 0; switch (attach_mode) { case PROBE_ATTACH_MODE_LEGACY: @@ -12903,7 +12942,8 @@ static int attach_uprobe(const struct bpf_program *= prog, long cookie, struct bpf offset =3D 0; } opts.retprobe =3D strcmp(probe_type, "uretprobe") =3D=3D 0 || - strcmp(probe_type, "uretprobe.s") =3D=3D 0; + strcmp(probe_type, "uretprobe.s") =3D=3D 0 || + strcmp(probe_type, "uretprobe.single") =3D=3D 0; if (opts.retprobe && offset !=3D 0) { pr_warn("prog '%s': uretprobes do not support offset specification\n", prog->name); diff --git a/tools/testing/selftests/bpf/progs/test_fill_link_info.c b/tool= s/testing/selftests/bpf/progs/test_fill_link_info.c index fac33a14f200..8e47a818462f 100644 --- a/tools/testing/selftests/bpf/progs/test_fill_link_info.c +++ b/tools/testing/selftests/bpf/progs/test_fill_link_info.c @@ -28,7 +28,7 @@ int BPF_PROG(kprobe_run) return 0; } =20 -SEC("uprobe") +SEC("uprobe.single") int BPF_PROG(uprobe_run) { return 0; --=20 2.53.0 From nobody Sat Apr 4 01:33:03 2026 Received: from mail-pj1-f41.google.com (mail-pj1-f41.google.com [209.85.216.41]) (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 B26E43A6EE7 for ; Fri, 3 Apr 2026 12:44:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775220295; cv=none; b=G0kl+LVCUZ8lI8K9R3btXvRhGBwL/nsONkludDPUZRWhhbTE6qtvay1dca4v7NlAsNC3hK60PpDSlCogociA4rbpuNOl7eAhJDPICRBd6T0kSBc462clTkuJDm1F1RXZskrlPHrah0CX4NV+I18rj1Z6b9uklE2yP7yOmHZ+tes= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775220295; c=relaxed/simple; bh=+IB9jGf96wtUN84hD4VlbxFL50yw4CpCunL/Ed+wI8M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qFcozykACYg+RFrezobdiXeHuHz6rRrG5LDw+oYIJwYAxZn4Mj3OGGffV7B81hfMJNWEkraIVLsvzyRN1w7crl/R0rO4/LRYlb7wwJ3FPqGdWhr0WL+Za//3QrPjKXX8Cbr93/bdocOMBzFufKiOydee4jgDBtlXn2FFJkBnAkY= 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=otDBfl0i; arc=none smtp.client-ip=209.85.216.41 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="otDBfl0i" Received: by mail-pj1-f41.google.com with SMTP id 98e67ed59e1d1-358e3cc5e7eso969611a91.0 for ; Fri, 03 Apr 2026 05:44:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775220292; x=1775825092; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=W1P/38vtQcdL49WePaJUfbCTK7MDyAg1D/z13BMMaG8=; b=otDBfl0ipz/OAhkKkciuOBe1rZcTtiRrQG08g+YVda5h+9+vyz+pusKJLSZeJ/QwFO bBjqR/IbtaGuuA/cnhJZCMRNaIXtwNSUXpDisNw+HV2FRLezGY9jC377Ebq78FbEXxEG Qn2BDkgYFqrxBscSNfqbyNLM5Xmh1EO5vkMw28xSl+X149FiTLmCv9jCAUsZhJKyArDU nMViJGGAtBXCmgb41Q/W03SbMxithCrQS+t3NhAIXSQFboDMgLK7SY+xfcMeMcGjh7U4 UpkzJV+gDyBXrsZT73qW4PhGQgLiIxjqXYVfwlWZtMB9Fc/ua1gO11mjShEMdFPyYbIn XT/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775220292; x=1775825092; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=W1P/38vtQcdL49WePaJUfbCTK7MDyAg1D/z13BMMaG8=; b=n030Wm07f+aMH9BUqitXrFq+6iqwgiQMKMqu9dMlbC9pA6XSMXlBUJnie0pnUKr1l5 xxof8sBWoXTx+jJEtR/hrsV5a3/HTAZDYCgGISO04sK6qsH3VXVGdlj2Od4J9x4CT4bx EENrAM2Mn79Ee15BBdl4Eu69PlgiUvIOU2n34MPjh0IdSrPCFKbfZPqr1LNMubj0WA9h frPJwlJSIHbE+svy/NODQf9y23IzwnM6zBmwR3jaX5CI3qOcgulOJ3SgjhjxbMEdajwU AFGe0nYx7O6CfIx/Z25tsS5hIbCoaBUvIbz6o+OZ/FOdd+hg9DFuYI8b1wFG3YVqm+jg lO+g== X-Forwarded-Encrypted: i=1; AJvYcCVM39EnovrGFC45/QmAV1EydfV1BmTgJl5BMFQiz5+amuUQ7UJT2UzjUd4jNNjO58TJNUpQhs9gbJLlte4=@vger.kernel.org X-Gm-Message-State: AOJu0YzPnNSyHqIhD3ttuzo7ZG+JU2PrZvNhV17O9kCEHCLDbMjCYZhN 0RSqyqbZLRN3ugGLWGsKUiuMp/sreEflMHSDcEz5kpVQabcj9gdj5xpU X-Gm-Gg: AeBDiesUBECQ2pINPmjqIp46dnBkBLUXDiePCeW/YGX9vi4DZde6XKjG8IZGDO9WA10 8EsBdE47IBHiXlLy0Wgd/aSQuc0IF7dpPRzx7NTXSdmpH0bQubVO+Au6dz+wGB6gNFMuEc+sgwX tPZqmUI/3HA5eO+3IubJ/1OauXJLfY4g7e4SYPtc0YZ0XX1wzNv/2Bis0sg5plpbZmsABZD3pCD qvr3HjfHSiQLjax0je0zNR5e2qZANTU89UNvP+5tOd7XeUfj04KfaRRg8fzAGA0YmXrXqjSdp/3 rlAXQ26Cftd2OzByEpJChDlUPLprtvwMRa2LsSo7Yh43KZ0r2aEGISOKG45c/vGjdKnswh0lh7h om6qKlyxoqiLSYH2MYC9J2oZ2aGUbRIYCtn8cJbx1jUQpm/fIGb4S+SiIXvalMcJVBC50Eklw3n h9wquMEhLrb8WtUGN0Jfdzm3FQL6zV9RfQ3d1y19A0zFRvOmcAIDd5Xb7+3KWa2IPV52irPmoIW 5Rax8w= X-Received: by 2002:a17:90b:3c0c:b0:35b:9d97:63ac with SMTP id 98e67ed59e1d1-35de684cf9dmr2339910a91.7.1775220291774; Fri, 03 Apr 2026 05:44:51 -0700 (PDT) Received: from computer.goose-salary.ts.net ([2a09:bac5:40b2:1a96::2a6:1f]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-35dd35f52c8sm5463525a91.5.2026.04.03.05.44.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 05:44:51 -0700 (PDT) From: Varun R Mallya To: bpf@vger.kernel.org, jolsa@kernel.org, leon.hwang@linux.dev, andrii@kernel.org, alan.maguire@oracle.com Cc: ast@kernel.org, eddyz87@gmail.com, martin.lau@linux.dev, daniel@iogearbox.net, linux-kernel@vger.kernel.org, memxor@gmail.com, song@kernel.org, menglong8.dong@gmail.com, varunrmallya@gmail.com Subject: [RFC PATCH bpf-next v3 2/3] libbpf: Add FEAT_KPROBE_MULTI_LINK feature probe. Date: Fri, 3 Apr 2026 18:14:11 +0530 Message-ID: <20260403124412.37449-3-varunrmallya@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260403124412.37449-1-varunrmallya@gmail.com> References: <20260403124412.37449-1-varunrmallya@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add FEAT_KPROBE_MULTI_LINK, similar to UPROBE_MULTI_LINK by loading and creating a link for a small BPF program with BPF_TRACE_KPROBE_MULTI as the expected attach type, and then checking the success of the operation. Signed-off-by: Varun R Mallya --- tools/lib/bpf/features.c | 38 +++++++++++++++++++++++++++++++++ tools/lib/bpf/libbpf_internal.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/tools/lib/bpf/features.c b/tools/lib/bpf/features.c index 4f19a0d79b0c..01ded8a1e3c4 100644 --- a/tools/lib/bpf/features.c +++ b/tools/lib/bpf/features.c @@ -424,6 +424,41 @@ static int probe_uprobe_multi_link(int token_fd) return link_fd < 0 && err =3D=3D -EINVAL; } =20 +static int probe_kprobe_multi_link(int token_fd) +{ + LIBBPF_OPTS(bpf_prog_load_opts, load_opts, + .expected_attach_type =3D BPF_TRACE_KPROBE_MULTI, + .token_fd =3D token_fd, + .prog_flags =3D token_fd ? BPF_F_TOKEN_FD : 0, + ); + LIBBPF_OPTS(bpf_link_create_opts, link_opts); + struct bpf_insn insns[] =3D { + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }; + int prog_fd, link_fd, err; + const char *sym =3D "bpf_map_lookup_elem"; /* stable, always present */ + + prog_fd =3D bpf_prog_load(BPF_PROG_TYPE_KPROBE, NULL, "GPL", + insns, ARRAY_SIZE(insns), &load_opts); + if (prog_fd < 0) + return -errno; + + /* attaching to a valid symbol should succeed */ + link_opts.kprobe_multi.syms =3D &sym; + /* MAX_KPROBE_MULTI_CNT is defined as (1U << 20) in kernel/trace/bpf_trac= e.c, + * so we create one more than the allowed limit to make it fail with E2BI= G. + */ + link_opts.kprobe_multi.cnt =3D (1U << 20) + 1; + link_fd =3D bpf_link_create(prog_fd, -1, BPF_TRACE_KPROBE_MULTI, &link_op= ts); + err =3D -errno; + if (link_fd >=3D 0) + close(link_fd); + close(prog_fd); + /* Fails with E2BIG on kernels where kprobe_multi is supported */ + return link_fd <=3D 0 && err =3D=3D -E2BIG; +} + static int probe_kern_bpf_cookie(int token_fd) { struct bpf_insn insns[] =3D { @@ -699,6 +734,9 @@ static struct kern_feature_desc { [FEAT_BTF_LAYOUT] =3D { "kernel supports BTF layout", probe_kern_btf_layout, }, + [FEAT_KPROBE_MULTI_LINK] =3D { + "BPF multi-kprobe link support", probe_kprobe_multi_link, + }, }; =20 bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id= feat_id) diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_interna= l.h index cabdaef79098..b3cb216aadae 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -398,6 +398,8 @@ enum kern_feature_id { FEAT_UPROBE_SYSCALL, /* Kernel supports BTF layout information */ FEAT_BTF_LAYOUT, + /* BPF multi-kprobe link support */ + FEAT_KPROBE_MULTI_LINK, __FEAT_CNT, }; =20 --=20 2.53.0 From nobody Sat Apr 4 01:33:03 2026 Received: from mail-pj1-f48.google.com (mail-pj1-f48.google.com [209.85.216.48]) (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 22A023A6EE7 for ; Fri, 3 Apr 2026 12:45:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775220304; cv=none; b=j5p+fI99Z7v0BUb4tJan06TVqn0uJFWdU7xjpbxh5+xuffwYrTbpAPHmVPKn04TSt3eDBNv82QmBlP6BIGg7T0zW8u5WJzBHr+bIfDuoTIwv4Zo3xYP2/+TxAn/z/Vkus+V58bZ9oNOJPU1tw84A7jyLKRA9I9bCLVDAiOaGNUA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775220304; c=relaxed/simple; bh=kx4MYKFC9pSH4XNzLsm5hYeABYrOiRUbsSb3ezia37c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=az3UiSxndSo2Wmg+rvGYE8b3wCwOOX/Cvu7RdCBg5uCPuZSJYHSZCtJKwykAyh7IcqkMeFTjQMR3AdX2ePVb2ZDt3bJzfpuB66ZMSB1vfkj22A+wdcxQeP5Jg9MKkymubYIq86p3S4QaGVW51/r6xuOpVZui3HHjGsSCt7eHuII= 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=YXTC91eT; arc=none smtp.client-ip=209.85.216.48 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="YXTC91eT" Received: by mail-pj1-f48.google.com with SMTP id 98e67ed59e1d1-35da1af3e10so1624617a91.3 for ; Fri, 03 Apr 2026 05:45:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775220301; x=1775825101; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5Wqfe47DlwB0zJX6L4/75rgnipcNLNutDMkaLQLf/EM=; b=YXTC91eTE6dTX8FFOkDmPdts5i/tm5ekv7D0joMQ1S+HhuzWCrd2RNj6FBgu9ZuX4T Psx6mT/RNP6aoVBWFSvgA5STLjYUtlye1nPgnPVVKl3on6K6F28zLeOC6z1gEkOunBpX ELbCjgL9NGXbU4qfnp2Tqghg+ir4x9tLZ5iyVTdpjO6ev3fFO2X7iW5ZYDNtOvSHmTLa z+6snk1pWCW7dDsqjC1+jE84rTEZ21pSsN9XfQPILQTx4W/L41Hix0/ngm9YmsJOfbEt REBPdGxloj/mdOUmqhqWeahrN1FgdyJJCHinuypBEJqjcfRB3KQNe7pBVtkIPLjgZg2H K3/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775220301; x=1775825101; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=5Wqfe47DlwB0zJX6L4/75rgnipcNLNutDMkaLQLf/EM=; b=AImB3gul+yA3jEy7DyW74ap2DF41XYWPCuvBgAXJofHTMUgIDafF7uXRm8CjsjohwO /Aajfn5yN4ozEnhcR1xDqndYbct1FTPZ+HmXqp5kBgbMXOxqnD7/rMyvBcDq4vfq5mtA /SyStk3zQrv34pS9I0HBSwGoFMx+ub7X/oNpaqpZKIClgJ7BdVXYnYsmObAaHuvXGgKY W/YBMHSyvU4sm4FuZK15BkrBbm2Cc09/5D9hOUKkAuZedUIPIxXAelxLW3heou2tETj0 5gwDsHkL3En9181VTGznmj9mmjCazd63pojZfmZ7SbfFZiGNDVrIpCDdCnUODuYc/N/z XAng== X-Forwarded-Encrypted: i=1; AJvYcCW0QZtm9cEK81+hylZQ6VGrLadAUXT/Fbnfh7tnFT2BJHnN/hZweKOgh0t1AzSExAwgxEtOrerdyGtEui4=@vger.kernel.org X-Gm-Message-State: AOJu0YxM40SYfpO0ZlhAy+7OYAcKtSDJmZJvarw4xxbkybjF4ocFtcwt hpJPyJuA34DaecYYtzbebyV7nC3W+aAm0MVdCFPRh+XX0XMCZP8DxqUP X-Gm-Gg: AeBDievXCOLedkI+bBOGNu9CLz0zwM3gPl0eP9LVwcEkDX2WdY1SNyT3VjTud0zoAb6 su2LvLQ6HgTPvFpgdhDoxmoUBgIBeMe94NcWIEyoKgfl7HkXkgIHwhQe8AN4kF5EsU4ZQTO/2Ji y+NzzFqorOXxMF18AVxvb8kduJWtHT+Oenx60saEyL/+mJ8EkDqE41MgunpfLyjCZJmUbON6cvo uTtZhVQMhmRDjihIF9GKXy4wZwcdMQOP8/c+aDbDOxTKiBJGSBJcgmRyTB8fPHSKLVNSpgRHjBa /BIk5NnUSLn3yPTWHu4mrCGznxfb72wXDqBiQzlLREdstmZGhvTphrMd7TCXXojuQ3KAdy3ecWS GXkXtNzTaA35wS3Zgl+EX6djFgr7kKPjObdX/sCbDcQhAfrrC67qj2C4qkI5FL4bHn7gga9J1Hz sxvs1fumm0ZOIfIiSYisXo9IvTmHLHeici454zI7S3ffEW56NMkeglPgLtmKEBoWSz/2qT X-Received: by 2002:a17:90b:3f4d:b0:35b:e519:213b with SMTP id 98e67ed59e1d1-35de69c3c0bmr2508779a91.30.1775220300938; Fri, 03 Apr 2026 05:45:00 -0700 (PDT) Received: from computer.goose-salary.ts.net ([2a09:bac5:40b2:1a96::2a6:1f]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-35dd35f52c8sm5463525a91.5.2026.04.03.05.44.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 05:45:00 -0700 (PDT) From: Varun R Mallya To: bpf@vger.kernel.org, jolsa@kernel.org, leon.hwang@linux.dev, andrii@kernel.org, alan.maguire@oracle.com Cc: ast@kernel.org, eddyz87@gmail.com, martin.lau@linux.dev, daniel@iogearbox.net, linux-kernel@vger.kernel.org, memxor@gmail.com, song@kernel.org, menglong8.dong@gmail.com, varunrmallya@gmail.com Subject: [RFC PATCH bpf-next v3 3/3] libbpf: Auto-upgrade kprobes to multi-kprobes when supported Date: Fri, 3 Apr 2026 18:14:12 +0530 Message-ID: <20260403124412.37449-4-varunrmallya@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260403124412.37449-1-varunrmallya@gmail.com> References: <20260403124412.37449-1-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="utf-8" Content-Transfer-Encoding: quoted-printable This patch modifies libbpf to automatically upgrade standard SEC("kprobe") and SEC("kretprobe") programs to use the multi-kprobe infrastructure (BPF_TRACE_KPROBE_MULTI) at load time if the kernel supports it, making them compatible with BPF tokens. To maintain backward compatibility and handle cases where singular kprobes are required, new SEC("kprobe.single") and SEC("kretprobe.single") section types are introduced. These force libbpf to use the legacy perf_event_open() attachment path. The following explain the reasoning for changing selftests: - test_fill_link_info.c kprobe=E2=86=92kprobe.single: this test calls bpf_link_get_info_by_fd and asserts BPF_LINK_TYPE_PERF_EVENT and it explicitly needs the perf_event attachment path, which breaks after auto-upgrade to multi. - test_attach_probe_manual.c kprobe=E2=86=92kprobe.single, kretprobe=E2=86=92kretprobe.single: this test exercises all four explicit attachment modes (default, legacy, perf, link) and PROBE_ATTACH_MODE_LINK creates a perf_event BPF link which the kernel rejects for a prog loaded with expected_attach_type =3D BPF_TRACE_KPROBE_MULTI. - missed_kprobe.c kprobe->kprobe.single: The link is explicitly checked in the tests due to which it fails if we do not specifically kprobe.single this. - get_func_ip_test.c ?kprobe=E2=86=92?kprobe.single: the ? is stripped from sec_name by libbpf at init time so the prog still gets auto-upgraded. It is then manually attached with a non-zero body offset, which kprobe_multi doesn't support. Signed-off-by: Varun R Mallya --- tools/lib/bpf/libbpf.c | 104 ++++++++++++++---- .../selftests/bpf/progs/get_func_ip_test.c | 2 +- .../selftests/bpf/progs/missed_kprobe.c | 4 +- .../bpf/progs/test_attach_probe_manual.c | 4 +- .../selftests/bpf/progs/test_fill_link_info.c | 2 +- 5 files changed, 88 insertions(+), 28 deletions(-) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 6f56bdc243eb..7c6680759b0a 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -8286,6 +8286,43 @@ bpf_object__load_progs(struct bpf_object *obj, int l= og_level) return 0; } =20 +/* This function is responsible for upgrading uprobes and kprobes + * to their multi counterparts. + */ +static int upgrade_program(struct bpf_object *obj, struct bpf_program *pro= g) +{ + const char *sec_name =3D prog->sec_name; + + if (kernel_supports(obj, FEAT_UPROBE_MULTI_LINK)) { + /* 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. + */ + if ((strcmp(sec_name, "uprobe") =3D=3D 0 || + str_has_pfx(sec_name, "uprobe/") || + strcmp(sec_name, "uretprobe") =3D=3D 0 || + str_has_pfx(sec_name, "uretprobe/")) && + !strchr(sec_name, '@')) + prog->expected_attach_type =3D BPF_TRACE_UPROBE_MULTI; + } + + if (kernel_supports(obj, FEAT_KPROBE_MULTI_LINK)) { + /* Here, we filter out for k[ret]probe or "k[ret]probe/". + * We also do not allow '+' as we do not support + * offsets in kprobe_multi. + */ + if ((strcmp(sec_name, "kprobe") =3D=3D 0 || + str_has_pfx(sec_name, "kprobe/") || + strcmp(sec_name, "kretprobe") =3D=3D 0 || + str_has_pfx(sec_name, "kretprobe/")) && + !strchr(sec_name, '+')) + prog->expected_attach_type =3D BPF_TRACE_KPROBE_MULTI; + } + + return 0; +} + static int bpf_object_prepare_progs(struct bpf_object *obj) { struct bpf_program *prog; @@ -8294,22 +8331,9 @@ static int bpf_object_prepare_progs(struct bpf_objec= t *obj) =20 for (i =3D 0; i < obj->nr_programs; i++) { prog =3D &obj->programs[i]; - - if (kernel_supports(obj, FEAT_UPROBE_MULTI_LINK)) { - const char *sec_name =3D 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. - */ - if ((strcmp(sec_name, "uprobe") =3D=3D 0 || - str_has_pfx(sec_name, "uprobe/") || - strcmp(sec_name, "uretprobe") =3D=3D 0 || - str_has_pfx(sec_name, "uretprobe/")) && - !strchr(sec_name, '@')) - prog->expected_attach_type =3D BPF_TRACE_UPROBE_MULTI; - } - + err =3D upgrade_program(obj, prog); + if (err) + return err; err =3D bpf_object__sanitize_prog(obj, prog); if (err) return err; @@ -9969,10 +9993,12 @@ static const struct bpf_sec_def section_defs[] =3D { SEC_DEF("sk_reuseport/migrate", SK_REUSEPORT, BPF_SK_REUSEPORT_SELECT_OR_= MIGRATE, SEC_ATTACHABLE), SEC_DEF("sk_reuseport", SK_REUSEPORT, BPF_SK_REUSEPORT_SELECT, SEC_ATTAC= HABLE), SEC_DEF("kprobe+", KPROBE, 0, SEC_NONE, attach_kprobe), + SEC_DEF("kprobe.single+", 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), SEC_DEF("kretprobe+", KPROBE, 0, SEC_NONE, attach_kprobe), + SEC_DEF("kretprobe.single+", 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), @@ -11814,6 +11840,30 @@ bpf_program__attach_kprobe_opts(const struct bpf_p= rogram *prog, offset =3D OPTS_GET(opts, offset, 0); pe_opts.bpf_cookie =3D OPTS_GET(opts, bpf_cookie, 0); =20 + /* This provides backwards compatibility to programs using kprobe, but + * have been auto-upgraded to multi kprobe. + */ + if (prog->expected_attach_type =3D=3D BPF_TRACE_KPROBE_MULTI && + offset =3D=3D 0 && attach_mode =3D=3D PROBE_ATTACH_MODE_DEFAULT) { + LIBBPF_OPTS(bpf_kprobe_multi_opts, multi_opts); + __u64 bpf_cookie; + + multi_opts.retprobe =3D OPTS_GET(opts, retprobe, false); + multi_opts.syms =3D &func_name; + multi_opts.cnt =3D 1; + bpf_cookie =3D OPTS_GET(opts, bpf_cookie, 0); + if (bpf_cookie) + multi_opts.cookies =3D &bpf_cookie; + + return bpf_program__attach_kprobe_multi_opts(prog, NULL, &multi_opts); + } + + if (prog->expected_attach_type =3D=3D BPF_TRACE_KPROBE_MULTI) { + pr_warn("prog '%s': multi-kprobe upgrade failed (off=3D%lu, mode=3D%d); = use SEC(\"kprobe.single\")\n", + prog->name, offset, attach_mode); + return libbpf_err_ptr(-ENOTSUP); + } + legacy =3D determine_kprobe_perf_type() < 0; switch (attach_mode) { case PROBE_ATTACH_MODE_LEGACY: @@ -12268,14 +12318,24 @@ static int attach_kprobe(const struct bpf_program= *prog, long cookie, struct bpf *link =3D NULL; =20 /* no auto-attach for SEC("kprobe") and SEC("kretprobe") */ - if (strcmp(prog->sec_name, "kprobe") =3D=3D 0 || strcmp(prog->sec_name, "= kretprobe") =3D=3D 0) + if (strcmp(prog->sec_name, "kprobe") =3D=3D 0 || + strcmp(prog->sec_name, "kretprobe") =3D=3D 0 || + strcmp(prog->sec_name, "kprobe.single") =3D=3D 0 || + strcmp(prog->sec_name, "kretprobe.single") =3D=3D 0) return 0; =20 - opts.retprobe =3D str_has_pfx(prog->sec_name, "kretprobe/"); - if (opts.retprobe) - func_name =3D prog->sec_name + sizeof("kretprobe/") - 1; - else - func_name =3D prog->sec_name + sizeof("kprobe/") - 1; + if (str_has_pfx(prog->sec_name, "kretprobe/") || + str_has_pfx(prog->sec_name, "kretprobe.single/")) { + opts.retprobe =3D true; + func_name =3D str_has_pfx(prog->sec_name, "kretprobe/") + ? prog->sec_name + sizeof("kretprobe/") - 1 + : prog->sec_name + sizeof("kretprobe.single/") - 1; + } else { + opts.retprobe =3D false; + func_name =3D str_has_pfx(prog->sec_name, "kprobe.single/") + ? prog->sec_name + sizeof("kprobe.single/") - 1 + : prog->sec_name + sizeof("kprobe/") - 1; + } =20 n =3D sscanf(func_name, "%m[a-zA-Z0-9_.]+%li", &func, &offset); if (n < 1) { diff --git a/tools/testing/selftests/bpf/progs/get_func_ip_test.c b/tools/t= esting/selftests/bpf/progs/get_func_ip_test.c index 2011cacdeb18..a039760b8516 100644 --- a/tools/testing/selftests/bpf/progs/get_func_ip_test.c +++ b/tools/testing/selftests/bpf/progs/get_func_ip_test.c @@ -73,7 +73,7 @@ int BPF_PROG(test5, int a, int *b, int ret) } =20 __u64 test6_result =3D 0; -SEC("?kprobe") +SEC("?kprobe.single") int test6(struct pt_regs *ctx) { __u64 addr =3D bpf_get_func_ip(ctx); diff --git a/tools/testing/selftests/bpf/progs/missed_kprobe.c b/tools/test= ing/selftests/bpf/progs/missed_kprobe.c index 51a4fe64c917..5f405888ed0b 100644 --- a/tools/testing/selftests/bpf/progs/missed_kprobe.c +++ b/tools/testing/selftests/bpf/progs/missed_kprobe.c @@ -16,14 +16,14 @@ int BPF_PROG(trigger) return 0; } =20 -SEC("kprobe/bpf_fentry_test1") +SEC("kprobe.single/bpf_fentry_test1") int test1(struct pt_regs *ctx) { bpf_kfunc_common_test(); return 0; } =20 -SEC("kprobe/bpf_kfunc_common_test") +SEC("kprobe.single/bpf_kfunc_common_test") int test2(struct pt_regs *ctx) { return 0; diff --git a/tools/testing/selftests/bpf/progs/test_attach_probe_manual.c b= /tools/testing/selftests/bpf/progs/test_attach_probe_manual.c index 7f08bce94596..eb0fa3b39c5f 100644 --- a/tools/testing/selftests/bpf/progs/test_attach_probe_manual.c +++ b/tools/testing/selftests/bpf/progs/test_attach_probe_manual.c @@ -14,14 +14,14 @@ int uretprobe_res =3D 0; int uprobe_byname_res =3D 0; void *user_ptr =3D 0; =20 -SEC("kprobe") +SEC("kprobe.single") int handle_kprobe(struct pt_regs *ctx) { kprobe_res =3D 1; return 0; } =20 -SEC("kretprobe") +SEC("kretprobe.single") int handle_kretprobe(struct pt_regs *ctx) { kretprobe_res =3D 2; diff --git a/tools/testing/selftests/bpf/progs/test_fill_link_info.c b/tool= s/testing/selftests/bpf/progs/test_fill_link_info.c index 8e47a818462f..bc6cfed71fb8 100644 --- a/tools/testing/selftests/bpf/progs/test_fill_link_info.c +++ b/tools/testing/selftests/bpf/progs/test_fill_link_info.c @@ -22,7 +22,7 @@ int unused(void) CONFIG_PPC64 ? 0 : 1; } =20 -SEC("kprobe") +SEC("kprobe.single") int BPF_PROG(kprobe_run) { return 0; --=20 2.53.0