aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-07-22 20:24:25 -0400
committerRusty Russell <rusty@rustcorp.com.au>2008-07-22 05:24:25 -0400
commitda39ba5e1d65e997a98f6eb93ba6e6eb505f6e3c (patch)
tree7c47c0481a7e8b9a9a13a9ce6ea8f11ed145b546 /kernel
parent93ded9b8fd42abe2c3607097963d8de6ad9117eb (diff)
module: don't use stop_machine for waiting rmmod
rmmod has a little-used "-w" option, meaning that instead of failing if the module is in use, it should block until the module becomes unused. In this case, we don't need to use stop_machine: Max Krasnyansky indicated that would be useful for SystemTap which loads/unloads new modules frequently. Cc: Max Krasnyansky <maxk@qualcomm.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/module.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 5f80478b746d..705e1d5d516c 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -639,8 +639,8 @@ static int __try_stop_module(void *_sref)
639{ 639{
640 struct stopref *sref = _sref; 640 struct stopref *sref = _sref;
641 641
642 /* If it's not unused, quit unless we are told to block. */ 642 /* If it's not unused, quit unless we're forcing. */
643 if ((sref->flags & O_NONBLOCK) && module_refcount(sref->mod) != 0) { 643 if (module_refcount(sref->mod) != 0) {
644 if (!(*sref->forced = try_force_unload(sref->flags))) 644 if (!(*sref->forced = try_force_unload(sref->flags)))
645 return -EWOULDBLOCK; 645 return -EWOULDBLOCK;
646 } 646 }
@@ -652,9 +652,16 @@ static int __try_stop_module(void *_sref)
652 652
653static int try_stop_module(struct module *mod, int flags, int *forced) 653static int try_stop_module(struct module *mod, int flags, int *forced)
654{ 654{
655 struct stopref sref = { mod, flags, forced }; 655 if (flags & O_NONBLOCK) {
656 struct stopref sref = { mod, flags, forced };
656 657
657 return stop_machine_run(__try_stop_module, &sref, NR_CPUS); 658 return stop_machine_run(__try_stop_module, &sref, NR_CPUS);
659 } else {
660 /* We don't need to stop the machine for this. */
661 mod->state = MODULE_STATE_GOING;
662 synchronize_sched();
663 return 0;
664 }
658} 665}
659 666
660unsigned int module_refcount(struct module *mod) 667unsigned int module_refcount(struct module *mod)