BPF List
 help / color / mirror / Atom feed
From: Kui-Feng Lee <sinquersw@gmail.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>,
	Kui-Feng Lee <kuifeng@meta.com>
Cc: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev,
	song@kernel.org, kernel-team@meta.com, andrii@kernel.org,
	sdf@google.com
Subject: Re: [PATCH bpf-next v7 5/8] bpf: Update the struct_ops of a bpf_link.
Date: Fri, 17 Mar 2023 17:41:14 -0700	[thread overview]
Message-ID: <e40829fe-bb00-9296-3b24-2412d72f7eaf@gmail.com> (raw)
In-Reply-To: <CAEf4BzY77ntrzDK+YdFY56hhLaR2Nh3UuvR9rMU68BCPXsc1bg@mail.gmail.com>



On 3/17/23 15:27, Andrii Nakryiko wrote:
> On Wed, Mar 15, 2023 at 7:37 PM Kui-Feng Lee <kuifeng@meta.com> wrote:
>>
>> By improving the BPF_LINK_UPDATE command of bpf(), it should allow you
>> to conveniently switch between different struct_ops on a single
>> bpf_link. This would enable smoother transitions from one struct_ops
>> to another.
>>
>> The struct_ops maps passing along with BPF_LINK_UPDATE should have the
>> BPF_F_LINK flag.
>>
>> Signed-off-by: Kui-Feng Lee <kuifeng@meta.com>
>> ---
>>   include/linux/bpf.h            |  2 ++
>>   include/uapi/linux/bpf.h       |  8 +++++--
>>   kernel/bpf/bpf_struct_ops.c    | 38 ++++++++++++++++++++++++++++++++++
>>   kernel/bpf/syscall.c           | 20 ++++++++++++++++++
>>   net/bpf/bpf_dummy_struct_ops.c |  6 ++++++
>>   net/ipv4/bpf_tcp_ca.c          |  6 ++++++
>>   tools/include/uapi/linux/bpf.h |  8 +++++--
>>   7 files changed, 84 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
>> index 455b14bf8f28..56e6ab7559ef 100644
>> --- a/include/linux/bpf.h
>> +++ b/include/linux/bpf.h
>> @@ -1474,6 +1474,7 @@ struct bpf_link_ops {
>>          void (*show_fdinfo)(const struct bpf_link *link, struct seq_file *seq);
>>          int (*fill_link_info)(const struct bpf_link *link,
>>                                struct bpf_link_info *info);
>> +       int (*update_map)(struct bpf_link *link, struct bpf_map *new_map);
>>   };
>>
>>   struct bpf_tramp_link {
>> @@ -1516,6 +1517,7 @@ struct bpf_struct_ops {
>>                             void *kdata, const void *udata);
>>          int (*reg)(void *kdata);
>>          void (*unreg)(void *kdata);
>> +       int (*update)(void *kdata, void *old_kdata);
>>          int (*validate)(void *kdata);
>>          const struct btf_type *type;
>>          const struct btf_type *value_type;
>> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
>> index 42f40ee083bf..24e1dec4ad97 100644
>> --- a/include/uapi/linux/bpf.h
>> +++ b/include/uapi/linux/bpf.h
>> @@ -1555,8 +1555,12 @@ union bpf_attr {
>>
>>          struct { /* struct used by BPF_LINK_UPDATE command */
>>                  __u32           link_fd;        /* link fd */
>> -               /* new program fd to update link with */
>> -               __u32           new_prog_fd;
>> +               union {
>> +                       /* new program fd to update link with */
>> +                       __u32           new_prog_fd;
>> +                       /* new struct_ops map fd to update link with */
>> +                       __u32           new_map_fd;
>> +               };
>>                  __u32           flags;          /* extra flags */
>>                  /* expected link's program fd; is specified only if
>>                   * BPF_F_REPLACE flag is set in flags */
>> diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c
>> index 8ce6c7581ca3..5a9e10b92423 100644
>> --- a/kernel/bpf/bpf_struct_ops.c
>> +++ b/kernel/bpf/bpf_struct_ops.c
>> @@ -807,10 +807,48 @@ static int bpf_struct_ops_map_link_fill_link_info(const struct bpf_link *link,
>>          return 0;
>>   }
>>
>> +static int bpf_struct_ops_map_link_update(struct bpf_link *link, struct bpf_map *new_map)
>> +{
>> +       struct bpf_struct_ops_map *st_map, *old_st_map;
>> +       struct bpf_struct_ops_link *st_link;
>> +       struct bpf_map *old_map;
>> +       int err = 0;
>> +
>> +       st_link = container_of(link, struct bpf_struct_ops_link, link);
>> +       st_map = container_of(new_map, struct bpf_struct_ops_map, map);
>> +
>> +       if (!bpf_struct_ops_valid_to_reg(new_map))
>> +               return -EINVAL;
>> +
>> +       mutex_lock(&update_mutex);
>> +
>> +       old_map = rcu_dereference_protected(st_link->map, lockdep_is_held(&update_mutex));
>> +       old_st_map = container_of(old_map, struct bpf_struct_ops_map, map);
>> +       /* The new and old struct_ops must be the same type. */
>> +       if (st_map->st_ops != old_st_map->st_ops) {
>> +               err = -EINVAL;
>> +               goto err_out;
>> +       }
>> +
>> +       err = st_map->st_ops->update(st_map->kvalue.data, old_st_map->kvalue.data);
>> +       if (err)
>> +               goto err_out;
>> +
>> +       bpf_map_inc(new_map);
>> +       rcu_assign_pointer(st_link->map, new_map);
>> +       bpf_map_put(old_map);
>> +
>> +err_out:
>> +       mutex_unlock(&update_mutex);
>> +
>> +       return err;
>> +}
>> +
>>   static const struct bpf_link_ops bpf_struct_ops_map_lops = {
>>          .dealloc = bpf_struct_ops_map_link_dealloc,
>>          .show_fdinfo = bpf_struct_ops_map_link_show_fdinfo,
>>          .fill_link_info = bpf_struct_ops_map_link_fill_link_info,
>> +       .update_map = bpf_struct_ops_map_link_update,
>>   };
>>
>>   int bpf_struct_ops_link_create(union bpf_attr *attr)
>> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
>> index 5a45e3bf34e2..6fa10d108278 100644
>> --- a/kernel/bpf/syscall.c
>> +++ b/kernel/bpf/syscall.c
>> @@ -4676,6 +4676,21 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
>>          return ret;
>>   }
>>
>> +static int link_update_map(struct bpf_link *link, union bpf_attr *attr)
>> +{
>> +       struct bpf_map *new_map;
>> +       int ret = 0;
>> +
>> +       new_map = bpf_map_get(attr->link_update.new_map_fd);
>> +       if (IS_ERR(new_map))
>> +               return -EINVAL;
> 
> I was expecting a check for the BPF_F_LINK flag here. Isn't it
> necessary to verify that here?


link->ops->update_map != NULL implies BPF_F_LINK.  So, it doesn't do
additional check for BPF_F_LINK here.


> 
> 
> 
>> +
>> +       ret = link->ops->update_map(link, new_map);
>> +
>> +       bpf_map_put(new_map);
>> +       return ret;
>> +}
>> +
>>   #define BPF_LINK_UPDATE_LAST_FIELD link_update.old_prog_fd
>>
> 
> [...]

  reply	other threads:[~2023-03-18  0:41 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-16  2:36 [PATCH bpf-next v7 0/8] Transit between BPF TCP congestion controls Kui-Feng Lee
2023-03-16  2:36 ` [PATCH bpf-next v7 1/8] bpf: Retire the struct_ops map kvalue->refcnt Kui-Feng Lee
2023-03-17 16:47   ` Martin KaFai Lau
2023-03-17 20:41     ` Kui-Feng Lee
2023-03-16  2:36 ` [PATCH bpf-next v7 2/8] net: Update an existing TCP congestion control algorithm Kui-Feng Lee
2023-03-17 15:23   ` Daniel Borkmann
2023-03-17 17:18     ` Martin KaFai Lau
2023-03-17 17:23       ` Daniel Borkmann
2023-03-17 21:46         ` Kui-Feng Lee
2023-03-17 23:07     ` Kui-Feng Lee
2023-03-16  2:36 ` [PATCH bpf-next v7 3/8] bpf: Create links for BPF struct_ops maps Kui-Feng Lee
2023-03-17 18:10   ` Martin KaFai Lau
2023-03-17 20:52     ` Kui-Feng Lee
2023-03-16  2:36 ` [PATCH bpf-next v7 4/8] libbpf: Create a bpf_link in bpf_map__attach_struct_ops() Kui-Feng Lee
2023-03-17 18:44   ` Martin KaFai Lau
2023-03-17 21:00     ` Kui-Feng Lee
2023-03-17 22:23   ` Andrii Nakryiko
2023-03-17 23:48     ` Kui-Feng Lee
2023-03-16  2:36 ` [PATCH bpf-next v7 5/8] bpf: Update the struct_ops of a bpf_link Kui-Feng Lee
2023-03-17 19:23   ` Martin KaFai Lau
2023-03-17 21:39     ` Kui-Feng Lee
2023-03-18  1:11     ` Kui-Feng Lee
2023-03-18  5:38       ` Martin KaFai Lau
2023-03-17 22:27   ` Andrii Nakryiko
2023-03-18  0:41     ` Kui-Feng Lee [this message]
2023-03-16  2:36 ` [PATCH bpf-next v7 6/8] libbpf: Update a bpf_link with another struct_ops Kui-Feng Lee
2023-03-17 19:42   ` Martin KaFai Lau
2023-03-17 21:40     ` Kui-Feng Lee
2023-03-17 22:33   ` Andrii Nakryiko
2023-03-18  1:17     ` Kui-Feng Lee
2023-03-16  2:36 ` [PATCH bpf-next v7 7/8] libbpf: Use .struct_ops.link section to indicate a struct_ops with a link Kui-Feng Lee
2023-03-17 22:35   ` Andrii Nakryiko
2023-03-16  2:36 ` [PATCH bpf-next v7 8/8] selftests/bpf: Test switching TCP Congestion Control algorithms Kui-Feng Lee

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=e40829fe-bb00-9296-3b24-2412d72f7eaf@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=sdf@google.com \
    --cc=song@kernel.org \
    /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