Module Name: src Committed By: pgoyette Date: Mon Jun 25 07:22:54 UTC 2018
Modified Files: src/sys/kern [pgoyette-compat]: kern_module.c src/sys/sys [pgoyette-compat]: module.h Log Message: Resolve conflicts with HEAD To generate a diff of this commit: cvs rdiff -u -r1.130.2.8 -r1.130.2.9 src/sys/kern/kern_module.c cvs rdiff -u -r1.41.14.8 -r1.41.14.9 src/sys/sys/module.h 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.8 src/sys/kern/kern_module.c:1.130.2.9 --- src/sys/kern/kern_module.c:1.130.2.8 Mon Apr 2 00:18:43 2018 +++ src/sys/kern/kern_module.c Mon Jun 25 07:22:54 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_module.c,v 1.130.2.8 2018/04/02 00:18:43 pgoyette Exp $ */ +/* $NetBSD: kern_module.c,v 1.130.2.9 2018/06/25 07:22:54 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.8 2018/04/02 00:18:43 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.130.2.9 2018/06/25 07:22:54 pgoyette Exp $"); #define _MODULE_INTERNAL @@ -65,6 +65,21 @@ struct modlist module_list = TAIL struct modlist module_builtins = TAILQ_HEAD_INITIALIZER(module_builtins); static struct modlist module_bootlist = TAILQ_HEAD_INITIALIZER(module_bootlist); +struct module_callbacks { + TAILQ_ENTRY(module_callbacks) modcb_list; + void (*modcb_load)(struct module *); + void (*modcb_unload)(struct module *); +}; +TAILQ_HEAD(modcblist, module_callbacks); +static struct modcblist modcblist; + +static module_t *module_netbsd; +static const modinfo_t module_netbsd_modinfo = { + .mi_version = __NetBSD_Version__, + .mi_class = MODULE_CLASS_MISC, + .mi_name = "netbsd" +}; + static module_t *module_active; bool module_verbose_on; #ifdef MODULAR_DEFAULT_AUTOLOAD @@ -84,11 +99,14 @@ int (*module_load_vfs_vec)(const char *, static kauth_listener_t module_listener; +static specificdata_domain_t module_specificdata_domain; + /* Ensure that the kernel's link set isn't empty. */ static modinfo_t module_dummy; __link_set_add_rodata(modules, module_dummy); static module_t *module_newmodule(modsrc_t); +static void module_free(module_t *); static void module_require_force(module_t *); static int module_do_load(const char *, bool, int, prop_dictionary_t, module_t **, modclass_t modclass, bool); @@ -107,6 +125,9 @@ static bool module_merge_dicts(prop_dict static void sysctl_module_setup(void); static int sysctl_module_autotime(SYSCTLFN_PROTO); +static void module_callback_load(struct module *); +static void module_callback_unload(struct module *); + #define MODULE_CLASS_MATCH(mi, modclass) \ ((modclass) == MODULE_CLASS_ANY || (modclass) == (mi)->mi_class) @@ -117,6 +138,13 @@ module_incompat(const modinfo_t *mi, int mi->mi_name, modclass, mi->mi_class); } +struct module * +module_kernel(void) +{ + + return module_netbsd; +} + /* * module_error: * @@ -153,6 +181,30 @@ module_print(const char *fmt, ...) } } +/* + * module_name: + * + * Utility function: return the module's name. + */ +const char * +module_name(struct module *mod) +{ + + return mod->mod_info->mi_name; +} + +/* + * module_source: + * + * Utility function: return the module's source. + */ +modsrc_t +module_source(struct module *mod) +{ + + return mod->mod_source; +} + static int module_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) @@ -180,12 +232,25 @@ module_newmodule(modsrc_t source) mod = kmem_zalloc(sizeof(*mod), KM_SLEEP); mod->mod_source = source; - mod->mod_info = NULL; - mod->mod_flags = 0; + specificdata_init(module_specificdata_domain, &mod->mod_sdref); return mod; } /* + * Free a module_t + */ +static void +module_free(module_t *mod) +{ + + specificdata_fini(module_specificdata_domain, &mod->mod_sdref); + if (mod->mod_required) + kmem_free(mod->mod_required, mod->mod_arequired * + sizeof(module_t)); + kmem_free(mod, sizeof(*mod)); +} + +/* * Require the -f (force) flag to load a module */ static void @@ -281,7 +346,7 @@ module_builtin_add(modinfo_t *const *mip if (rv != 0) { for (i = 0; i < nmodinfo; i++) { if (modp[i]) - kmem_free(modp[i], sizeof(*modp[i])); + module_free(modp[i]); } } kmem_free(modp, sizeof(*modp) * nmodinfo); @@ -348,6 +413,7 @@ module_init(void) } cv_init(&module_thread_cv, "mod_unld"); mutex_init(&module_thread_lock, MUTEX_DEFAULT, IPL_NONE); + TAILQ_INIT(&modcblist); #ifdef MODULAR /* XXX */ module_init_md(); @@ -374,6 +440,11 @@ module_init(void) } sysctl_module_setup(); + module_specificdata_domain = specificdata_domain_create(); + + module_netbsd = module_newmodule(MODULE_SOURCE_KERNEL); + module_netbsd->mod_refcnt = 1; + module_netbsd->mod_info = &module_netbsd_modinfo; } /* @@ -707,21 +778,13 @@ module_lookup(const char *name) * responsibility to ensure that the reference is dropped * later. */ -int -module_hold(const char *name) +void +module_hold(module_t *mod) { - module_t *mod; kernconfig_lock(); - mod = module_lookup(name); - if (mod == NULL) { - kernconfig_unlock(); - return ENOENT; - } mod->mod_refcnt++; kernconfig_unlock(); - - return 0; } /* @@ -730,16 +793,11 @@ module_hold(const char *name) * Release a reference acquired with module_hold(). */ void -module_rele(const char *name) +module_rele(module_t *mod) { - module_t *mod; kernconfig_lock(); - mod = module_lookup(name); - if (mod == NULL) { - kernconfig_unlock(); - panic("%s: gone", __func__); - } + KASSERT(mod->mod_refcnt > 0); mod->mod_refcnt--; kernconfig_unlock(); } @@ -1045,8 +1103,9 @@ module_do_load(const char *name, bool is module_error("vfs load failed for `%s', " "error %d", name, error); #endif - kmem_free(mod, sizeof(*mod)); SLIST_REMOVE_HEAD(&pend_stack, pe_entry); + module_free(mod); + depth--; return error; } TAILQ_INSERT_TAIL(pending, mod, mod_chain); @@ -1258,6 +1317,7 @@ module_do_load(const char *name, bool is } SLIST_REMOVE_HEAD(&pend_stack, pe_entry); module_print("module `%s' loaded successfully", mi->mi_name); + module_callback_load(mod); return 0; fail1: @@ -1270,11 +1330,9 @@ module_do_load(const char *name, bool is filedict = NULL; } TAILQ_REMOVE(pending, mod, mod_chain); - if (mod->mod_required) - kmem_free(mod->mod_required, mod->mod_arequired * - sizeof(module_t)); - kmem_free(mod, sizeof(*mod)); SLIST_REMOVE_HEAD(&pend_stack, pe_entry); + module_free(mod); + depth--; return error; } @@ -1318,6 +1376,7 @@ module_do_unload(const char *name, bool prev_active = module_active; module_active = mod; + module_callback_unload(mod); error = (*mod->mod_info->mi_modcmd)(MODULE_CMD_FINI, NULL); module_active = prev_active; if (error != 0) { @@ -1345,7 +1404,7 @@ module_do_unload(const char *name, bool TAILQ_INSERT_TAIL(&module_builtins, mod, mod_chain); module_builtinlist++; } else { - kmem_free(mod, sizeof(*mod)); + module_free(mod); } module_gen++; @@ -1395,7 +1454,7 @@ module_prime(const char *name, void *bas error = kobj_load_mem(&mod->mod_kobj, name, base, size); if (error != 0) { - kmem_free(mod, sizeof(*mod)); + module_free(mod); module_error("unable to load `%s' pushed by boot loader, " "error %d", name, error); return error; @@ -1403,7 +1462,7 @@ module_prime(const char *name, void *bas error = module_fetch_info(mod); if (error != 0) { kobj_unload(mod->mod_kobj); - kmem_free(mod, sizeof(*mod)); + module_free(mod); module_error("unable to fetch_info for `%s' pushed by boot " "loader, error %d", name, error); return error; @@ -1649,3 +1708,131 @@ out: return !error; } + +/* + * module_specific_key_create: + * + * Create a key for subsystem module-specific data. + */ +specificdata_key_t +module_specific_key_create(specificdata_key_t *keyp, specificdata_dtor_t dtor) +{ + + return specificdata_key_create(module_specificdata_domain, keyp, dtor); +} + +/* + * module_specific_key_delete: + * + * Delete a key for subsystem module-specific data. + */ +void +module_specific_key_delete(specificdata_key_t key) +{ + + return specificdata_key_delete(module_specificdata_domain, key); +} + +/* + * module_getspecific: + * + * Return module-specific data corresponding to the specified key. + */ +void * +module_getspecific(module_t *mod, specificdata_key_t key) +{ + + return specificdata_getspecific(module_specificdata_domain, + &mod->mod_sdref, key); +} + +/* + * module_setspecific: + * + * Set module-specific data corresponding to the specified key. + */ +void +module_setspecific(module_t *mod, specificdata_key_t key, void *data) +{ + + specificdata_setspecific(module_specificdata_domain, + &mod->mod_sdref, key, data); +} + +/* + * module_register_callbacks: + * + * Register a new set of callbacks to be called on module load/unload. + * Call the load callback on each existing module. + * Return an opaque handle for unregistering these later. + */ +void * +module_register_callbacks(void (*load)(struct module *), + void (*unload)(struct module *)) +{ + struct module_callbacks *modcb; + struct module *mod; + + modcb = kmem_alloc(sizeof(*modcb), KM_SLEEP); + modcb->modcb_load = load; + modcb->modcb_unload = unload; + + kernconfig_lock(); + TAILQ_INSERT_TAIL(&modcblist, modcb, modcb_list); + TAILQ_FOREACH(mod, &module_list, mod_chain) + load(mod); + kernconfig_unlock(); + + return modcb; +} + +/* + * module_unregister_callbacks: + * + * Unregister a previously-registered set of module load/unload callbacks. + * Call the unload callback on each existing module. + */ +void +module_unregister_callbacks(void *opaque) +{ + struct module_callbacks *modcb; + struct module *mod; + + modcb = opaque; + kernconfig_lock(); + TAILQ_FOREACH(mod, &module_list, mod_chain) + modcb->modcb_unload(mod); + TAILQ_REMOVE(&modcblist, modcb, modcb_list); + kernconfig_unlock(); + kmem_free(modcb, sizeof(*modcb)); +} + +/* + * module_callback_load: + * + * Helper routine: call all load callbacks on a module being loaded. + */ +static void +module_callback_load(struct module *mod) +{ + struct module_callbacks *modcb; + + TAILQ_FOREACH(modcb, &modcblist, modcb_list) { + modcb->modcb_load(mod); + } +} + +/* + * module_callback_unload: + * + * Helper routine: call all unload callbacks on a module being unloaded. + */ +static void +module_callback_unload(struct module *mod) +{ + struct module_callbacks *modcb; + + TAILQ_FOREACH(modcb, &modcblist, modcb_list) { + modcb->modcb_unload(mod); + } +} Index: src/sys/sys/module.h diff -u src/sys/sys/module.h:1.41.14.8 src/sys/sys/module.h:1.41.14.9 --- src/sys/sys/module.h:1.41.14.8 Tue Apr 3 08:29:44 2018 +++ src/sys/sys/module.h Mon Jun 25 07:22:54 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: module.h,v 1.41.14.8 2018/04/03 08:29:44 pgoyette Exp $ */ +/* $NetBSD: module.h,v 1.41.14.9 2018/06/25 07:22:54 pgoyette Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -32,7 +32,6 @@ #include <sys/types.h> #include <sys/param.h> #include <sys/cdefs.h> -#include <sys/queue.h> #include <sys/uio.h> #define MAXMODNAME 32 @@ -68,6 +67,8 @@ typedef enum modcmd { #include <sys/kernel.h> #include <sys/mutex.h> +#include <sys/queue.h> +#include <sys/specificdata.h> #include <prop/proplib.h> @@ -84,6 +85,10 @@ typedef struct modinfo { /* Per module information, maintained by kern_module.c */ typedef struct module { u_int mod_refcnt; + int mod_flags; +#define MODFLG_MUST_FORCE 0x01 +#define MODFLG_AUTO_LOADED 0x02 +#define MODFLG_IS_ALIAS 0x04 /* only for export via modstat_t */ const modinfo_t *mod_info; struct kobj *mod_kobj; TAILQ_ENTRY(module) mod_chain; @@ -92,13 +97,7 @@ typedef struct module { u_int mod_arequired; modsrc_t mod_source; time_t mod_autotime; - void *mod_ctf; - u_int mod_fbtentries; /* DTrace FBT entry count */ - int mod_flags; -#define MODFLG_MUST_FORCE 0x01 -#define MODFLG_AUTO_LOADED 0x02 -#define MODFLG_IS_ALIAS 0x04 /* only for export via modstat_t */ - + specificdata_reference mod_sdref; } module_t; /* @@ -190,18 +189,29 @@ void module_init_md(void); void module_init_class(modclass_t); int module_prime(const char *, void *, size_t); +module_t *module_kernel(void); +const char *module_name(struct module *); +modsrc_t module_source(struct module *); bool module_compatible(int, int); int module_load(const char *, int, prop_dictionary_t, modclass_t); int module_builtin_add(modinfo_t * const *, size_t, bool); int module_builtin_remove(modinfo_t *, bool); int module_autoload(const char *, modclass_t); int module_unload(const char *); -int module_hold(const char *); -void module_rele(const char *); +void module_hold(module_t *); +void module_rele(module_t *); int module_find_section(const char *, void **, size_t *); void module_thread_kick(void); void module_load_vfs_init(void); +specificdata_key_t module_specific_key_create(specificdata_key_t *, specificdata_dtor_t); +void module_specific_key_delete(specificdata_key_t); +void *module_getspecific(module_t *, specificdata_key_t); +void module_setspecific(module_t *, specificdata_key_t, void *); +void *module_register_callbacks(void (*)(struct module *), + void (*)(struct module *)); +void module_unregister_callbacks(void *); + void module_whatis(uintptr_t, void (*)(const char *, ...) __printflike(1, 2)); void module_print_list(void (*)(const char *, ...) __printflike(1, 2)); @@ -237,13 +247,12 @@ typedef struct modctl_load { size_t ml_propslen; } modctl_load_t; -typedef enum modctl { +enum modctl { MODCTL_LOAD, /* modctl_load_t *ml */ MODCTL_UNLOAD, /* char *name */ - MODCTL_OSTAT, /* struct iovec *buffer */ - MODCTL_EXISTS, /* enum: 0: load, 1: autoload */ - MODCTL_STAT /* struct iovec *buffer */ -} modctl_t; + MODCTL_STAT, /* struct iovec *buffer */ + MODCTL_EXISTS /* enum: 0: load, 1: autoload */ +}; /* * This structure intentionally has the same layout for 32 and 64