From patchwork Mon Apr 29 13:16:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Puranjay Mohan X-Patchwork-Id: 13646946 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C9B367350E; Mon, 29 Apr 2024 13:17:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714396627; cv=none; b=Ct2P7t1GQxT9Yqhbe2capzlgaU8JI7kCfmF+81hwU1+DE70TuDvXhA5L+g5285jZKqKnTGw6bGB0BdOnKpmo+Pn9AfZrSgj4uM2i4Y9i+s6VAs3FFilg+a2lGMEyOhnMxcrrrjzYa3mLRRfQQ3r6nrY7aTCv3XQ/LYwa4Soz18Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714396627; c=relaxed/simple; bh=TbPOTBmS82ynsL8h5jbyPu2ZW+Geh2onSqdzZPRv0KM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=nZNXrenayPqPq0YQdxAwurpSLUE9JoSgk2snngtYmpo2PHYoWBRI8cgzOza4c01ylD/EetC2GEPfw7B7Lm8mcjb2rUgKfXu7TA0E5R4K+q7hh5sqFgPIlJt2pYXqftC9uYjpYR5B8Ijqn1QeG5CWQNzTU//3CNNOuagilMpBVng= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HO1IrVTG; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HO1IrVTG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 25BC4C113CD; Mon, 29 Apr 2024 13:17:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1714396627; bh=TbPOTBmS82ynsL8h5jbyPu2ZW+Geh2onSqdzZPRv0KM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HO1IrVTGne4vshDceYQk3aUXferuUIFE61oHPFTZemhBmKxvTTmyOv1vRx/Qm8uvh y4vsAOHfP6oTuswdUQxXbwqDazG6ST39FVUk1Tex7anKu0YAUsso+hM2lnRO1qXzOT oWgh5y+HkPJ/4WFEMxl0KQE3ane5sXozPxG09yqyTS2icK/q2hBag4VaGY2cznE44e CwCmhLT4lgmB845VbpOxkvxltPjrytZ4gUrdQGuyze1Ho6d0vw7Ow8GcoIOYarB/oC PlOVR+jKkrOC5J93rBD2XrdcidETmWguJm7yVsQ8rQoAwapNoIl8P0+Klm04srJHWQ PCBI/tY6AXHDQ== From: Puranjay Mohan To: Catalin Marinas , Will Deacon , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Zi Shen Lim , Xu Kuohai , Florent Revest , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Cc: puranjay12@gmail.com Subject: [PATCH bpf-next v4 1/2] arm64, bpf: add internal-only MOV instruction to resolve per-CPU addrs Date: Mon, 29 Apr 2024 13:16:46 +0000 Message-Id: <20240429131647.50165-2-puranjay@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240429131647.50165-1-puranjay@kernel.org> References: <20240429131647.50165-1-puranjay@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net From: Puranjay Mohan Support an instruction for resolving absolute addresses of per-CPU data from their per-CPU offsets. This instruction is internal-only and users are not allowed to use them directly. They will only be used for internal inlining optimizations for now between BPF verifier and BPF JITs. Since commit 7158627686f0 ("arm64: percpu: implement optimised pcpu access using tpidr_el1"), the per-cpu offset for the CPU is stored in the tpidr_el1/2 register of that CPU. To support this BPF instruction in the ARM64 JIT, the following ARM64 instructions are emitted: mov dst, src // Move src to dst, if src != dst mrs tmp, tpidr_el1/2 // Move per-cpu offset of the current cpu in tmp. add dst, dst, tmp // Add the per cpu offset to the dst. To measure the performance improvement provided by this change, the benchmark in [1] was used: Before: glob-arr-inc : 23.597 ± 0.012M/s arr-inc : 23.173 ± 0.019M/s hash-inc : 12.186 ± 0.028M/s After: glob-arr-inc : 23.819 ± 0.034M/s arr-inc : 23.285 ± 0.017M/s hash-inc : 12.419 ± 0.011M/s [1] https://github.com/anakryiko/linux/commit/8dec900975ef Signed-off-by: Puranjay Mohan --- arch/arm64/include/asm/insn.h | 7 +++++++ arch/arm64/lib/insn.c | 11 +++++++++++ arch/arm64/net/bpf_jit.h | 6 ++++++ arch/arm64/net/bpf_jit_comp.c | 14 ++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h index db1aeacd4cd9..8de0e39b29f3 100644 --- a/arch/arm64/include/asm/insn.h +++ b/arch/arm64/include/asm/insn.h @@ -135,6 +135,11 @@ enum aarch64_insn_special_register { AARCH64_INSN_SPCLREG_SP_EL2 = 0xF210 }; +enum aarch64_insn_system_register { + AARCH64_INSN_SYSREG_TPIDR_EL1 = 0x4684, + AARCH64_INSN_SYSREG_TPIDR_EL2 = 0x6682, +}; + enum aarch64_insn_variant { AARCH64_INSN_VARIANT_32BIT, AARCH64_INSN_VARIANT_64BIT @@ -686,6 +691,8 @@ u32 aarch64_insn_gen_cas(enum aarch64_insn_register result, } #endif u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type); +u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result, + enum aarch64_insn_system_register sysreg); s32 aarch64_get_branch_offset(u32 insn); u32 aarch64_set_branch_offset(u32 insn, s32 offset); diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c index a635ab83fee3..b008a9b46a7f 100644 --- a/arch/arm64/lib/insn.c +++ b/arch/arm64/lib/insn.c @@ -1515,3 +1515,14 @@ u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type) return insn; } + +u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result, + enum aarch64_insn_system_register sysreg) +{ + u32 insn = aarch64_insn_get_mrs_value(); + + insn &= ~GENMASK(19, 0); + insn |= sysreg << 5; + return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, + insn, result); +} diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h index 23b1b34db088..b627ef7188c7 100644 --- a/arch/arm64/net/bpf_jit.h +++ b/arch/arm64/net/bpf_jit.h @@ -297,4 +297,10 @@ #define A64_ADR(Rd, offset) \ aarch64_insn_gen_adr(0, offset, Rd, AARCH64_INSN_ADR_TYPE_ADR) +/* MRS */ +#define A64_MRS_TPIDR_EL1(Rt) \ + aarch64_insn_gen_mrs(Rt, AARCH64_INSN_SYSREG_TPIDR_EL1) +#define A64_MRS_TPIDR_EL2(Rt) \ + aarch64_insn_gen_mrs(Rt, AARCH64_INSN_SYSREG_TPIDR_EL2) + #endif /* _BPF_JIT_H */ diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index 76b91f36c729..ed8f9716d9d5 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -877,6 +877,15 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, emit(A64_ORR(1, tmp, dst, tmp), ctx); emit(A64_MOV(1, dst, tmp), ctx); break; + } else if (insn_is_mov_percpu_addr(insn)) { + if (dst != src) + emit(A64_MOV(1, dst, src), ctx); + if (cpus_have_cap(ARM64_HAS_VIRT_HOST_EXTN)) + emit(A64_MRS_TPIDR_EL2(tmp), ctx); + else + emit(A64_MRS_TPIDR_EL1(tmp), ctx); + emit(A64_ADD(1, dst, dst, tmp), ctx); + break; } switch (insn->off) { case 0: @@ -2527,6 +2536,11 @@ bool bpf_jit_supports_arena(void) return true; } +bool bpf_jit_supports_percpu_insn(void) +{ + return true; +} + void bpf_jit_free(struct bpf_prog *prog) { if (prog->jited) { From patchwork Mon Apr 29 13:16:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Puranjay Mohan X-Patchwork-Id: 13646947 X-Patchwork-Delegate: bpf@iogearbox.net Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5961C7350E; Mon, 29 Apr 2024 13:17:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714396631; cv=none; b=bwKBNer82bUL/dynYscef8quC2HDNg1tnlquy2tnhs+sBrdb/L/tKQgLxl4VHiFGxbYZgVBgzJMPNjU6Ze5+aMPHz+3i//aA66q0ScWfKFsAZ3OidarV62c9dV+xnLujcqvXJ9gM+uYP8SaTf9xRz/TCeQ546MTp92uREnDmBhg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714396631; c=relaxed/simple; bh=w2Ysbdlw62K0XMPywgvp3DwJa4tgzeEkrintEchxF5U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=DhSn6fQP53lhITcs863x0pSS8zvhhc4Zaf4N+fzwN7wlXuGQCU/hOQfXjKsWYVigSQyx3RXX/6VQ0SpxxHpICwtt/tuVZ5ZzNbyHHXnUgas14U6mYy2uhjsF7CqukmOnpcuqOAQFOxsTQ1fSjDgbGN90tV1MXnJtSqVGuRpssAw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=jgZihBMK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="jgZihBMK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DAE3FC4AF19; Mon, 29 Apr 2024 13:17:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1714396631; bh=w2Ysbdlw62K0XMPywgvp3DwJa4tgzeEkrintEchxF5U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jgZihBMKVPHRsloBrY/8lzLQ/TRynZHkNsHXz/ww9wRr+Av0CpfExPcWbDbhfkym5 GLSOpLPZ/BIInWmbkT6XLEK95VsCL5UwA7qIMCl4z38Nnntf60a4HXHilFRyV9+NWK LuTwupx/d/ttfDXaO3OrDC6l/o08n62KMxBajo6OO8Ffu+6xkZMwkVDGOEt5HrNhQI c+MZiKmjpb9m5d6flH8k4wT2v4QZlqPh+dBV0ywGnVAIJaRxaXUT73aRJxBcTELrmO j/lGMUQjBBkK+x0xzhxx6WZbQtx+PWNtFsbnSySP2vFAkaEs+sBKD0ASau85NA2c0A GbLpILZGFHTPg== From: Puranjay Mohan To: Catalin Marinas , Will Deacon , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Zi Shen Lim , Xu Kuohai , Florent Revest , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Cc: puranjay12@gmail.com Subject: [PATCH bpf-next v4 2/2] bpf, arm64: inline bpf_get_smp_processor_id() helper Date: Mon, 29 Apr 2024 13:16:47 +0000 Message-Id: <20240429131647.50165-3-puranjay@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20240429131647.50165-1-puranjay@kernel.org> References: <20240429131647.50165-1-puranjay@kernel.org> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: bpf@iogearbox.net As ARM64 JIT now implements BPF_MOV64_PERCPU_REG instruction, inline bpf_get_smp_processor_id(). ARM64 uses the per-cpu variable cpu_number to store the cpu id. Here is how the BPF and ARM64 JITed assembly changes after this commit: BPF ===== BEFORE AFTER -------- ------- int cpu = bpf_get_smp_processor_id(); int cpu = bpf_get_smp_processor_id(); (85) call bpf_get_smp_processor_id#229032 (18) r0 = 0xffff800082072008 (bf) r0 = &(void __percpu *)(r0) (61) r0 = *(u32 *)(r0 +0) ARM64 JIT =========== BEFORE AFTER -------- ------- int cpu = bpf_get_smp_processor_id(); int cpu = bpf_get_smp_processor_id(); mov x10, #0xfffffffffffff4d0 mov x7, #0xffff8000ffffffff movk x10, #0x802b, lsl #16 movk x7, #0x8207, lsl #16 movk x10, #0x8000, lsl #32 movk x7, #0x2008 blr x10 mrs x10, tpidr_el1 add x7, x0, #0x0 add x7, x7, x10 ldr w7, [x7] Performance improvement using benchmark[1] BEFORE AFTER -------- ------- glob-arr-inc : 23.817 ± 0.019M/s glob-arr-inc : 24.631 ± 0.027M/s [+ 3.41%] arr-inc : 23.253 ± 0.019M/s arr-inc : 23.742 ± 0.023M/s [+ 2.10%] hash-inc : 12.258 ± 0.010M/s hash-inc : 12.625 ± 0.004M/s [+ 3.00%] [1] https://github.com/anakryiko/linux/commit/8dec900975ef Signed-off-by: Puranjay Mohan Acked-by: Andrii Nakryiko --- kernel/bpf/verifier.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 4e474ef44e9c..d0725b1c7bec 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -20273,19 +20273,33 @@ static int do_misc_fixups(struct bpf_verifier_env *env) goto next_insn; } -#ifdef CONFIG_X86_64 /* Implement bpf_get_smp_processor_id() inline. */ if (insn->imm == BPF_FUNC_get_smp_processor_id && prog->jit_requested && bpf_jit_supports_percpu_insn()) { /* BPF_FUNC_get_smp_processor_id inlining is an - * optimization, so if pcpu_hot.cpu_number is ever + * optimization, so if cpu_number_addr is ever * changed in some incompatible and hard to support * way, it's fine to back out this inlining logic */ - insn_buf[0] = BPF_MOV32_IMM(BPF_REG_0, (u32)(unsigned long)&pcpu_hot.cpu_number); - insn_buf[1] = BPF_MOV64_PERCPU_REG(BPF_REG_0, BPF_REG_0); - insn_buf[2] = BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0); - cnt = 3; + u64 cpu_number_addr; + struct bpf_insn ld_insn[2] = { + BPF_LD_IMM64(BPF_REG_0, 0) + }; + +#if defined(CONFIG_X86_64) + cpu_number_addr = (u64)&pcpu_hot.cpu_number; +#elif defined(CONFIG_ARM64) + cpu_number_addr = (u64)&cpu_number; +#else + goto next_insn; +#endif + ld_insn[0].imm = (u32)cpu_number_addr; + ld_insn[1].imm = (u32)(cpu_number_addr >> 32); + insn_buf[0] = ld_insn[0]; + insn_buf[1] = ld_insn[1]; + insn_buf[2] = BPF_MOV64_PERCPU_REG(BPF_REG_0, BPF_REG_0); + insn_buf[3] = BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0); + cnt = 4; new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt); if (!new_prog) @@ -20296,7 +20310,6 @@ static int do_misc_fixups(struct bpf_verifier_env *env) insn = new_prog->insnsi + i + delta; goto next_insn; } -#endif /* Implement bpf_get_func_arg inline. */ if (prog_type == BPF_PROG_TYPE_TRACING && insn->imm == BPF_FUNC_get_func_arg) {