From: Puranjay Mohan <puranjay@kernel.org>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: "Alexei Starovoitov" <ast@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Martin KaFai Lau" <martin.lau@linux.dev>,
"Eduard Zingerman" <eddyz87@gmail.com>,
"Song Liu" <song@kernel.org>,
"Yonghong Song" <yonghong.song@linux.dev>,
"John Fastabend" <john.fastabend@gmail.com>,
"KP Singh" <kpsingh@kernel.org>,
"Stanislav Fomichev" <sdf@google.com>,
"Hao Luo" <haoluo@google.com>, "Jiri Olsa" <jolsa@kernel.org>,
"Björn Töpel" <bjorn@kernel.org>,
"Paul Walmsley" <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Albert Ou" <aou@eecs.berkeley.edu>,
bpf@vger.kernel.org, linux-riscv@lists.infradead.org,
linux-kernel@vger.kernel.org, "Pu Lehui" <pulehui@huawei.com>
Subject: Re: [PATCH bpf-next v2 2/2] riscv, bpf: inline bpf_get_smp_processor_id()
Date: Thu, 02 May 2024 13:16:52 +0000 [thread overview]
Message-ID: <mb61pcyq45p6j.fsf@kernel.org> (raw)
In-Reply-To: <CAEf4Bzb4FYVNjuoghCcDxLgQCOT9Mb=nbjgNktqDarPHkOsuog@mail.gmail.com>
Andrii Nakryiko <andrii.nakryiko@gmail.com> writes:
> On Tue, Apr 30, 2024 at 10:59 AM Puranjay Mohan <puranjay@kernel.org> wrote:
>>
>> Inline the calls to bpf_get_smp_processor_id() in the riscv bpf jit.
>>
>> RISCV saves the pointer to the CPU's task_struct in the TP (thread
>> pointer) register. This makes it trivial to get the CPU's processor id.
>> As thread_info is the first member of task_struct, we can read the
>> processor id from TP + offsetof(struct thread_info, cpu).
>>
>> RISCV64 JIT output for `call bpf_get_smp_processor_id`
>> ======================================================
>>
>> Before After
>> -------- -------
>>
>> auipc t1,0x848c ld a5,32(tp)
>> jalr 604(t1)
>> mv a5,a0
>>
>
> Nice, great find! Would you be able to do similar inlining for x86-64
> as well? Disassembling bpf_get_smp_processor_id for x86-64 shows this:
>
> Dump of assembler code for function bpf_get_smp_processor_id:
> 0xffffffff810f91a0 <+0>: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
> 0xffffffff810f91a5 <+5>: 65 8b 05 60 79 f3 7e mov
> %gs:0x7ef37960(%rip),%eax # 0x30b0c <pcpu_hot+12>
> 0xffffffff810f91ac <+12>: 48 98 cltq
> 0xffffffff810f91ae <+14>: c3 ret
> End of assembler dump.
> We should be able to do the same in x86-64 BPF JIT. (it's actually how
> I started initially, I had a dedicated instruction reading per-cpu
> memory, but ended up with more general "calculate per-cpu address").
I feel in x86-64's case JIT can not do a (much) better job compared to the
current approach in the verifier.
On RISC-V and ARM64, JIT was able to do it better because both of these
architectures save a pointer to the task struct in a special CPU
register. As x86-64 doesn't have enough extra registers, it uses a
percpu variable to store task struct, thread_info, and the cpu
number.
P.S. - While doing this for BPF, I realized that ARM64 kernel code is
also not optimal as it is using the percpu variable and is not reading
the CPU register directly. So, I sent a patch[1] to fix it in the kernel
and get rid of the per-cpu variable in ARM64.
[1] https://lore.kernel.org/all/20240502123449.2690-2-puranjay@kernel.org/
> Anyways, great work, a small nit below.
>
> Acked-by: Andrii Nakryiko <andrii@kernel.org>
Thanks,
Puranjay
WARNING: multiple messages have this Message-ID (diff)
From: Puranjay Mohan <puranjay@kernel.org>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: "Alexei Starovoitov" <ast@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>,
"Andrii Nakryiko" <andrii@kernel.org>,
"Martin KaFai Lau" <martin.lau@linux.dev>,
"Eduard Zingerman" <eddyz87@gmail.com>,
"Song Liu" <song@kernel.org>,
"Yonghong Song" <yonghong.song@linux.dev>,
"John Fastabend" <john.fastabend@gmail.com>,
"KP Singh" <kpsingh@kernel.org>,
"Stanislav Fomichev" <sdf@google.com>,
"Hao Luo" <haoluo@google.com>, "Jiri Olsa" <jolsa@kernel.org>,
"Björn Töpel" <bjorn@kernel.org>,
"Paul Walmsley" <paul.walmsley@sifive.com>,
"Palmer Dabbelt" <palmer@dabbelt.com>,
"Albert Ou" <aou@eecs.berkeley.edu>,
bpf@vger.kernel.org, linux-riscv@lists.infradead.org,
linux-kernel@vger.kernel.org, "Pu Lehui" <pulehui@huawei.com>
Subject: Re: [PATCH bpf-next v2 2/2] riscv, bpf: inline bpf_get_smp_processor_id()
Date: Thu, 02 May 2024 13:16:52 +0000 [thread overview]
Message-ID: <mb61pcyq45p6j.fsf@kernel.org> (raw)
In-Reply-To: <CAEf4Bzb4FYVNjuoghCcDxLgQCOT9Mb=nbjgNktqDarPHkOsuog@mail.gmail.com>
Andrii Nakryiko <andrii.nakryiko@gmail.com> writes:
> On Tue, Apr 30, 2024 at 10:59 AM Puranjay Mohan <puranjay@kernel.org> wrote:
>>
>> Inline the calls to bpf_get_smp_processor_id() in the riscv bpf jit.
>>
>> RISCV saves the pointer to the CPU's task_struct in the TP (thread
>> pointer) register. This makes it trivial to get the CPU's processor id.
>> As thread_info is the first member of task_struct, we can read the
>> processor id from TP + offsetof(struct thread_info, cpu).
>>
>> RISCV64 JIT output for `call bpf_get_smp_processor_id`
>> ======================================================
>>
>> Before After
>> -------- -------
>>
>> auipc t1,0x848c ld a5,32(tp)
>> jalr 604(t1)
>> mv a5,a0
>>
>
> Nice, great find! Would you be able to do similar inlining for x86-64
> as well? Disassembling bpf_get_smp_processor_id for x86-64 shows this:
>
> Dump of assembler code for function bpf_get_smp_processor_id:
> 0xffffffff810f91a0 <+0>: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
> 0xffffffff810f91a5 <+5>: 65 8b 05 60 79 f3 7e mov
> %gs:0x7ef37960(%rip),%eax # 0x30b0c <pcpu_hot+12>
> 0xffffffff810f91ac <+12>: 48 98 cltq
> 0xffffffff810f91ae <+14>: c3 ret
> End of assembler dump.
> We should be able to do the same in x86-64 BPF JIT. (it's actually how
> I started initially, I had a dedicated instruction reading per-cpu
> memory, but ended up with more general "calculate per-cpu address").
I feel in x86-64's case JIT can not do a (much) better job compared to the
current approach in the verifier.
On RISC-V and ARM64, JIT was able to do it better because both of these
architectures save a pointer to the task struct in a special CPU
register. As x86-64 doesn't have enough extra registers, it uses a
percpu variable to store task struct, thread_info, and the cpu
number.
P.S. - While doing this for BPF, I realized that ARM64 kernel code is
also not optimal as it is using the percpu variable and is not reading
the CPU register directly. So, I sent a patch[1] to fix it in the kernel
and get rid of the per-cpu variable in ARM64.
[1] https://lore.kernel.org/all/20240502123449.2690-2-puranjay@kernel.org/
> Anyways, great work, a small nit below.
>
> Acked-by: Andrii Nakryiko <andrii@kernel.org>
Thanks,
Puranjay
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2024-05-02 13:16 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-30 17:58 [PATCH bpf-next v2 0/2] riscv, bpf: Support per-CPU insn and inline bpf_get_smp_processor_id() Puranjay Mohan
2024-04-30 17:58 ` Puranjay Mohan
2024-04-30 17:58 ` [PATCH bpf-next v2 1/2] riscv, bpf: add internal-only MOV instruction to resolve per-CPU addrs Puranjay Mohan
2024-04-30 17:58 ` Puranjay Mohan
2024-05-01 16:39 ` Andrii Nakryiko
2024-05-01 16:39 ` Andrii Nakryiko
2024-05-02 16:18 ` Björn Töpel
2024-05-02 16:18 ` Björn Töpel
2024-05-02 16:20 ` Puranjay Mohan
2024-05-02 16:20 ` Puranjay Mohan
2024-04-30 17:58 ` [PATCH bpf-next v2 2/2] riscv, bpf: inline bpf_get_smp_processor_id() Puranjay Mohan
2024-04-30 17:58 ` Puranjay Mohan
2024-04-30 19:18 ` Kumar Kartikeya Dwivedi
2024-04-30 19:18 ` Kumar Kartikeya Dwivedi
2024-05-01 16:46 ` Andrii Nakryiko
2024-05-01 16:46 ` Andrii Nakryiko
2024-05-02 13:16 ` Puranjay Mohan [this message]
2024-05-02 13:16 ` Puranjay Mohan
2024-05-02 16:03 ` Andrii Nakryiko
2024-05-02 16:03 ` Andrii Nakryiko
2024-05-02 16:19 ` Björn Töpel
2024-05-02 16:19 ` Björn Töpel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=mb61pcyq45p6j.fsf@kernel.org \
--to=puranjay@kernel.org \
--cc=andrii.nakryiko@gmail.com \
--cc=andrii@kernel.org \
--cc=aou@eecs.berkeley.edu \
--cc=ast@kernel.org \
--cc=bjorn@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=haoluo@google.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=kpsingh@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=martin.lau@linux.dev \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=pulehui@huawei.com \
--cc=sdf@google.com \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.