diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2008-07-22 20:24:25 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2008-07-22 05:24:25 -0400 |
commit | da39ba5e1d65e997a98f6eb93ba6e6eb505f6e3c (patch) | |
tree | 7c47c0481a7e8b9a9a13a9ce6ea8f11ed145b546 /kernel/module.c | |
parent | 93ded9b8fd42abe2c3607097963d8de6ad9117eb (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/module.c')
-rw-r--r-- | kernel/module.c | 15 |
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 | ||
653 | static int try_stop_module(struct module *mod, int flags, int *forced) | 653 | static 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 | ||
660 | unsigned int module_refcount(struct module *mod) | 667 | unsigned int module_refcount(struct module *mod) |