Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: module auto-unload



On Sun, 15 Dec 2013, Paul Goyette wrote:

Given the recent discussion on the usefulness of auto-unload, would it possibly make sense to enable/disable this via a new sysctl variable?

We could make kern.module.unload_delay default to 10 seconds (the current default); if the delay is ever set to a non-positive value, it would disable the auto-unload feature completely.

Comments?

The attached patch has been compile-tested, but not actually booted. If anyone wants to give it a try, please let me know if it works.



-------------------------------------------------------------------------
| Paul Goyette     | PGP Key fingerprint:     | E-mail addresses:       |
| Customer Service | FA29 0E3B 35AF E8AE 6651 | paul at whooppee.com    |
| Network Engineer | 0786 F758 55DE 53BA 7731 | pgoyette at juniper.net |
| Kernel Developer |                          | pgoyette at netbsd.org  |
-------------------------------------------------------------------------
Index: kern_module.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_module.c,v
retrieving revision 1.93
diff -u -p -r1.93 kern_module.c
--- kern_module.c       13 Sep 2013 07:18:34 -0000      1.93
+++ kern_module.c       15 Dec 2013 18:07:08 -0000
@@ -99,6 +99,8 @@ static void   module_enqueue(module_t *);
 static bool    module_merge_dicts(prop_dictionary_t, const prop_dictionary_t);
 
 static void    sysctl_module_setup(void);
+static int     sysctl_module_autotime(SYSCTLFN_PROTO);
+
 #define MODULE_CLASS_MATCH(mi, class) \
        ((class) == MODULE_CLASS_ANY || (class) == (mi)->mi_class)
 
@@ -405,6 +407,27 @@ module_builtin_require_force(void)
 
 static struct sysctllog *module_sysctllog;
 
+static int
+sysctl_module_autotime(SYSCTLFN_ARGS)
+{
+       struct sysctlnode node;
+       int t, error;
+
+       t = *(int *)rnode->sysctl_data;
+
+       node = *rnode;
+       node.sysctl_data = &t;
+       error = sysctl_lookup(SYSCTLFN_CALL(&node));
+       if (error || newp == NULL)
+               return (error);
+
+       if (t < 0)
+               return (EINVAL);
+
+       *(int *)rnode->sysctl_data = t;
+       return (0);
+}
+
 static void
 sysctl_module_setup(void)
 {
@@ -437,6 +460,12 @@ sysctl_module_setup(void)
                SYSCTL_DESCR("Enable verbose output"),
                NULL, 0, &module_verbose_on, 0,
                CTL_CREATE, CTL_EOL);
+       sysctl_createv(&module_sysctllog, 0, &node, NULL,
+               CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+               CTLTYPE_INT, "verbose",
+               SYSCTL_DESCR("Auto-unload delay"),
+               sysctl_module_autotime, 0, &module_autotime, 0,
+               CTL_CREATE, CTL_EOL);
 }
 
 /*
@@ -1107,10 +1136,10 @@ module_do_load(const char *name, bool is
        if (modp != NULL) {
                *modp = mod;
        }
-       if (autoload) {
+       if (autoload && module_autotime > 0) {
                /*
                 * Arrange to try unloading the module after
-                * a short delay.
+                * a short delay unless auto-unload is disabled.
                 */
                mod->mod_autotime = time_second + module_autotime;
                mod->mod_flags |= MODFLG_AUTO_LOADED;
@@ -1288,7 +1317,8 @@ module_find_section(const char *name, vo
  *
  *     Automatically unload modules.  We try once to unload autoloaded
  *     modules after module_autotime seconds.  If the system is under
- *     severe memory pressure, we'll try unloading all modules.
+ *     severe memory pressure, we'll try unloading all modules, else if
+ *     module_autotime is non-positive, we don't try to unload.
  */
 static void
 module_thread(void *cookie)
@@ -1311,6 +1341,8 @@ module_thread(void *cookie)
 
                        if (uvmexp.free < uvmexp.freemin) {
                                module_thread_ticks = hz;
+                       } else if (module_autotime <= 0) {
+                               continue;
                        } else if (mod->mod_autotime == 0) {
                                continue;
                        } else if (time_second < mod->mod_autotime) {


Home | Main Index | Thread Index | Old Index