* [RFC PATCH] nfsd: convert the nfsd_users to atomic_t
@ 2025-06-18 10:41 chenxiaosong
2025-06-18 11:50 ` Jeff Layton
2025-06-20 11:55 ` NeilBrown
0 siblings, 2 replies; 6+ messages in thread
From: chenxiaosong @ 2025-06-18 10:41 UTC (permalink / raw)
To: chuck.lever, jlayton, neilb, okorniev, Dai.Ngo, tom
Cc: linux-nfs, linux-kernel, huhai, ChenXiaoSong
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
Before commit 38f080f3cd19 ("NFSD: Move callback_wq into struct nfs4_client"),
we had a null-ptr-deref in nfsd4_probe_callback() (Link[1]):
nfsd: last server has exited, flushing export cache
NFSD: starting 90-second grace period (net f0000030)
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
...
Call trace:
__queue_work+0xb4/0x558
queue_work_on+0x88/0x90
nfsd4_probe_callback+0x4c/0x58 [nfsd]
NFSD: starting 90-second grace period (net f0000030)
nfsd4_probe_callback_sync+0x20/0x38 [nfsd]
nfsd4_init_conn.isra.57+0x8c/0xa8 [nfsd]
nfsd4_create_session+0x5b8/0x718 [nfsd]
nfsd4_proc_compound+0x4c0/0x710 [nfsd]
nfsd_dispatch+0x104/0x248 [nfsd]
svc_process_common+0x348/0x808 [sunrpc]
svc_process+0xb0/0xc8 [sunrpc]
nfsd+0xf0/0x160 [nfsd]
kthread+0x134/0x138
ret_from_fork+0x10/0x18
Code: aa1c03e0 97ffffba aa0003e2 b5000780 (f9400262)
SMP: stopping secondary CPUs
Starting crashdump kernel...
Bye!
One of the cases is:
task A (cpu 1) | task B (cpu 2) | task C (cpu 3)
---------------------|----------------------|---------------------------------
nfsd_startup_generic | nfsd_startup_generic |
nfsd_users == 0 | nfsd_users == 0 |
nfsd_users++ | nfsd_users++ |
nfsd_users == 1 | |
... | |
callback_wq == xxx | |
---------------------|----------------------|---------------------------------
| | nfsd_shutdown_generic
| | nfsd_users == 1
| | --nfsd_users
| | nfsd_users == 0
| | ...
| | callback_wq == xxx
| | destroy_workqueue(callback_wq)
---------------------|----------------------|---------------------------------
| nfsd_users == 1 |
| ... |
| callback_wq == yyy |
After commit 38f080f3cd19 ("NFSD: Move callback_wq into struct nfs4_client"),
this issue no longer occurs, but we should still convert the nfsd_users
to atomic_t to prevent other similar issues.
Link[1]: https://chenxiaosong.com/en/nfs/en-null-ptr-deref-in-nfsd4_probe_callback.html
Co-developed-by: huhai <huhai@kylinos.cn>
Signed-off-by: huhai <huhai@kylinos.cn>
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
---
fs/nfsd/nfssvc.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 9b3d6cff0e1e..08b1f9ebdc2a 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -270,13 +270,13 @@ static int nfsd_init_socks(struct net *net, const struct cred *cred)
return 0;
}
-static int nfsd_users = 0;
+static atomic_t nfsd_users = ATOMIC_INIT(0);
static int nfsd_startup_generic(void)
{
int ret;
- if (nfsd_users++)
+ if (atomic_fetch_inc(&nfsd_users))
return 0;
ret = nfsd_file_cache_init();
@@ -291,13 +291,13 @@ static int nfsd_startup_generic(void)
out_file_cache:
nfsd_file_cache_shutdown();
dec_users:
- nfsd_users--;
+ atomic_dec(&nfsd_users);
return ret;
}
static void nfsd_shutdown_generic(void)
{
- if (--nfsd_users)
+ if (atomic_dec_return(&nfsd_users))
return;
nfs4_state_shutdown();
--
2.34.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC PATCH] nfsd: convert the nfsd_users to atomic_t
2025-06-18 10:41 [RFC PATCH] nfsd: convert the nfsd_users to atomic_t chenxiaosong
@ 2025-06-18 11:50 ` Jeff Layton
2025-06-19 7:10 ` ChenXiaoSong
2025-06-20 11:55 ` NeilBrown
1 sibling, 1 reply; 6+ messages in thread
From: Jeff Layton @ 2025-06-18 11:50 UTC (permalink / raw)
To: chenxiaosong, chuck.lever, neilb, okorniev, Dai.Ngo, tom
Cc: linux-nfs, linux-kernel, huhai, ChenXiaoSong
On Wed, 2025-06-18 at 18:41 +0800, chenxiaosong@chenxiaosong.com wrote:
> From: ChenXiaoSong <chenxiaosong@kylinos.cn>
>
> Before commit 38f080f3cd19 ("NFSD: Move callback_wq into struct nfs4_client"),
> we had a null-ptr-deref in nfsd4_probe_callback() (Link[1]):
>
> nfsd: last server has exited, flushing export cache
> NFSD: starting 90-second grace period (net f0000030)
> Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
> ...
> Call trace:
> __queue_work+0xb4/0x558
> queue_work_on+0x88/0x90
> nfsd4_probe_callback+0x4c/0x58 [nfsd]
> NFSD: starting 90-second grace period (net f0000030)
> nfsd4_probe_callback_sync+0x20/0x38 [nfsd]
> nfsd4_init_conn.isra.57+0x8c/0xa8 [nfsd]
> nfsd4_create_session+0x5b8/0x718 [nfsd]
> nfsd4_proc_compound+0x4c0/0x710 [nfsd]
> nfsd_dispatch+0x104/0x248 [nfsd]
> svc_process_common+0x348/0x808 [sunrpc]
> svc_process+0xb0/0xc8 [sunrpc]
> nfsd+0xf0/0x160 [nfsd]
> kthread+0x134/0x138
> ret_from_fork+0x10/0x18
> Code: aa1c03e0 97ffffba aa0003e2 b5000780 (f9400262)
> SMP: stopping secondary CPUs
> Starting crashdump kernel...
> Bye!
>
> One of the cases is:
>
> task A (cpu 1) | task B (cpu 2) | task C (cpu 3)
> ---------------------|----------------------|---------------------------------
> nfsd_startup_generic | nfsd_startup_generic |
> nfsd_users == 0 | nfsd_users == 0 |
> nfsd_users++ | nfsd_users++ |
> nfsd_users == 1 | |
> ... | |
> callback_wq == xxx | |
> ---------------------|----------------------|---------------------------------
> | | nfsd_shutdown_generic
> | | nfsd_users == 1
> | | --nfsd_users
> | | nfsd_users == 0
> | | ...
> | | callback_wq == xxx
> | | destroy_workqueue(callback_wq)
> ---------------------|----------------------|---------------------------------
> | nfsd_users == 1 |
> | ... |
> | callback_wq == yyy |
>
> After commit 38f080f3cd19 ("NFSD: Move callback_wq into struct nfs4_client"),
> this issue no longer occurs, but we should still convert the nfsd_users
> to atomic_t to prevent other similar issues.
>
> Link[1]: https://chenxiaosong.com/en/nfs/en-null-ptr-deref-in-nfsd4_probe_callback.html
> Co-developed-by: huhai <huhai@kylinos.cn>
> Signed-off-by: huhai <huhai@kylinos.cn>
> Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
> ---
> fs/nfsd/nfssvc.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
> index 9b3d6cff0e1e..08b1f9ebdc2a 100644
> --- a/fs/nfsd/nfssvc.c
> +++ b/fs/nfsd/nfssvc.c
> @@ -270,13 +270,13 @@ static int nfsd_init_socks(struct net *net, const struct cred *cred)
> return 0;
> }
>
> -static int nfsd_users = 0;
> +static atomic_t nfsd_users = ATOMIC_INIT(0);
>
> static int nfsd_startup_generic(void)
> {
> int ret;
>
> - if (nfsd_users++)
> + if (atomic_fetch_inc(&nfsd_users))
> return 0;
>
> ret = nfsd_file_cache_init();
> @@ -291,13 +291,13 @@ static int nfsd_startup_generic(void)
> out_file_cache:
> nfsd_file_cache_shutdown();
> dec_users:
> - nfsd_users--;
> + atomic_dec(&nfsd_users);
> return ret;
> }
>
> static void nfsd_shutdown_generic(void)
> {
> - if (--nfsd_users)
> + if (atomic_dec_return(&nfsd_users))
> return;
>
> nfs4_state_shutdown();
Isn't nfsd_users protected by the nfsd_mutex? It looks like it's held
in all of the places this counter is accessed.
--
Jeff Layton <jlayton@kernel.org>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC PATCH] nfsd: convert the nfsd_users to atomic_t
2025-06-18 11:50 ` Jeff Layton
@ 2025-06-19 7:10 ` ChenXiaoSong
2025-06-19 17:24 ` Jeff Layton
0 siblings, 1 reply; 6+ messages in thread
From: ChenXiaoSong @ 2025-06-19 7:10 UTC (permalink / raw)
To: Jeff Layton, chuck.lever, neilb, okorniev, Dai.Ngo, tom
Cc: linux-nfs, linux-kernel, huhai, ChenXiaoSong
Yes, nfsd_users is protected by the nfsd_mutex. But the following log
confuse me, why were they printed in a very short period when crash?
[24225.575708] nfsd: last server has exited, flushing export cache
[24225.580242] NFSD: starting 90-second grace period (net f0000030)
...
[24225.807458] NFSD: starting 90-second grace period (net f0000030)
Why was callback_wq queued that it had already been freed? And a new
callback_wq was created. I’ve added some new vmcore analysis to the link:
https://chenxiaosong.com/en/nfs/en-null-ptr-deref-in-nfsd4_probe_callback.html
在 2025/6/18 19:50, Jeff Layton 写道:
> Isn't nfsd_users protected by the nfsd_mutex? It looks like it's held
> in all of the places this counter is accessed.
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC PATCH] nfsd: convert the nfsd_users to atomic_t
2025-06-19 7:10 ` ChenXiaoSong
@ 2025-06-19 17:24 ` Jeff Layton
0 siblings, 0 replies; 6+ messages in thread
From: Jeff Layton @ 2025-06-19 17:24 UTC (permalink / raw)
To: ChenXiaoSong, chuck.lever, neilb, okorniev, Dai.Ngo, tom
Cc: linux-nfs, linux-kernel, huhai, ChenXiaoSong
On Thu, 2025-06-19 at 15:10 +0800, ChenXiaoSong wrote:
> Yes, nfsd_users is protected by the nfsd_mutex. But the following log
> confuse me, why were they printed in a very short period when crash?
>
> [24225.575708] nfsd: last server has exited, flushing export cache
> [24225.580242] NFSD: starting 90-second grace period (net f0000030)
> ...
> [24225.807458] NFSD: starting 90-second grace period (net f0000030)
>
> Why was callback_wq queued that it had already been freed? And a new
> callback_wq was created. I’ve added some new vmcore analysis to the link:
>
> https://chenxiaosong.com/en/nfs/en-null-ptr-deref-in-nfsd4_probe_callback.html
>
>
> 在 2025/6/18 19:50, Jeff Layton 写道:
> > Isn't nfsd_users protected by the nfsd_mutex? It looks like it's held
> > in all of the places this counter is accessed.
> >
>
I don't know, specifically.
4.19.90 was released more than 5 years ago, and I have no idea what
else you have in that kernel. If this is only reproducible there, then
there's not much we can do to help you. Can you reproduce this on
something more recent?
--
Jeff Layton <jlayton@kernel.org>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC PATCH] nfsd: convert the nfsd_users to atomic_t
2025-06-18 10:41 [RFC PATCH] nfsd: convert the nfsd_users to atomic_t chenxiaosong
2025-06-18 11:50 ` Jeff Layton
@ 2025-06-20 11:55 ` NeilBrown
2025-06-23 8:52 ` ChenXiaoSong
1 sibling, 1 reply; 6+ messages in thread
From: NeilBrown @ 2025-06-20 11:55 UTC (permalink / raw)
To: chenxiaosong
Cc: chuck.lever, jlayton, okorniev, Dai.Ngo, tom, linux-nfs,
linux-kernel, huhai, ChenXiaoSong
On Wed, 18 Jun 2025, chenxiaosong@chenxiaosong.com wrote:
> From: ChenXiaoSong <chenxiaosong@kylinos.cn>
>
> Before commit 38f080f3cd19 ("NFSD: Move callback_wq into struct nfs4_client"),
> we had a null-ptr-deref in nfsd4_probe_callback() (Link[1]):
>
> nfsd: last server has exited, flushing export cache
> NFSD: starting 90-second grace period (net f0000030)
> Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
The only possible cause that I can find for this crash is that the nfsd
thread must have still been running when nfsd_shutdown_net() and then
nfsd_shutdown_generic() were called resulting in the workqueue being
destroyed.
The threads will all have been signalled with SIGKILL, but there was no
mechanism to wait for the threads to complete.
This was changed in
Commit: 3409e4f1e8f2 ("NFSD: Make it possible to use svc_set_num_threads_sync")
Sync then threads were stopped synchronously so they were certainly all
stopped before the workqueue was removed.
NeilBrown
> ...
> Call trace:
> __queue_work+0xb4/0x558
> queue_work_on+0x88/0x90
> nfsd4_probe_callback+0x4c/0x58 [nfsd]
> NFSD: starting 90-second grace period (net f0000030)
> nfsd4_probe_callback_sync+0x20/0x38 [nfsd]
> nfsd4_init_conn.isra.57+0x8c/0xa8 [nfsd]
> nfsd4_create_session+0x5b8/0x718 [nfsd]
> nfsd4_proc_compound+0x4c0/0x710 [nfsd]
> nfsd_dispatch+0x104/0x248 [nfsd]
> svc_process_common+0x348/0x808 [sunrpc]
> svc_process+0xb0/0xc8 [sunrpc]
> nfsd+0xf0/0x160 [nfsd]
> kthread+0x134/0x138
> ret_from_fork+0x10/0x18
> Code: aa1c03e0 97ffffba aa0003e2 b5000780 (f9400262)
> SMP: stopping secondary CPUs
> Starting crashdump kernel...
> Bye!
>
> One of the cases is:
>
> task A (cpu 1) | task B (cpu 2) | task C (cpu 3)
> ---------------------|----------------------|---------------------------------
> nfsd_startup_generic | nfsd_startup_generic |
> nfsd_users == 0 | nfsd_users == 0 |
> nfsd_users++ | nfsd_users++ |
> nfsd_users == 1 | |
> ... | |
> callback_wq == xxx | |
> ---------------------|----------------------|---------------------------------
> | | nfsd_shutdown_generic
> | | nfsd_users == 1
> | | --nfsd_users
> | | nfsd_users == 0
> | | ...
> | | callback_wq == xxx
> | | destroy_workqueue(callback_wq)
> ---------------------|----------------------|---------------------------------
> | nfsd_users == 1 |
> | ... |
> | callback_wq == yyy |
>
> After commit 38f080f3cd19 ("NFSD: Move callback_wq into struct nfs4_client"),
> this issue no longer occurs, but we should still convert the nfsd_users
> to atomic_t to prevent other similar issues.
>
> Link[1]: https://chenxiaosong.com/en/nfs/en-null-ptr-deref-in-nfsd4_probe_callback.html
> Co-developed-by: huhai <huhai@kylinos.cn>
> Signed-off-by: huhai <huhai@kylinos.cn>
> Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
> ---
> fs/nfsd/nfssvc.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
> index 9b3d6cff0e1e..08b1f9ebdc2a 100644
> --- a/fs/nfsd/nfssvc.c
> +++ b/fs/nfsd/nfssvc.c
> @@ -270,13 +270,13 @@ static int nfsd_init_socks(struct net *net, const struct cred *cred)
> return 0;
> }
>
> -static int nfsd_users = 0;
> +static atomic_t nfsd_users = ATOMIC_INIT(0);
>
> static int nfsd_startup_generic(void)
> {
> int ret;
>
> - if (nfsd_users++)
> + if (atomic_fetch_inc(&nfsd_users))
> return 0;
>
> ret = nfsd_file_cache_init();
> @@ -291,13 +291,13 @@ static int nfsd_startup_generic(void)
> out_file_cache:
> nfsd_file_cache_shutdown();
> dec_users:
> - nfsd_users--;
> + atomic_dec(&nfsd_users);
> return ret;
> }
>
> static void nfsd_shutdown_generic(void)
> {
> - if (--nfsd_users)
> + if (atomic_dec_return(&nfsd_users))
> return;
>
> nfs4_state_shutdown();
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RFC PATCH] nfsd: convert the nfsd_users to atomic_t
2025-06-20 11:55 ` NeilBrown
@ 2025-06-23 8:52 ` ChenXiaoSong
0 siblings, 0 replies; 6+ messages in thread
From: ChenXiaoSong @ 2025-06-23 8:52 UTC (permalink / raw)
To: NeilBrown
Cc: chuck.lever, jlayton, okorniev, Dai.Ngo, tom, linux-nfs,
linux-kernel, huhai, ChenXiaoSong
It seems this patch (or patchset) could resolve the issue.
Thanks for your reply.
ChenXiaoSong.
在 2025/6/20 19:55, NeilBrown 写道:
> The only possible cause that I can find for this crash is that the nfsd
> thread must have still been running when nfsd_shutdown_net() and then
> nfsd_shutdown_generic() were called resulting in the workqueue being
> destroyed.
>
> The threads will all have been signalled with SIGKILL, but there was no
> mechanism to wait for the threads to complete.
>
> This was changed in
>
> Commit: 3409e4f1e8f2 ("NFSD: Make it possible to use svc_set_num_threads_sync")
>
> Sync then threads were stopped synchronously so they were certainly all
> stopped before the workqueue was removed.
>
> NeilBrown
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2025-06-23 8:54 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-18 10:41 [RFC PATCH] nfsd: convert the nfsd_users to atomic_t chenxiaosong
2025-06-18 11:50 ` Jeff Layton
2025-06-19 7:10 ` ChenXiaoSong
2025-06-19 17:24 ` Jeff Layton
2025-06-20 11:55 ` NeilBrown
2025-06-23 8:52 ` ChenXiaoSong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®