Module Name: src
Committed By: pgoyette
Date: Fri Mar 30 23:49:42 UTC 2018
Modified Files:
src/sys/kern [pgoyette-compat]: kern_module.c
Log Message:
Use an SLIST-based stack rather than a statically-allocated array for
recursion control. This eliminates the MAXDEPTH constraint.
XXX We still have a static limit on MAXMODDEPS
To generate a diff of this commit:
cvs rdiff -u -r1.130.2.4 -r1.130.2.5 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.130.2.4 src/sys/kern/kern_module.c:1.130.2.5
--- src/sys/kern/kern_module.c:1.130.2.4 Sun Mar 11 11:47:45 2018
+++ src/sys/kern/kern_module.c Fri Mar 30 23:49:42 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_module.c,v 1.130.2.4 2018/03/11 11:47:45 pgoyette Exp $ */
+/* $NetBSD: kern_module.c,v 1.130.2.5 2018/03/30 23:49:42 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.130.2.4 2018/03/11 11:47:45 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.130.2.5 2018/03/30 23:49:42 pgoyette Exp $");
#define _MODULE_INTERNAL
@@ -902,13 +902,19 @@ module_do_load(const char *name, bool is
prop_dictionary_t props, module_t **modp, modclass_t modclass,
bool autoload)
{
-#define MODULE_MAX_DEPTH 6
-
+ /* The pending list for this level of recursion */
TAILQ_HEAD(pending_t, module);
- static int depth = 0;
- static struct pending_t *pending_lists[MODULE_MAX_DEPTH];
struct pending_t *pending;
struct pending_t new_pending = TAILQ_HEAD_INITIALIZER(new_pending);
+
+ /* The stack of pending lists */
+ static SLIST_HEAD(pend_head, pend_entry) pend_stack =
+ SLIST_HEAD_INITIALIZER(pend_stack);
+ struct pend_entry {
+ SLIST_ENTRY(pend_entry) pe_entry;
+ struct pending_t *pe_pending;
+ } *my_pend_entry;
+
modinfo_t *mi;
module_t *mod, *mod2, *prev_active;
prop_dictionary_t filedict;
@@ -924,27 +930,21 @@ module_do_load(const char *name, bool is
error = 0;
/*
- * Avoid recursing too far.
- */
- if (++depth > MODULE_MAX_DEPTH) {
- module_error("recursion too deep for `%s' %d > %d", name,
- depth, MODULE_MAX_DEPTH);
- depth--;
- return EMLINK;
- }
-
- /*
- * Set up the pending list for this depth. If this is a
- * recursive entry, then use same list as for outer call,
- * else use the locally allocated list. In either case,
- * remember which one we're using.
+ * Set up the pending list for this entry. If this is an
+ * internal entry (for a dependency), then use the same list
+ * as for the outer call; otherwise, it's an external entry
+ * (possibly recursive, ie a module's xxx_modcmd(init, ...)
+ * routine called us), so use the locally allocated list. In
+ * either case, add it to our stack.
*/
if (isdep) {
- KASSERT(depth > 1);
- pending = pending_lists[depth - 2];
+ KASSERT(SLIST_FIRST(&pend_stack) != NULL);
+ pending = SLIST_FIRST(&pend_stack)->pe_pending;
} else
pending = &new_pending;
- pending_lists[depth - 1] = pending;
+ my_pend_entry = kmem_zalloc(sizeof(*my_pend_entry), KM_SLEEP);
+ my_pend_entry->pe_pending = pending;
+ SLIST_INSERT_HEAD(&pend_stack, my_pend_entry, pe_entry);
/*
* Search the list of disabled builtins first.
@@ -961,11 +961,13 @@ module_do_load(const char *name, bool is
module_error("use -f to reinstate "
"builtin module `%s'", name);
}
- depth--;
+ SLIST_REMOVE_HEAD(&pend_stack, pe_entry);
+ kmem_free(my_pend_entry, sizeof(*my_pend_entry));
return EPERM;
} else {
+ SLIST_REMOVE_HEAD(&pend_stack, pe_entry);
+ kmem_free(my_pend_entry, sizeof(*my_pend_entry));
error = module_do_builtin(mod, name, modp, props);
- depth--;
return error;
}
}
@@ -993,14 +995,16 @@ module_do_load(const char *name, bool is
}
module_print("%s module `%s' already loaded",
isdep ? "dependent" : "requested", name);
- depth--;
+ SLIST_REMOVE_HEAD(&pend_stack, pe_entry);
+ kmem_free(my_pend_entry, sizeof(*my_pend_entry));
return EEXIST;
}
mod = module_newmodule(MODULE_SOURCE_FILESYS);
if (mod == NULL) {
module_error("out of memory for `%s'", name);
- depth--;
+ SLIST_REMOVE_HEAD(&pend_stack, pe_entry);
+ kmem_free(my_pend_entry, sizeof(*my_pend_entry));
return ENOMEM;
}
@@ -1020,7 +1024,8 @@ module_do_load(const char *name, bool is
"error %d", name, error);
#endif
kmem_free(mod, sizeof(*mod));
- depth--;
+ SLIST_REMOVE_HEAD(&pend_stack, pe_entry);
+ kmem_free(my_pend_entry, sizeof(*my_pend_entry));
return error;
}
TAILQ_INSERT_TAIL(pending, mod, mod_chain);
@@ -1235,7 +1240,8 @@ module_do_load(const char *name, bool is
mod->mod_flags |= MODFLG_AUTO_LOADED;
module_thread_kick();
}
- depth--;
+ SLIST_REMOVE_HEAD(&pend_stack, pe_entry);
+ kmem_free(my_pend_entry, sizeof(*my_pend_entry));
module_print("module `%s' loaded successfully", mi->mi_name);
return 0;
@@ -1250,7 +1256,8 @@ module_do_load(const char *name, bool is
}
TAILQ_REMOVE(pending, mod, mod_chain);
kmem_free(mod, sizeof(*mod));
- depth--;
+ SLIST_REMOVE_HEAD(&pend_stack, pe_entry);
+ kmem_free(my_pend_entry, sizeof(*my_pend_entry));
return error;
}