Author: jhb
Date: Wed Jan 21 18:32:43 2009
New Revision: 187553
URL: http://svn.freebsd.org/changeset/base/187553

Log:
  MFC: Invoke MOD_QUIESCE on all modules in a linker file (kld) before
  unloading any modules.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)
  stable/7/sys/kern/kern_linker.c
  stable/7/sys/kern/kern_module.c
  stable/7/sys/sys/module.h

Modified: stable/7/sys/kern/kern_linker.c
==============================================================================
--- stable/7/sys/kern/kern_linker.c     Wed Jan 21 18:26:10 2009        
(r187552)
+++ stable/7/sys/kern/kern_linker.c     Wed Jan 21 18:32:43 2009        
(r187553)
@@ -587,7 +587,30 @@ linker_file_unload(linker_file_t file, i
            " informing modules\n"));
 
        /*
-        * Inform any modules associated with this file.
+        * Quiesce all the modules to give them a chance to veto the unload.
+        */
+       MOD_SLOCK;
+       for (mod = TAILQ_FIRST(&file->modules); mod;
+            mod = module_getfnext(mod)) {
+
+               error = module_quiesce(mod);
+               if (error != 0 && flags != LINKER_UNLOAD_FORCE) {
+                       KLD_DPF(FILE, ("linker_file_unload: module %s"
+                           " vetoed unload\n", module_getname(mod)));
+                       /*
+                        * XXX: Do we need to tell all the quiesced modules
+                        * that they can resume work now via a new module
+                        * event?
+                        */
+                       MOD_SUNLOCK;
+                       return (error);
+               }
+       }
+       MOD_SUNLOCK;
+
+       /*
+        * Inform any modules associated with this file that they are
+        * being be unloaded.
         */
        MOD_XLOCK;
        for (mod = TAILQ_FIRST(&file->modules); mod; mod = next) {
@@ -597,9 +620,9 @@ linker_file_unload(linker_file_t file, i
                /*
                 * Give the module a chance to veto the unload.
                 */
-               if ((error = module_unload(mod, flags)) != 0) {
-                       KLD_DPF(FILE, ("linker_file_unload: module %p"
-                           " vetoes unload\n", mod));
+               if ((error = module_unload(mod)) != 0) {
+                       KLD_DPF(FILE, ("linker_file_unload: module %s"
+                           " failed unload\n", mod));
                        return (error);
                }
                MOD_XLOCK;

Modified: stable/7/sys/kern/kern_module.c
==============================================================================
--- stable/7/sys/kern/kern_module.c     Wed Jan 21 18:26:10 2009        
(r187552)
+++ stable/7/sys/kern/kern_module.c     Wed Jan 21 18:32:43 2009        
(r187553)
@@ -196,9 +196,7 @@ module_release(module_t mod)
                TAILQ_REMOVE(&modules, mod, link);
                if (mod->file)
                        TAILQ_REMOVE(&mod->file->modules, mod, flink);
-               MOD_XUNLOCK;
                free(mod, M_MODULE);
-               MOD_XLOCK;
        }
 }
 
@@ -232,16 +230,25 @@ module_lookupbyid(int modid)
 }
 
 int
-module_unload(module_t mod, int flags)
+module_quiesce(module_t mod)
 {
        int error;
 
        mtx_lock(&Giant);
        error = MOD_EVENT(mod, MOD_QUIESCE);
+       mtx_unlock(&Giant);
        if (error == EOPNOTSUPP || error == EINVAL)
                error = 0;
-       if (error == 0 || flags == LINKER_UNLOAD_FORCE)
-               error = MOD_EVENT(mod, MOD_UNLOAD);
+       return (error);
+}
+
+int
+module_unload(module_t mod)
+{
+       int error;
+
+       mtx_lock(&Giant);
+       error = MOD_EVENT(mod, MOD_UNLOAD);
        mtx_unlock(&Giant);
        return (error);
 }
@@ -262,6 +269,14 @@ module_getfnext(module_t mod)
        return (TAILQ_NEXT(mod, flink));
 }
 
+const char *
+module_getname(module_t mod)
+{
+
+       MOD_LOCK_ASSERT;
+       return (mod->name);
+}
+
 void
 module_setspecific(module_t mod, modspecific_t *datap)
 {

Modified: stable/7/sys/sys/module.h
==============================================================================
--- stable/7/sys/sys/module.h   Wed Jan 21 18:26:10 2009        (r187552)
+++ stable/7/sys/sys/module.h   Wed Jan 21 18:32:43 2009        (r187553)
@@ -141,11 +141,13 @@ void      module_register_init(const void *);
 int    module_register(const struct moduledata *, struct linker_file *);
 module_t       module_lookupbyname(const char *);
 module_t       module_lookupbyid(int);
+int    module_quiesce(module_t);
 void   module_reference(module_t);
 void   module_release(module_t);
-int    module_unload(module_t, int flags);
+int    module_unload(module_t);
 int    module_getid(module_t);
 module_t       module_getfnext(module_t);
+const char *   module_getname(module_t);
 void   module_setspecific(module_t, modspecific_t *);
 struct linker_file *module_file(module_t);
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to