summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2013-08-24 21:13:38 +0000
committermarkj <markj@FreeBSD.org>2013-08-24 21:13:38 +0000
commit3541d8b1434b233c6420ff91d742fe8b8c53a2e1 (patch)
treeef10dca68a0c1d91a3cc018d4f95de74d267c03f /sys/kern
parent6ad648e223be6153dd1674649bfc08d9733aa04a (diff)
downloadFreeBSD-src-3541d8b1434b233c6420ff91d742fe8b8c53a2e1.zip
FreeBSD-src-3541d8b1434b233c6420ff91d742fe8b8c53a2e1.tar.gz
Rename the kld_unload event handler to kld_unload_try, and add a new
kld_unload event handler which gets invoked after a linker file has been successfully unloaded. The kld_unload and kld_load event handlers are now invoked with the shared linker lock held, while kld_unload_try is invoked with the lock exclusively held. Convert hwpmc(4) to use these event handlers instead of having kern_kldload() and kern_kldunload() invoke hwpmc(4) hooks whenever files are loaded or unloaded. This has no functional effect, but simplifes the linker code somewhat. Reviewed by: jhb
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_linker.c39
1 files changed, 13 insertions, 26 deletions
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index b5a2fbb..7d32260 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -995,9 +995,6 @@ linker_search_symbol_name(caddr_t value, char *buf, u_int buflen,
int
kern_kldload(struct thread *td, const char *file, int *fileid)
{
-#ifdef HWPMC_HOOKS
- struct pmckern_map_in pkm;
-#endif
const char *kldname, *modname;
linker_file_t lf;
int error;
@@ -1037,17 +1034,9 @@ kern_kldload(struct thread *td, const char *file, int *fileid)
if (fileid != NULL)
*fileid = lf->id;
- EVENTHANDLER_INVOKE(kld_load, lf);
-
-#ifdef HWPMC_HOOKS
sx_downgrade(&kld_sx);
- pkm.pm_file = lf->filename;
- pkm.pm_address = (uintptr_t) lf->address;
- PMC_CALL_HOOK(td, PMC_FN_KLD_LOAD, (void *) &pkm);
+ EVENTHANDLER_INVOKE(kld_load, lf);
sx_sunlock(&kld_sx);
-#else
- sx_xunlock(&kld_sx);
-#endif
done:
CURVNET_RESTORE();
@@ -1076,10 +1065,10 @@ sys_kldload(struct thread *td, struct kldload_args *uap)
int
kern_kldunload(struct thread *td, int fileid, int flags)
{
-#ifdef HWPMC_HOOKS
- struct pmckern_map_out pkm;
-#endif
linker_file_t lf;
+ char *filename = NULL;
+ caddr_t address;
+ size_t size;
int error = 0;
if ((error = securelevel_gt(td->td_ucred, 0)) != 0)
@@ -1094,7 +1083,7 @@ kern_kldunload(struct thread *td, int fileid, int flags)
if (lf) {
KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs));
- EVENTHANDLER_INVOKE(kld_unload, lf, &error);
+ EVENTHANDLER_INVOKE(kld_unload_try, lf, &error);
if (error != 0)
error = EBUSY;
else if (lf->userrefs == 0) {
@@ -1105,11 +1094,11 @@ kern_kldunload(struct thread *td, int fileid, int flags)
" loaded by the kernel\n");
error = EBUSY;
} else {
-#ifdef HWPMC_HOOKS
- /* Save data needed by hwpmc(4) before unloading. */
- pkm.pm_address = (uintptr_t) lf->address;
- pkm.pm_size = lf->size;
-#endif
+ /* Save data needed for the kld_unload callbacks. */
+ filename = strdup(lf->filename, M_TEMP);
+ address = lf->address;
+ size = lf->size;
+
lf->userrefs--;
error = linker_file_unload(lf, flags);
if (error)
@@ -1118,16 +1107,14 @@ kern_kldunload(struct thread *td, int fileid, int flags)
} else
error = ENOENT;
-#ifdef HWPMC_HOOKS
if (error == 0) {
sx_downgrade(&kld_sx);
- PMC_CALL_HOOK(td, PMC_FN_KLD_UNLOAD, (void *) &pkm);
+ EVENTHANDLER_INVOKE(kld_unload, filename, address, size);
sx_sunlock(&kld_sx);
} else
sx_xunlock(&kld_sx);
-#else
- sx_xunlock(&kld_sx);
-#endif
+ free(filename, M_TEMP);
+
CURVNET_RESTORE();
return (error);
}
OpenPOWER on IntegriCloud