From: Martin KaFai Lau <martin.lau@linux.dev>
To: thinker.li@gmail.com
Cc: sinquersw@gmail.com, kuifeng@meta.com, bpf@vger.kernel.org,
ast@kernel.org, song@kernel.org, kernel-team@meta.com,
andrii@kernel.org, drosen@google.com
Subject: Re: [PATCH bpf-next v5 3/9] bpf: hold module for bpf_struct_ops_map.
Date: Wed, 18 Oct 2023 17:36:10 -0700 [thread overview]
Message-ID: <a245d4c4-6eb0-ce54-41aa-4f8c8acf3051@linux.dev> (raw)
In-Reply-To: <20231017162306.176586-4-thinker.li@gmail.com>
On 10/17/23 9:23 AM, thinker.li@gmail.com wrote:
> From: Kui-Feng Lee <thinker.li@gmail.com>
>
> To ensure that a module remains accessible whenever a struct_ops object of
> a struct_ops type provided by the module is still in use.
>
> Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com>
> ---
> include/linux/bpf.h | 1 +
> kernel/bpf/bpf_struct_ops.c | 21 ++++++++++++++++++---
> 2 files changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index e6a648af2daa..1e1647c8b0ce 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -1627,6 +1627,7 @@ struct bpf_struct_ops {
> int (*update)(void *kdata, void *old_kdata);
> int (*validate)(void *kdata);
> struct btf *btf;
> + struct module *owner;
> const struct btf_type *type;
> const struct btf_type *value_type;
> const char *name;
> diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c
> index 7758f66ad734..b561245fe235 100644
> --- a/kernel/bpf/bpf_struct_ops.c
> +++ b/kernel/bpf/bpf_struct_ops.c
> @@ -112,6 +112,7 @@ static const struct btf_type *module_type;
>
> static void bpf_struct_ops_init_one(struct bpf_struct_ops *st_ops,
> struct btf *btf,
> + struct module *owner,
> struct bpf_verifier_log *log)
> {
> const struct btf_member *member;
> @@ -186,6 +187,7 @@ static void bpf_struct_ops_init_one(struct bpf_struct_ops *st_ops,
> st_ops->name);
> } else {
> st_ops->btf = btf;
> + st_ops->owner = owner;
I suspect it will turn out to be just "st_ops->owner = st_ops->owner;" in a
latter patch. st_ops->owner should have already been initialized (with
THIS_MODULE?).
> st_ops->type_id = type_id;
> st_ops->type = t;
> st_ops->value_id = value_id;
> @@ -193,6 +195,7 @@ static void bpf_struct_ops_init_one(struct bpf_struct_ops *st_ops,
> value_id);
> }
> }
> +
nit. extra newline.
> }
>
> void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log)
> @@ -215,7 +218,7 @@ void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log)
>
> for (i = 0; i < ARRAY_SIZE(bpf_struct_ops); i++) {
> st_ops = bpf_struct_ops[i];
> - bpf_struct_ops_init_one(st_ops, btf, log);
> + bpf_struct_ops_init_one(st_ops, btf, NULL, log);
> }
> }
>
> @@ -630,6 +633,7 @@ static void __bpf_struct_ops_map_free(struct bpf_map *map)
> bpf_jit_uncharge_modmem(PAGE_SIZE);
> }
> bpf_map_area_free(st_map->uvalue);
> + module_put(st_map->st_ops->owner);
> bpf_map_area_free(st_map);
> }
>
> @@ -676,9 +680,18 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
> if (!st_ops)
> return ERR_PTR(-ENOTSUPP);
>
> + /* If st_ops->owner is NULL, it means the struct_ops is
> + * statically defined in the kernel. We don't need to
> + * take a refcount on it.
> + */
> + if (st_ops->owner && !btf_try_get_module(st_ops->btf))
This just came to my mind. Is the module refcnt needed during map alloc/free or
it could be done during the reg/unreg instead?
> + return ERR_PTR(-EINVAL);
> +
> vt = st_ops->value_type;
> - if (attr->value_size != vt->size)
> + if (attr->value_size != vt->size) {
> + module_put(st_ops->owner);
> return ERR_PTR(-EINVAL);
> + }
>
> t = st_ops->type;
>
> @@ -689,8 +702,10 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
> (vt->size - sizeof(struct bpf_struct_ops_value));
>
> st_map = bpf_map_area_alloc(st_map_size, NUMA_NO_NODE);
> - if (!st_map)
> + if (!st_map) {
> + module_put(st_ops->owner);
> return ERR_PTR(-ENOMEM);
> + }
>
> st_map->st_ops = st_ops;
> map = &st_map->map;
next prev parent reply other threads:[~2023-10-19 0:36 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-17 16:22 [PATCH bpf-next v5 0/9] Registrating struct_ops types from modules thinker.li
2023-10-17 16:22 ` [PATCH bpf-next v5 1/9] bpf: refactory struct_ops type initialization to a function thinker.li
2023-10-17 16:22 ` [PATCH bpf-next v5 2/9] bpf: add struct_ops_tab to btf thinker.li
2023-10-19 0:00 ` Martin KaFai Lau
2023-10-19 0:33 ` Kui-Feng Lee
2023-10-19 2:28 ` Martin KaFai Lau
2023-10-19 16:15 ` Kui-Feng Lee
2023-10-17 16:23 ` [PATCH bpf-next v5 3/9] bpf: hold module for bpf_struct_ops_map thinker.li
2023-10-19 0:36 ` Martin KaFai Lau [this message]
2023-10-19 16:29 ` Kui-Feng Lee
2023-10-20 5:07 ` Kui-Feng Lee
2023-10-20 21:37 ` Martin KaFai Lau
2023-10-20 22:28 ` Kui-Feng Lee
2023-10-17 16:23 ` [PATCH bpf-next v5 4/9] bpf: validate value_type thinker.li
2023-10-17 16:23 ` [PATCH bpf-next v5 5/9] bpf: pass attached BTF to the bpf_struct_ops subsystem thinker.li
2023-10-17 16:23 ` [PATCH bpf-next v5 6/9] bpf, net: switch to dynamic registration thinker.li
2023-10-19 1:49 ` Martin KaFai Lau
2023-10-20 15:12 ` Kui-Feng Lee
2023-10-20 17:53 ` Kui-Feng Lee
2023-10-17 16:23 ` [PATCH bpf-next v5 7/9] libbpf: Find correct module BTFs for struct_ops maps and progs thinker.li
2023-10-17 21:49 ` Andrii Nakryiko
2023-10-18 2:25 ` Kui-Feng Lee
2023-10-19 2:43 ` Martin KaFai Lau
2023-10-19 16:31 ` Kui-Feng Lee
2023-10-17 16:23 ` [PATCH bpf-next v5 8/9] bpf: export btf_ctx_access to modules thinker.li
2023-10-17 16:23 ` [PATCH bpf-next v5 9/9] selftests/bpf: test case for register_bpf_struct_ops() thinker.li
2023-10-17 18:03 ` kernel test robot
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=a245d4c4-6eb0-ce54-41aa-4f8c8acf3051@linux.dev \
--to=martin.lau@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=drosen@google.com \
--cc=kernel-team@meta.com \
--cc=kuifeng@meta.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 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.