Module Name:    src
Committed By:   pgoyette
Date:           Sun Dec 15 21:09:50 UTC 2013

Modified Files:
        src/sys/kern: kern_module.c

Log Message:
Make the auto-unload timeout configurable via sysctl, and if the timeout
is set to zero, disable all auto-unloads (even those that were "scheduled"
previously).


To generate a diff of this commit:
cvs rdiff -u -r1.93 -r1.94 src/sys/kern/kern_module.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/kern_module.c
diff -u src/sys/kern/kern_module.c:1.93 src/sys/kern/kern_module.c:1.94
--- src/sys/kern/kern_module.c:1.93	Fri Sep 13 07:18:34 2013
+++ src/sys/kern/kern_module.c	Sun Dec 15 21:09:50 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_module.c,v 1.93 2013/09/13 07:18:34 jnemeth Exp $	*/
+/*	$NetBSD: kern_module.c,v 1.94 2013/12/15 21:09:50 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.93 2013/09/13 07:18:34 jnemeth Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.94 2013/12/15 21:09:50 pgoyette Exp $");
 
 #define _MODULE_INTERNAL
 
@@ -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, "autotime",
+		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,9 @@ 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 zero, we don't try to unload, even if the
+ *	module was previously scheduled for unload.
  */
 static void
 module_thread(void *cookie)
@@ -1311,7 +1342,8 @@ module_thread(void *cookie)
 
 			if (uvmexp.free < uvmexp.freemin) {
 				module_thread_ticks = hz;
-			} else if (mod->mod_autotime == 0) {
+			} else if (module_autotime == 0 ||
+				   mod->mod_autotime == 0) {
 				continue;
 			} else if (time_second < mod->mod_autotime) {
 				module_thread_ticks = hz;

Reply via email to