module: don't use stop_machine for waiting rmmod
authorRusty Russell <rusty@rustcorp.com.au>
Wed, 23 Jul 2008 00:24:25 +0000 (19:24 -0500)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 22 Jul 2008 09:24:25 +0000 (19:24 +1000)
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>
kernel/module.c

index 5f80478b746d4eeb1a1dc92040c1e8eacd31bc34..705e1d5d516cc54b1056003737407af9c7090447 100644 (file)
@@ -639,8 +639,8 @@ static int __try_stop_module(void *_sref)
 {
        struct stopref *sref = _sref;
 
-       /* If it's not unused, quit unless we are told to block. */
-       if ((sref->flags & O_NONBLOCK) && module_refcount(sref->mod) != 0) {
+       /* If it's not unused, quit unless we're forcing. */
+       if (module_refcount(sref->mod) != 0) {
                if (!(*sref->forced = try_force_unload(sref->flags)))
                        return -EWOULDBLOCK;
        }
@@ -652,9 +652,16 @@ static int __try_stop_module(void *_sref)
 
 static int try_stop_module(struct module *mod, int flags, int *forced)
 {
-       struct stopref sref = { mod, flags, forced };
+       if (flags & O_NONBLOCK) {
+               struct stopref sref = { mod, flags, forced };
 
-       return stop_machine_run(__try_stop_module, &sref, NR_CPUS);
+               return stop_machine_run(__try_stop_module, &sref, NR_CPUS);
+       } else {
+               /* We don't need to stop the machine for this. */
+               mod->state = MODULE_STATE_GOING;
+               synchronize_sched();
+               return 0;
+       }
 }
 
 unsigned int module_refcount(struct module *mod)