BPF List
 help / color / mirror / Atom feed
From: Martin KaFai Lau <martin.lau@linux.dev>
To: thinker.li@gmail.com
Cc: bpf@vger.kernel.org, ast@kernel.org, kernel-team@meta.com,
	andrii@kernel.org, sinquersw@gmail.com, kuifeng@meta.com
Subject: Re: [PATCH bpf-next v7 6/8] selftests/bpf: detach a struct_ops link from the subsystem managing it.
Date: Thu, 30 May 2024 16:02:04 -0700	[thread overview]
Message-ID: <08348ecb-5c6d-4937-8bfd-13e2b4d28260@linux.dev> (raw)
In-Reply-To: <20240530065946.979330-7-thinker.li@gmail.com>

On 5/29/24 11:59 PM, thinker.li@gmail.com wrote:
> From: Kui-Feng Lee <thinker.li@gmail.com>
> 
> Not only a user space program can detach a struct_ops link, the subsystem
> managing a link can also detach the link. This patch adds a kfunc to
> simulate detaching a link by the subsystem managing it and makes sure user
> space programs get notified through epoll.
> 
> Signed-off-by: Kui-Feng Lee <thinker.li@gmail.com>
> ---
>   .../selftests/bpf/bpf_testmod/bpf_testmod.c   | 42 ++++++++++++
>   .../bpf/bpf_testmod/bpf_testmod_kfunc.h       |  1 +
>   .../bpf/prog_tests/test_struct_ops_module.c   | 67 +++++++++++++++++++
>   .../selftests/bpf/progs/struct_ops_detach.c   |  7 ++
>   4 files changed, 117 insertions(+)
> 
> diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
> index 0a09732cde4b..2b3a89609b7e 100644
> --- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
> +++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
> @@ -744,6 +744,38 @@ __bpf_kfunc int bpf_kfunc_call_kernel_getpeername(struct addr_args *args)
>   	return err;
>   }
>   
> +static DEFINE_SPINLOCK(detach_lock);
> +static struct bpf_link *link_to_detach;
> +
> +__bpf_kfunc int bpf_dummy_do_link_detach(void)
> +{
> +	struct bpf_link *link;
> +	int ret = -ENOENT;
> +
> +	/* A subsystem must ensure that a link is valid when detaching the
> +	 * link. In order to achieve that, the subsystem may need to obtain
> +	 * a lock to safeguard a table that holds the pointer to the link
> +	 * being detached. However, the subsystem cannot invoke
> +	 * link->ops->detach() while holding the lock because other tasks
> +	 * may be in the process of unregistering, which could lead to
> +	 * acquiring the same lock and causing a deadlock. This is why
> +	 * bpf_link_inc_not_zero() is used to maintain the link's validity.
> +	 */
> +	spin_lock(&detach_lock);
> +	link = link_to_detach;
> +	/* Make sure the link is still valid by increasing its refcnt */
> +	if (link && IS_ERR(bpf_link_inc_not_zero(link)))
> +		link = NULL;
> +	spin_unlock(&detach_lock);
> +
> +	if (link) {
> +		ret = link->ops->detach(link);
> +		bpf_link_put(link);
> +	}
> +
> +	return ret;
> +}
> +
>   BTF_KFUNCS_START(bpf_testmod_check_kfunc_ids)
>   BTF_ID_FLAGS(func, bpf_testmod_test_mod_kfunc)
>   BTF_ID_FLAGS(func, bpf_kfunc_call_test1)
> @@ -780,6 +812,7 @@ BTF_ID_FLAGS(func, bpf_kfunc_call_kernel_sendmsg, KF_SLEEPABLE)
>   BTF_ID_FLAGS(func, bpf_kfunc_call_sock_sendmsg, KF_SLEEPABLE)
>   BTF_ID_FLAGS(func, bpf_kfunc_call_kernel_getsockname, KF_SLEEPABLE)
>   BTF_ID_FLAGS(func, bpf_kfunc_call_kernel_getpeername, KF_SLEEPABLE)
> +BTF_ID_FLAGS(func, bpf_dummy_do_link_detach)
>   BTF_KFUNCS_END(bpf_testmod_check_kfunc_ids)
>   
>   static int bpf_testmod_ops_init(struct btf *btf)
> @@ -832,11 +865,20 @@ static int bpf_dummy_reg(void *kdata, struct bpf_link *link)
>   	if (ops->test_2)
>   		ops->test_2(4, ops->data);
>   
> +	spin_lock(&detach_lock);
> +	if (!link_to_detach)
> +		link_to_detach = link;
> +	spin_unlock(&detach_lock);
> +
>   	return 0;
>   }

[ ... ]

>   void serial_test_struct_ops_module(void)
>   {
>   	if (test__start_subtest("struct_ops_load"))
> @@ -311,5 +376,7 @@ void serial_test_struct_ops_module(void)
>   		test_struct_ops_forgotten_cb();
>   	if (test__start_subtest("test_detach_link"))
>   		test_detach_link();
> +	if (test__start_subtest("test_subsystem_detach"))
> +		test_subsystem_detach();

A summary of the offline discussion with Kui-Feng.

* serial_ is currently unnecessary for the test_struct_ops_module. It was a 
leftover because of a negative test case that was removed in the later revision 
of the initial struct_ops kmod support.
* Better don't renew this currently unnecessary serial_ requirement.
* The link_to_detach should only be initialized for a particular test. This can 
be done by checking a poison value in the bpf_testmod_ops.
* The reg() should complain and error out if the link_to_detach has already been 
set.

Patch 6 and 7 needs to be a followup. Path 1-5 and 8 look good and are applied. 
Thanks.



  reply	other threads:[~2024-05-30 23:02 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-30  6:59 [PATCH bpf-next v7 0/8] Notify user space when a struct_ops object is detached/unregistered thinker.li
2024-05-30  6:59 ` [PATCH bpf-next v7 1/8] bpf: pass bpf_struct_ops_link to callbacks in bpf_struct_ops thinker.li
2024-05-30  6:59 ` [PATCH bpf-next v7 2/8] bpf: enable detaching links of struct_ops objects thinker.li
2024-05-30  6:59 ` [PATCH bpf-next v7 3/8] bpf: support epoll from bpf struct_ops links thinker.li
2024-05-30  6:59 ` [PATCH bpf-next v7 4/8] bpf: export bpf_link_inc_not_zero thinker.li
2024-05-30  6:59 ` [PATCH bpf-next v7 5/8] selftests/bpf: test struct_ops with epoll thinker.li
2024-05-30  6:59 ` [PATCH bpf-next v7 6/8] selftests/bpf: detach a struct_ops link from the subsystem managing it thinker.li
2024-05-30 23:02   ` Martin KaFai Lau [this message]
2024-05-30  6:59 ` [PATCH bpf-next v7 7/8] selftests/bpf: make sure bpf_testmod handling racing link destroying well thinker.li
2024-05-30  6:59 ` [PATCH bpf-next v7 8/8] bpftool: Change pid_iter.bpf.c to comply with the change of bpf_link_fops thinker.li
2024-05-30 22:40 ` [PATCH bpf-next v7 0/8] Notify user space when a struct_ops object is detached/unregistered 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=08348ecb-5c6d-4937-8bfd-13e2b4d28260@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=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