From: Martin KaFai Lau <martin.lau@linux.dev>
To: Kuifeng Lee <sinquersw@gmail.com>
Cc: Kui-Feng Lee <thinker.li@gmail.com>,
bpf@vger.kernel.org, ast@kernel.org, song@kernel.org,
kernel-team@meta.com, andrii@kernel.org, kuifeng@meta.com
Subject: Re: [PATCH bpf-next v6 2/8] bpf: enable detaching links of struct_ops objects.
Date: Wed, 29 May 2024 15:38:06 -0700 [thread overview]
Message-ID: <c995be4c-eac8-490c-a220-7f19794c3420@linux.dev> (raw)
In-Reply-To: <CAHE2DV1R8VwbVfZgcmzvJWdtnAaHyzC_KboUO_LynT8_-z71ZQ@mail.gmail.com>
On 5/29/24 8:04 AM, Kuifeng Lee wrote:
> On Tue, May 28, 2024 at 11:17 PM Martin KaFai Lau <martin.lau@linux.dev> wrote:
>>
>> On 5/24/24 3:30 PM, Kui-Feng Lee wrote:
>>> +static int bpf_struct_ops_map_link_detach(struct bpf_link *link)
>>> +{
>>> + struct bpf_struct_ops_link *st_link = container_of(link, struct bpf_struct_ops_link, link);
>>> + struct bpf_struct_ops_map *st_map;
>>> + struct bpf_map *map;
>>> +
>>> + mutex_lock(&update_mutex);
>>
>> update_mutex is needed to detach.
>>
>>> +
>>> + map = rcu_dereference_protected(st_link->map, lockdep_is_held(&update_mutex));
>>> + if (!map) {
>>> + mutex_unlock(&update_mutex);
>>> + return 0;
>>> + }
>>> + st_map = container_of(map, struct bpf_struct_ops_map, map);
>>> +
>>> + st_map->st_ops_desc->st_ops->unreg(&st_map->kvalue.data, link);
>>> +
>>> + rcu_assign_pointer(st_link->map, NULL);
>>> + /* Pair with bpf_map_get() in bpf_struct_ops_link_create() or
>>> + * bpf_map_inc() in bpf_struct_ops_map_link_update().
>>> + */
>>> + bpf_map_put(&st_map->map);
>>> +
>>> + mutex_unlock(&update_mutex);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> static const struct bpf_link_ops bpf_struct_ops_map_lops = {
>>> .dealloc = bpf_struct_ops_map_link_dealloc,
>>> + .detach = bpf_struct_ops_map_link_detach,
>>> .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,
>>> @@ -1176,13 +1208,22 @@ int bpf_struct_ops_link_create(union bpf_attr *attr)
>>> if (err)
>>> goto err_out;
>>>
>>> + /* Init link->map before calling reg() in case being detached
>>> + * immediately.
>>> + */
>>
>> With update_mutex held in link_create here, the parallel detach can still happen
>> before the link is fully initialized (the link->map pointer here in particular)?
>>
>>> + RCU_INIT_POINTER(link->map, map);
>>> +
>>> + mutex_lock(&update_mutex);
>>> err = st_map->st_ops_desc->st_ops->reg(st_map->kvalue.data, &link->link);
>>> if (err) {
>>> + RCU_INIT_POINTER(link->map, NULL);
>>
>> I was hoping by holding the the update_mutex, it can avoid this link->map init
>> dance, like RCU_INIT_POINTER(link->map, map) above and then resetting here on
>> the error case.
>>
>>> + mutex_unlock(&update_mutex);
>>> bpf_link_cleanup(&link_primer);
>>> + /* The link has been free by bpf_link_cleanup() */
>>> link = NULL;
>>> goto err_out;
>>> }
>>> - RCU_INIT_POINTER(link->map, map);
>>
>> If only init link->map once here like the existing code (and the init is
>> protected by the update_mutex), the subsystem should not be able to detach until
>> the link->map is fully initialized.
>>
>> or I am missing something obvious. Can you explain why this link->map init dance
>> is still needed?
>
> Ok, I get what you mean.
>
> I will move RCU_INIT_POINTER() back to its original place, and move the check
> on the value of "err" to the place after mutext_unlock().
The RCU_INIT_POINTER(link->map, map) needs to be done with update_mutex held and
it should be init after the err check, so the err check needs to be inside
update_mutex lock also.
Something like this (untested):
mutex_lock(&update_mutex);
err = st_map->st_ops_desc->st_ops->reg(st_map->kvalue.data, &link->link);
if (err) {
mutex_unlock(&update_mutex);
bpf_link_cleanup(&link_primer);
link = NULL;
goto err_out;
}
RCU_INIT_POINTER(link->map, map);
mutex_unlock(&update_mutex);
>
>>
>>> + mutex_unlock(&update_mutex);
>>
next prev parent reply other threads:[~2024-05-29 22:38 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-24 22:30 [PATCH bpf-next v6 0/8] Notify user space when a struct_ops object is detached/unregistered Kui-Feng Lee
2024-05-24 22:30 ` [PATCH bpf-next v6 1/8] bpf: pass bpf_struct_ops_link to callbacks in bpf_struct_ops Kui-Feng Lee
2024-05-24 22:30 ` [PATCH bpf-next v6 2/8] bpf: enable detaching links of struct_ops objects Kui-Feng Lee
2024-05-29 6:17 ` Martin KaFai Lau
2024-05-29 15:04 ` Kuifeng Lee
2024-05-29 22:38 ` Martin KaFai Lau [this message]
2024-05-29 23:26 ` Kuifeng Lee
2024-05-24 22:30 ` [PATCH bpf-next v6 3/8] bpf: support epoll from bpf struct_ops links Kui-Feng Lee
2024-05-24 22:30 ` [PATCH bpf-next v6 4/8] bpf: export bpf_link_inc_not_zero Kui-Feng Lee
2024-05-24 22:30 ` [PATCH bpf-next v6 5/8] selftests/bpf: test struct_ops with epoll Kui-Feng Lee
2024-05-29 22:26 ` Martin KaFai Lau
2024-05-24 22:30 ` [PATCH bpf-next v6 6/8] selftests/bpf: detach a struct_ops link from the subsystem managing it Kui-Feng Lee
2024-05-29 21:51 ` Martin KaFai Lau
[not found] ` <CAHE2DV0RBf9JbkmngsdKdER5F2KmUXwY_JH44Z09DsY0VNa37A@mail.gmail.com>
2024-05-30 17:53 ` Martin KaFai Lau
2024-05-30 19:34 ` Kuifeng Lee
2024-05-30 19:42 ` Kuifeng Lee
2024-05-30 20:19 ` Martin KaFai Lau
2024-05-24 22:30 ` [PATCH bpf-next v6 7/8] selftests/bpf: make sure bpf_testmod handling racing link destroying well Kui-Feng Lee
2024-05-24 22:30 ` [PATCH bpf-next v6 8/8] bpftool: Change pid_iter.bpf.c to comply with the change of bpf_link_fops 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=c995be4c-eac8-490c-a220-7f19794c3420@linux.dev \
--to=martin.lau@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--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.