Message ID | 1650739455-26096-4-git-send-email-dai.ngo@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | NFSD: Initial implementation of NFSv4 Courteous Server | expand |
This patch has problem to build with this error: >> nfsctl.c:(.exit.text+0x0): undefined reference to `laundry_wq' >> mipsel-linux-ld: nfsctl.c:(.exit.text+0x4): undefined reference to `laundry_wq' This happens when CONFIG_NFSD is defined but CONFIG_NFSD_V4 is not. I think to fix this we need to also move the declaration of laundry_wq from nfs4state.c to nfsctl.c. However this seems odd since the laundry_wq is only used for v4, unless you have any other suggestion. -Dai On 4/23/22 11:44 AM, Dai Ngo wrote: > This patch moves create/destroy of laundry_wq from nfs4_state_start > and nfs4_state_shutdown_net to init_nfsd and exit_nfsd to prevent > the laundromat from being freed while a thread is processing a > conflicting lock. > > Signed-off-by: Dai Ngo <dai.ngo@oracle.com> > --- > fs/nfsd/nfs4state.c | 15 ++------------- > fs/nfsd/nfsctl.c | 6 ++++++ > fs/nfsd/nfsd.h | 1 + > 3 files changed, 9 insertions(+), 13 deletions(-) > > diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c > index b08c132648b9..b70ba2eb5665 100644 > --- a/fs/nfsd/nfs4state.c > +++ b/fs/nfsd/nfs4state.c > @@ -125,7 +125,7 @@ static void free_session(struct nfsd4_session *); > static const struct nfsd4_callback_ops nfsd4_cb_recall_ops; > static const struct nfsd4_callback_ops nfsd4_cb_notify_lock_ops; > > -static struct workqueue_struct *laundry_wq; > +struct workqueue_struct *laundry_wq; > > static bool is_session_dead(struct nfsd4_session *ses) > { > @@ -7798,22 +7798,12 @@ nfs4_state_start(void) > { > int ret; > > - laundry_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, "nfsd4"); > - if (laundry_wq == NULL) { > - ret = -ENOMEM; > - goto out; > - } > ret = nfsd4_create_callback_queue(); > if (ret) > - goto out_free_laundry; > + return ret; > > set_max_delegations(); > return 0; > - > -out_free_laundry: > - destroy_workqueue(laundry_wq); > -out: > - return ret; > } > > void > @@ -7850,7 +7840,6 @@ nfs4_state_shutdown_net(struct net *net) > void > nfs4_state_shutdown(void) > { > - destroy_workqueue(laundry_wq); > nfsd4_destroy_callback_queue(); > } > > diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c > index 16920e4512bd..884e873b46ad 100644 > --- a/fs/nfsd/nfsctl.c > +++ b/fs/nfsd/nfsctl.c > @@ -1544,6 +1544,11 @@ static int __init init_nfsd(void) > retval = register_cld_notifier(); > if (retval) > goto out_free_all; > + laundry_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, "nfsd4"); > + if (laundry_wq == NULL) { > + retval = -ENOMEM; > + goto out_free_all; > + } > return 0; > out_free_all: > unregister_pernet_subsys(&nfsd_net_ops); > @@ -1566,6 +1571,7 @@ static int __init init_nfsd(void) > > static void __exit exit_nfsd(void) > { > + destroy_workqueue(laundry_wq); > unregister_cld_notifier(); > unregister_pernet_subsys(&nfsd_net_ops); > nfsd_drc_slab_free(); > diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h > index 23996c6ca75e..d41dcf1c4312 100644 > --- a/fs/nfsd/nfsd.h > +++ b/fs/nfsd/nfsd.h > @@ -72,6 +72,7 @@ extern unsigned long nfsd_drc_max_mem; > extern unsigned long nfsd_drc_mem_used; > > extern const struct seq_operations nfs_exports_op; > +extern struct workqueue_struct *laundry_wq; > > /* > * Common void argument and result helpers
On Mon, Apr 25, 2022 at 08:27:22AM -0700, dai.ngo@oracle.com wrote: > This patch has problem to build with this error: > > >>nfsctl.c:(.exit.text+0x0): undefined reference to `laundry_wq' > >>mipsel-linux-ld: nfsctl.c:(.exit.text+0x4): undefined reference to `laundry_wq' > > This happens when CONFIG_NFSD is defined but CONFIG_NFSD_V4 > is not. I think to fix this we need to also move the declaration > of laundry_wq from nfs4state.c to nfsctl.c. However this seems > odd since the laundry_wq is only used for v4, unless you have > any other suggestion. I'd just leave laundry_wq private to nfs4state.c. Define create_laundromat() and destroy_laundromat() in nfs4state.c too. And in nfsd.h, do the usual trick of defining no-op versions of those functions in the non-v4 case. (See e.g. what we do with nfsd4_init/free_slabs().) --b. > > -Dai > > On 4/23/22 11:44 AM, Dai Ngo wrote: > >This patch moves create/destroy of laundry_wq from nfs4_state_start > >and nfs4_state_shutdown_net to init_nfsd and exit_nfsd to prevent > >the laundromat from being freed while a thread is processing a > >conflicting lock. > > > >Signed-off-by: Dai Ngo <dai.ngo@oracle.com> > >--- > > fs/nfsd/nfs4state.c | 15 ++------------- > > fs/nfsd/nfsctl.c | 6 ++++++ > > fs/nfsd/nfsd.h | 1 + > > 3 files changed, 9 insertions(+), 13 deletions(-) > > > >diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c > >index b08c132648b9..b70ba2eb5665 100644 > >--- a/fs/nfsd/nfs4state.c > >+++ b/fs/nfsd/nfs4state.c > >@@ -125,7 +125,7 @@ static void free_session(struct nfsd4_session *); > > static const struct nfsd4_callback_ops nfsd4_cb_recall_ops; > > static const struct nfsd4_callback_ops nfsd4_cb_notify_lock_ops; > >-static struct workqueue_struct *laundry_wq; > >+struct workqueue_struct *laundry_wq; > > static bool is_session_dead(struct nfsd4_session *ses) > > { > >@@ -7798,22 +7798,12 @@ nfs4_state_start(void) > > { > > int ret; > >- laundry_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, "nfsd4"); > >- if (laundry_wq == NULL) { > >- ret = -ENOMEM; > >- goto out; > >- } > > ret = nfsd4_create_callback_queue(); > > if (ret) > >- goto out_free_laundry; > >+ return ret; > > set_max_delegations(); > > return 0; > >- > >-out_free_laundry: > >- destroy_workqueue(laundry_wq); > >-out: > >- return ret; > > } > > void > >@@ -7850,7 +7840,6 @@ nfs4_state_shutdown_net(struct net *net) > > void > > nfs4_state_shutdown(void) > > { > >- destroy_workqueue(laundry_wq); > > nfsd4_destroy_callback_queue(); > > } > >diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c > >index 16920e4512bd..884e873b46ad 100644 > >--- a/fs/nfsd/nfsctl.c > >+++ b/fs/nfsd/nfsctl.c > >@@ -1544,6 +1544,11 @@ static int __init init_nfsd(void) > > retval = register_cld_notifier(); > > if (retval) > > goto out_free_all; > >+ laundry_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, "nfsd4"); > >+ if (laundry_wq == NULL) { > >+ retval = -ENOMEM; > >+ goto out_free_all; > >+ } > > return 0; > > out_free_all: > > unregister_pernet_subsys(&nfsd_net_ops); > >@@ -1566,6 +1571,7 @@ static int __init init_nfsd(void) > > static void __exit exit_nfsd(void) > > { > >+ destroy_workqueue(laundry_wq); > > unregister_cld_notifier(); > > unregister_pernet_subsys(&nfsd_net_ops); > > nfsd_drc_slab_free(); > >diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h > >index 23996c6ca75e..d41dcf1c4312 100644 > >--- a/fs/nfsd/nfsd.h > >+++ b/fs/nfsd/nfsd.h > >@@ -72,6 +72,7 @@ extern unsigned long nfsd_drc_max_mem; > > extern unsigned long nfsd_drc_mem_used; > > extern const struct seq_operations nfs_exports_op; > >+extern struct workqueue_struct *laundry_wq; > > /* > > * Common void argument and result helpers
On 4/25/22 12:35 PM, J. Bruce Fields wrote: > On Mon, Apr 25, 2022 at 08:27:22AM -0700, dai.ngo@oracle.com wrote: >> This patch has problem to build with this error: >> >>>> nfsctl.c:(.exit.text+0x0): undefined reference to `laundry_wq' >>>> mipsel-linux-ld: nfsctl.c:(.exit.text+0x4): undefined reference to `laundry_wq' >> This happens when CONFIG_NFSD is defined but CONFIG_NFSD_V4 >> is not. I think to fix this we need to also move the declaration >> of laundry_wq from nfs4state.c to nfsctl.c. However this seems >> odd since the laundry_wq is only used for v4, unless you have >> any other suggestion. > I'd just leave laundry_wq private to nfs4state.c. Define > create_laundromat() and destroy_laundromat() in nfs4state.c too. And in > nfsd.h, do the usual trick of defining no-op versions of those functions > in the non-v4 case. (See e.g. what we do with nfsd4_init/free_slabs().) ok, thanks. -Dai > > --b. > >> -Dai >> >> On 4/23/22 11:44 AM, Dai Ngo wrote: >>> This patch moves create/destroy of laundry_wq from nfs4_state_start >>> and nfs4_state_shutdown_net to init_nfsd and exit_nfsd to prevent >>> the laundromat from being freed while a thread is processing a >>> conflicting lock. >>> >>> Signed-off-by: Dai Ngo <dai.ngo@oracle.com> >>> --- >>> fs/nfsd/nfs4state.c | 15 ++------------- >>> fs/nfsd/nfsctl.c | 6 ++++++ >>> fs/nfsd/nfsd.h | 1 + >>> 3 files changed, 9 insertions(+), 13 deletions(-) >>> >>> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c >>> index b08c132648b9..b70ba2eb5665 100644 >>> --- a/fs/nfsd/nfs4state.c >>> +++ b/fs/nfsd/nfs4state.c >>> @@ -125,7 +125,7 @@ static void free_session(struct nfsd4_session *); >>> static const struct nfsd4_callback_ops nfsd4_cb_recall_ops; >>> static const struct nfsd4_callback_ops nfsd4_cb_notify_lock_ops; >>> -static struct workqueue_struct *laundry_wq; >>> +struct workqueue_struct *laundry_wq; >>> static bool is_session_dead(struct nfsd4_session *ses) >>> { >>> @@ -7798,22 +7798,12 @@ nfs4_state_start(void) >>> { >>> int ret; >>> - laundry_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, "nfsd4"); >>> - if (laundry_wq == NULL) { >>> - ret = -ENOMEM; >>> - goto out; >>> - } >>> ret = nfsd4_create_callback_queue(); >>> if (ret) >>> - goto out_free_laundry; >>> + return ret; >>> set_max_delegations(); >>> return 0; >>> - >>> -out_free_laundry: >>> - destroy_workqueue(laundry_wq); >>> -out: >>> - return ret; >>> } >>> void >>> @@ -7850,7 +7840,6 @@ nfs4_state_shutdown_net(struct net *net) >>> void >>> nfs4_state_shutdown(void) >>> { >>> - destroy_workqueue(laundry_wq); >>> nfsd4_destroy_callback_queue(); >>> } >>> diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c >>> index 16920e4512bd..884e873b46ad 100644 >>> --- a/fs/nfsd/nfsctl.c >>> +++ b/fs/nfsd/nfsctl.c >>> @@ -1544,6 +1544,11 @@ static int __init init_nfsd(void) >>> retval = register_cld_notifier(); >>> if (retval) >>> goto out_free_all; >>> + laundry_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, "nfsd4"); >>> + if (laundry_wq == NULL) { >>> + retval = -ENOMEM; >>> + goto out_free_all; >>> + } >>> return 0; >>> out_free_all: >>> unregister_pernet_subsys(&nfsd_net_ops); >>> @@ -1566,6 +1571,7 @@ static int __init init_nfsd(void) >>> static void __exit exit_nfsd(void) >>> { >>> + destroy_workqueue(laundry_wq); >>> unregister_cld_notifier(); >>> unregister_pernet_subsys(&nfsd_net_ops); >>> nfsd_drc_slab_free(); >>> diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h >>> index 23996c6ca75e..d41dcf1c4312 100644 >>> --- a/fs/nfsd/nfsd.h >>> +++ b/fs/nfsd/nfsd.h >>> @@ -72,6 +72,7 @@ extern unsigned long nfsd_drc_max_mem; >>> extern unsigned long nfsd_drc_mem_used; >>> extern const struct seq_operations nfs_exports_op; >>> +extern struct workqueue_struct *laundry_wq; >>> /* >>> * Common void argument and result helpers
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index b08c132648b9..b70ba2eb5665 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -125,7 +125,7 @@ static void free_session(struct nfsd4_session *); static const struct nfsd4_callback_ops nfsd4_cb_recall_ops; static const struct nfsd4_callback_ops nfsd4_cb_notify_lock_ops; -static struct workqueue_struct *laundry_wq; +struct workqueue_struct *laundry_wq; static bool is_session_dead(struct nfsd4_session *ses) { @@ -7798,22 +7798,12 @@ nfs4_state_start(void) { int ret; - laundry_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, "nfsd4"); - if (laundry_wq == NULL) { - ret = -ENOMEM; - goto out; - } ret = nfsd4_create_callback_queue(); if (ret) - goto out_free_laundry; + return ret; set_max_delegations(); return 0; - -out_free_laundry: - destroy_workqueue(laundry_wq); -out: - return ret; } void @@ -7850,7 +7840,6 @@ nfs4_state_shutdown_net(struct net *net) void nfs4_state_shutdown(void) { - destroy_workqueue(laundry_wq); nfsd4_destroy_callback_queue(); } diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 16920e4512bd..884e873b46ad 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1544,6 +1544,11 @@ static int __init init_nfsd(void) retval = register_cld_notifier(); if (retval) goto out_free_all; + laundry_wq = alloc_workqueue("%s", WQ_UNBOUND, 0, "nfsd4"); + if (laundry_wq == NULL) { + retval = -ENOMEM; + goto out_free_all; + } return 0; out_free_all: unregister_pernet_subsys(&nfsd_net_ops); @@ -1566,6 +1571,7 @@ static int __init init_nfsd(void) static void __exit exit_nfsd(void) { + destroy_workqueue(laundry_wq); unregister_cld_notifier(); unregister_pernet_subsys(&nfsd_net_ops); nfsd_drc_slab_free(); diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 23996c6ca75e..d41dcf1c4312 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -72,6 +72,7 @@ extern unsigned long nfsd_drc_max_mem; extern unsigned long nfsd_drc_mem_used; extern const struct seq_operations nfs_exports_op; +extern struct workqueue_struct *laundry_wq; /* * Common void argument and result helpers
This patch moves create/destroy of laundry_wq from nfs4_state_start and nfs4_state_shutdown_net to init_nfsd and exit_nfsd to prevent the laundromat from being freed while a thread is processing a conflicting lock. Signed-off-by: Dai Ngo <dai.ngo@oracle.com> --- fs/nfsd/nfs4state.c | 15 ++------------- fs/nfsd/nfsctl.c | 6 ++++++ fs/nfsd/nfsd.h | 1 + 3 files changed, 9 insertions(+), 13 deletions(-)