bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrii Nakryiko <andrii.nakryiko@gmail.com>
To: Kui-Feng Lee <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,
	quentin@isovalent.com,  sinquersw@gmail.com, kuifeng@meta.com
Subject: Re: [PATCH bpf-next v6 3/5] bpftool: generated shadow variables for struct_ops maps.
Date: Thu, 29 Feb 2024 14:25:49 -0800	[thread overview]
Message-ID: <CAEf4BzbPG1CSC62dKcDb_=aH8pi7NEZ5zQFQxMQdOPEzZmLzvQ@mail.gmail.com> (raw)
In-Reply-To: <20240229064523.2091270-4-thinker.li@gmail.com>

On Wed, Feb 28, 2024 at 10:45 PM Kui-Feng Lee <thinker.li@gmail.com> wrote:
>
> Declares and defines a pointer of the shadow type for each struct_ops map.
>
> The code generator will create an anonymous struct type as the shadow type
> for each struct_ops map. The shadow type is translated from the original
> struct type of the map. The user of the skeleton use pointers of them to
> access the values of struct_ops maps.
>
> However, shadow types only supports certain types of fields, including
> scalar types and function pointers. Any fields of unsupported types are
> translated into an array of characters to occupy the space of the original
> field. Function pointers are translated into pointers of the struct
> bpf_program. Additionally, padding fields are generated to occupy the space
> between two consecutive fields.
>
> The pointers of shadow types of struct_osp maps are initialized when
> *__open_opts() in skeletons are called. For a map called FOO, the user can
> access it through the pointer at skel->struct_ops.FOO.
>
> Reviewed-by: Quentin Monnet <quentin@isovalent.com>
> Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com>
> ---
>  tools/bpf/bpftool/gen.c | 237 +++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 236 insertions(+), 1 deletion(-)
>

[...]

> +/* Generate the pointer of the shadow type for a struct_ops map.
> + *
> + * This function adds a pointer of the shadow type for a struct_ops map.
> + * The members of a struct_ops map can be exported through a pointer to a
> + * shadow type. The user can access these members through the pointer.
> + *
> + * A shadow type includes not all members, only members of some types.
> + * They are scalar types and function pointers. The function pointers are
> + * translated to the pointer of the struct bpf_program. The scalar types
> + * are translated to the original type without any modifiers.
> + *
> + * Unsupported types will be translated to a char array to occupy the same
> + * space as the original field, being renamed as __unsupported_*.  The user
> + * should treat these fields as opaque data.
> + */
> +static int gen_st_ops_shadow_type(const char *obj_name, struct btf *btf, const char *ident,
> +                                 const struct bpf_map *map)
> +{
> +       const struct btf_type *map_type;
> +       const char *type_name;
> +       __u32 map_type_id;
> +       int err;
> +
> +       map_type_id = bpf_map__btf_value_type_id(map);
> +       if (map_type_id == 0)
> +               return -EINVAL;
> +       map_type = btf__type_by_id(btf, map_type_id);
> +       if (!map_type)
> +               return -EINVAL;
> +
> +       type_name = btf__name_by_offset(btf, map_type->name_off);
> +
> +       printf("\t\tstruct %s_%s_%s {\n", obj_name, ident, type_name);

it should be %s__%s__%s, I fixed it up

> +
> +       err = walk_st_ops_shadow_vars(btf, ident, map_type, map_type_id);
> +       if (err)
> +               return err;
> +
> +       printf("\t\t} *%s;\n", ident);
> +
> +       return 0;
> +}
> +
> +static int gen_st_ops_shadow(const char *obj_name, struct btf *btf, struct bpf_object *obj)
> +{
> +       int err, st_ops_cnt = 0;
> +       struct bpf_map *map;
> +       char ident[256];
> +
> +       if (!btf)
> +               return 0;
> +
> +       /* Generate the pointers to shadow types of
> +        * struct_ops maps.
> +        */
> +       bpf_object__for_each_map(map, obj) {
> +               if (bpf_map__type(map) != BPF_MAP_TYPE_STRUCT_OPS)
> +                       continue;
> +               if (!get_map_ident(map, ident, sizeof(ident)))
> +                       continue;
> +
> +               if (!st_ops_cnt++)

goodness, too much operator precedence knowledge assumed, I simplified
this to what I can follow myself:

if (st_ops_cnt == 0)
    printf(...);
st_ops_cnt++;

I don't think saving one line of code is worth it.

> +                       printf("\tstruct {\n");
> +
> +               err = gen_st_ops_shadow_type(obj_name, btf, ident, map);
> +               if (err)
> +                       return err;
> +       }
> +
> +       if (st_ops_cnt)
> +               printf("\t} struct_ops;\n");
> +
> +       return 0;
> +}
> +

[...]

  reply	other threads:[~2024-02-29 22:26 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-29  6:45 [PATCH bpf-next v6 0/5] Create shadow types for struct_ops maps in skeletons Kui-Feng Lee
2024-02-29  6:45 ` [PATCH bpf-next v6 1/5] libbpf: set btf_value_type_id of struct bpf_map for struct_ops Kui-Feng Lee
2024-02-29  6:45 ` [PATCH bpf-next v6 2/5] libbpf: Convert st_ops->data to shadow type Kui-Feng Lee
2024-02-29  6:45 ` [PATCH bpf-next v6 3/5] bpftool: generated shadow variables for struct_ops maps Kui-Feng Lee
2024-02-29 22:25   ` Andrii Nakryiko [this message]
2024-03-01 18:04     ` Kui-Feng Lee
2024-02-29  6:45 ` [PATCH bpf-next v6 4/5] bpftool: Add an example for struct_ops map and shadow type Kui-Feng Lee
2024-02-29  6:45 ` [PATCH bpf-next v6 5/5] selftests/bpf: Test if shadow types work correctly Kui-Feng Lee
2024-02-29 22:30 ` [PATCH bpf-next v6 0/5] Create shadow types for struct_ops maps in skeletons patchwork-bot+netdevbpf

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='CAEf4BzbPG1CSC62dKcDb_=aH8pi7NEZ5zQFQxMQdOPEzZmLzvQ@mail.gmail.com' \
    --to=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=quentin@isovalent.com \
    --cc=sinquersw@gmail.com \
    --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;
as well as URLs for NNTP newsgroup(s).