From: Kui-Feng Lee <sinquersw@gmail.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>, thinker.li@gmail.com
Cc: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev,
song@kernel.org, kernel-team@meta.com, andrii@kernel.org,
kuifeng@meta.com
Subject: Re: [RFC bpf-next v2 0/3] Create shadow variables for struct_ops in skeletons
Date: Thu, 15 Feb 2024 18:40:37 -0800 [thread overview]
Message-ID: <65f8cbbc-0330-4df8-8e8b-79c389f82f78@gmail.com> (raw)
In-Reply-To: <CAEf4BzbwZLMD=LWqZ_kmMeyLWvpzbeLGXSgWVQPSCsdnh+mufQ@mail.gmail.com>
On 2/15/24 15:50, Andrii Nakryiko wrote:
> On Tue, Feb 13, 2024 at 6:08 PM <thinker.li@gmail.com> wrote:
>>
>> From: Kui-Feng Lee <thinker.li@gmail.com>
>>
>> This RFC is for gathering feedback/opinions on the design.
>> Based on the feedback received for v1, I made some modifications.
>>
>> == Pointers to Shadow Copies ==
>>
>> With the current implementation, the code generator will create a
>> pointer to a shadow copy of the struct_ops map for each map. For
>> instance, if we define a testmod_1 as a struct_ops map, we can access
>> its corresponding shadow variable "data" using the pointer.
>>
>> skel->struct_ops.testmod1->data
>>
>> == Shadow Info ==
>>
>> The code generator also generates a shadow info to describe the layout
>> of the data pointed to by all these pointers. For instance, the
>> following shadow info describes the layout of a struct_ops map called
>> testmod_1, which has 3 members: test_1, test_2, and data.
>>
>> static struct bpf_struct_ops_member_info member_info_testmod_1[] = {
>> {
>> .name = "test_1",
>> .offset = .....,
>> .size = .....,
>> },
>> {
>> .name = "test_2",
>> .offset = .....,
>> .size = .....,
>> },
>> {
>> .name = "data",
>> .offset = .....,
>> .size = .....,
>> },
>> };
>> static struct bpf_struct_ops_map_info map_info[] = {
>> {
>> .name = "testmod_1",
>> .members = member_info_testmod_1,
>> .cnt = ARRAY_SIZE(member_info_testmod_1),
>> .data_size = sizeof(struct_ops->testmod_1),
>> },
>> };
>> static struct bpf_struct_ops_shadow_info shadow_info = {
>> .maps = map_info,
>> .cnt = ARRAY_SIZE(map_info),
>> };
>>
>> A shadow info describes the layout of the shadow copies of all
>> struct_ops maps included in a skeleton. (Defined in *__shadow_info())
>
> I must be missing something, but libbpf knows the layout of struct_ops
> struct through BTF, why do we need all these descriptors?
I explain it in the response for part 1.
>
>>
>> == libbpf Creates Shadow Copies ==
>>
>> This shadow info should be passed to bpf_object__open_skeleton() as a
>> part of "opts" so that libbpf can create shadow copies with the layout
>> described by the shadow info. For now, *__open() in the skeleton will
>> automatically pass the shadow info to bpf_object__open_skeleton(),
>> looking like the following example.
>>
>> static inline struct struct_ops_module *
>> struct_ops_module__open(void)
>> {
>> DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts);
>>
>> opts.struct_ops_shadow = struct_ops_module__shadow_info();
>>
>> return struct_ops_module__open_opts(*** BLURB HERE ***opts);
>> }
>>
>> The function bpf_map__initial_value() will return the shadow copy that
>> is created based on the received shadow info. Therefore, in the
>> function *__open_opts() in the skeleton, the pointers to shadow copies
>> will be initialized with the values returned from
>> bpf_map__initial_value(). For instance,
>>
>> obj->struct_ops.testmod_1 =
>> bpf_map__initial_value(obj->maps.testmod_1, NULL);
>>
>
> I also don't get why you need to allocate some extra "shadow memory"
> if we already have struct bpf_struct_ops->data pointer malloc()'ed
> during bpf_map initialization, and its size matches exactly the
> struct_ops's type size.
I assume that the alignments & padding of BPF and the user space
programs are different. (Check the response for part 1 as well)
>
>> This line of code will be included in the *__open_opts() function. If
>> the opts.struct_ops_shadow is not set, bpf_map__initial_value() will
>> return a NULL.
>>
>> ========================================
>> DESCRIPTION form v1
>> ========================================
>>
>
> you probably don't need to keep cover letter from previous versions if
> they are not relevant anymore
>
> [...]
Sure!
It explains what the feature is and how to use this feature.
So, I keep it here for people just found this discussion.
>
>>
>> ---
>>
>> v1: https://lore.kernel.org/all/20240124224130.859921-1-thinker.li@gmail.com/
>>
>> Kui-Feng Lee (3):
>> libbpf: Create a shadow copy for each struct_ops map if necessary.
>> bpftool: generated shadow variables for struct_ops maps.
>> selftests/bpf: Test if shadow variables work.
>>
>> tools/bpf/bpftool/gen.c | 358 +++++++++++++++++-
>> tools/lib/bpf/libbpf.c | 195 +++++++++-
>> tools/lib/bpf/libbpf.h | 34 +-
>> tools/lib/bpf/libbpf.map | 1 +
>> tools/lib/bpf/libbpf_internal.h | 1 +
>> .../selftests/bpf/bpf_testmod/bpf_testmod.c | 6 +-
>> .../selftests/bpf/bpf_testmod/bpf_testmod.h | 1 +
>> .../bpf/prog_tests/test_struct_ops_module.c | 16 +-
>> .../selftests/bpf/progs/struct_ops_module.c | 8 +
>> 9 files changed, 596 insertions(+), 24 deletions(-)
>>
>> --
>> 2.34.1
>>
next prev parent reply other threads:[~2024-02-16 2:40 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-14 2:08 [RFC bpf-next v2 0/3] Create shadow variables for struct_ops in skeletons thinker.li
2024-02-14 2:08 ` [RFC bpf-next v2 1/3] libbpf: Create a shadow copy for each struct_ops map if necessary thinker.li
2024-02-15 23:55 ` Andrii Nakryiko
2024-02-16 2:35 ` Kui-Feng Lee
2024-02-16 16:52 ` Andrii Nakryiko
2024-02-16 17:12 ` Kui-Feng Lee
2024-02-14 2:08 ` [RFC bpf-next v2 2/3] bpftool: generated shadow variables for struct_ops maps thinker.li
2024-02-14 2:08 ` [RFC bpf-next v2 3/3] selftests/bpf: Test if shadow variables work thinker.li
2024-02-15 23:50 ` [RFC bpf-next v2 0/3] Create shadow variables for struct_ops in skeletons Andrii Nakryiko
2024-02-16 2:40 ` Kui-Feng Lee [this message]
2024-02-16 16:54 ` Andrii Nakryiko
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=65f8cbbc-0330-4df8-8e8b-79c389f82f78@gmail.com \
--to=sinquersw@gmail.com \
--cc=andrii.nakryiko@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=kernel-team@meta.com \
--cc=kuifeng@meta.com \
--cc=martin.lau@linux.dev \
--cc=song@kernel.org \
--cc=thinker.li@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox