Messages in this thread Patch in this message | | | From | Rusty Russell <> | Subject | [PATCH] module_put_and_exit | Date | Fri, 04 Jul 2003 14:47:13 +1000 |
| |
From: Neil Brown
Define module_put_and_exit() and use it for nfsd/lockd
Both nfsd and lockd have threads which expect to hold a reference to the module while the thread is running. In order for the thread to be able to put_module() the module before exiting, the put_module code must be call from outside the module.
This patch provides module_put_and_exit in non-modular code which a thread-in-a-module can call. It also gets nfsd and lockd to use it as appropriate.
Note that in lockd, we can __get_module in the thread itself as the creator of the thread is waiting for the thread to startup.
In nfsd and for the 'reclaimer' threaded started by locked, we __get_module first and put_module if the thread failed to start.
----------- Diffstat output ------------ ./fs/lockd/clntlock.c | 9 ++++----- ./fs/lockd/svc.c | 8 ++++++-- ./fs/nfsd/nfssvc.c | 8 +++++--- ./include/linux/module.h | 8 ++++++++ ./kernel/exit.c | 1 + ./kernel/module.c | 12 ++++++++++++ 6 files changed, 36 insertions(+), 10 deletions(-)
Name: module_put_and_exit Author: Neil Brown Status: Booted on 2.5.74-bk1
D: Define module_put_and_exit() and use it for nfsd/lockd D: D: Both nfsd and lockd have threads which expect to hold a reference D: to the module while the thread is running. In order for the thread D: to be able to put_module() the module before exiting, the D: put_module code must be call from outside the module. D: D: This patch provides module_put_and_exit in non-modular code which a D: thread-in-a-module can call. It also gets nfsd and lockd to use it D: as appropriate. D: D: Note that in lockd, we can __get_module in the thread itself as the D: creator of the thread is waiting for the thread to startup. D: D: In nfsd and for the 'reclaimer' threaded started by locked, we D: __get_module first and put_module if the thread failed to start. D: D: ----------- Diffstat output ------------ D: ./fs/lockd/clntlock.c | 9 ++++----- D: ./fs/lockd/svc.c | 8 ++++++-- D: ./fs/nfsd/nfssvc.c | 8 +++++--- D: ./include/linux/module.h | 8 ++++++++ D: ./kernel/exit.c | 1 + D: ./kernel/module.c | 12 ++++++++++++ D: 6 files changed, 36 insertions(+), 10 deletions(-)
diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .25804-linux-2.5.74-bk1/fs/lockd/clntlock.c .25804-linux-2.5.74-bk1.updated/fs/lockd/clntlock.c --- .25804-linux-2.5.74-bk1/fs/lockd/clntlock.c 2003-02-17 11:37:52.000000000 +1100 +++ .25804-linux-2.5.74-bk1.updated/fs/lockd/clntlock.c 2003-07-04 07:58:04.000000000 +1000 @@ -187,8 +187,9 @@ nlmclnt_recovery(struct nlm_host *host, } else { nlmclnt_prepare_reclaim(host, newstate); nlm_get_host(host); - MOD_INC_USE_COUNT; - kernel_thread(reclaimer, host, CLONE_KERNEL); + __module_get(THIS_MODULE); + if (kernel_thread(reclaimer, host, CLONE_KERNEL)) + module_put(THIS_MODULE); } } @@ -244,7 +245,5 @@ restart: nlm_release_host(host); lockd_down(); unlock_kernel(); - MOD_DEC_USE_COUNT; - - return 0; + module_put_and_exit(0); } diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .25804-linux-2.5.74-bk1/fs/lockd/svc.c .25804-linux-2.5.74-bk1.updated/fs/lockd/svc.c --- .25804-linux-2.5.74-bk1/fs/lockd/svc.c 2003-07-03 09:43:54.000000000 +1000 +++ .25804-linux-2.5.74-bk1.updated/fs/lockd/svc.c 2003-07-04 07:58:04.000000000 +1000 @@ -88,7 +88,11 @@ lockd(struct svc_rqst *rqstp) unsigned long grace_period_expire; /* Lock module and set up kernel thread */ - MOD_INC_USE_COUNT; + /* lockd_up is waiting for us to startup, so will + * be holding a reference to this module, so it + * is safe to just claim another reference + */ + __module_get(THIS_MODULE); lock_kernel(); /* @@ -183,7 +187,7 @@ lockd(struct svc_rqst *rqstp) /* Release module */ unlock_kernel(); - MOD_DEC_USE_COUNT; + module_put_and_exit(0); } /* diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .25804-linux-2.5.74-bk1/fs/nfsd/nfssvc.c .25804-linux-2.5.74-bk1.updated/fs/nfsd/nfssvc.c --- .25804-linux-2.5.74-bk1/fs/nfsd/nfssvc.c 2003-07-03 09:43:54.000000000 +1000 +++ .25804-linux-2.5.74-bk1.updated/fs/nfsd/nfssvc.c 2003-07-04 07:58:04.000000000 +1000 @@ -115,9 +115,12 @@ nfsd_svc(unsigned short port, int nrserv nrservs -= (nfsd_serv->sv_nrthreads-1); while (nrservs > 0) { nrservs--; + __module_get(THIS_MODULE); error = svc_create_thread(nfsd, nfsd_serv); - if (error < 0) + if (error < 0) { + module_put(THIS_MODULE); break; + } } victim = nfsd_list.next; while (nrservs < 0 && victim != &nfsd_list) { @@ -173,7 +176,6 @@ nfsd(struct svc_rqst *rqstp) sigset_t shutdown_mask, allowed_mask; /* Lock module and set up kernel thread */ - MOD_INC_USE_COUNT; lock_kernel(); daemonize("nfsd"); current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; @@ -266,7 +268,7 @@ nfsd(struct svc_rqst *rqstp) svc_exit_thread(rqstp); /* Release module */ - MOD_DEC_USE_COUNT; + module_put_and_exit(0); } int diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .25804-linux-2.5.74-bk1/include/linux/module.h .25804-linux-2.5.74-bk1.updated/include/linux/module.h --- .25804-linux-2.5.74-bk1/include/linux/module.h 2003-07-03 09:44:00.000000000 +1000 +++ .25804-linux-2.5.74-bk1.updated/include/linux/module.h 2003-07-04 08:00:09.000000000 +1000 @@ -276,8 +276,12 @@ struct module *module_get_kallsym(unsign char *type, char namebuf[128]); int is_exported(const char *name, const struct module *mod); -#ifdef CONFIG_MODULE_UNLOAD +extern void __module_put_and_exit(struct module *mod, long code) + __attribute__((noreturn)); +#define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code); + +#ifdef CONFIG_MODULE_UNLOAD unsigned int module_refcount(struct module *mod); void __symbol_put(const char *symbol); #define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) @@ -445,6 +449,8 @@ static inline int unregister_module_noti return 0; } +#define module_put_and_exit(code) do_exit(code) + #endif /* CONFIG_MODULES */ #ifdef MODULE diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .25804-linux-2.5.74-bk1/kernel/module.c .25804-linux-2.5.74-bk1.updated/kernel/module.c --- .25804-linux-2.5.74-bk1/kernel/module.c 2003-07-03 09:44:01.000000000 +1000 +++ .25804-linux-2.5.74-bk1.updated/kernel/module.c 2003-07-04 07:59:20.000000000 +1000 @@ -98,6 +98,17 @@ int init_module(void) } EXPORT_SYMBOL(init_module); +/* A thread that wants to hold a reference to a module only while it + * is running can call ths to safely exit. + * nfsd and lockd use this. + */ +void __module_put_and_exit(struct module *mod, long code) +{ + module_put(mod); + do_exit(code); +} +EXPORT_SYMBOL(__module_put_and_exit); + /* Find a module section: 0 means not found. */ static unsigned int find_sec(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, -- Anyone who quotes me in their sig is an idiot. -- Rusty Russell. - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |