All of lore.kernel.org
 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 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.