diff options
author | markj <markj@FreeBSD.org> | 2013-08-13 03:10:39 +0000 |
---|---|---|
committer | markj <markj@FreeBSD.org> | 2013-08-13 03:10:39 +0000 |
commit | 5a3f78714c72773b5d7b845e2cfa02dd8e9b2d94 (patch) | |
tree | 46930cccd981ff368016d8ab6113a94632ab865f /sys/cddl/dev/fbt | |
parent | 5423ffaa89a66236a476ec84f1919e37b14210dc (diff) | |
download | FreeBSD-src-5a3f78714c72773b5d7b845e2cfa02dd8e9b2d94.zip FreeBSD-src-5a3f78714c72773b5d7b845e2cfa02dd8e9b2d94.tar.gz |
FreeBSD's DTrace implementation has a few problems with respect to handling
probes declared in a kernel module when that module is unloaded. In
particular,
* Unloading a module with active SDT probes will cause a panic. [1]
* A module's (FBT/SDT) probes aren't destroyed when the module is unloaded;
trying to use them after the fact will generally cause a panic.
This change fixes both problems by porting the DTrace module load/unload
handlers from illumos and registering them with the corresponding
EVENTHANDLER(9) handlers. This allows the DTrace framework to destroy all
probes defined in a module when that module is unloaded, and to prevent a
module unload from proceeding if some of its probes are active. The latter
problem has already been fixed for FBT probes by checking lf->nenabled in
kern_kldunload(), but moving the check into the DTrace framework generalizes
it to all kernel providers and also fixes a race in the current
implementation (since a probe may be activated between the check and the
call to linker_file_unload()).
Additionally, the SDT implementation has been reworked to define SDT
providers/probes/argtypes in linker sets rather than using SYSINIT/SYSUNINIT
to create and destroy SDT probes when a module is loaded or unloaded. This
simplifies things quite a bit since it means that pretty much all of the SDT
code can live in sdt.ko, and since it becomes easier to integrate SDT with
the DTrace framework. Furthermore, this allows FreeBSD to be quite flexible
in that SDT providers spanning multiple modules can be created on the fly
when a module is loaded; at the moment it looks like illumos' SDT
implementation requires all SDT probes to be statically defined in a single
kernel table.
PR: 166927, 166926, 166928
Reported by: davide [1]
Reviewed by: avg, trociny (earlier version)
MFC after: 1 month
Diffstat (limited to 'sys/cddl/dev/fbt')
-rw-r--r-- | sys/cddl/dev/fbt/fbt.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/sys/cddl/dev/fbt/fbt.c b/sys/cddl/dev/fbt/fbt.c index b828163..7b278f7 100644 --- a/sys/cddl/dev/fbt/fbt.c +++ b/sys/cddl/dev/fbt/fbt.c @@ -1335,6 +1335,15 @@ fbt_getargdesc(void *arg __unused, dtrace_id_t id __unused, void *parg, dtrace_a return; } +static int +fbt_linker_file_cb(linker_file_t lf, void *arg) +{ + + fbt_provide_module(arg, lf); + + return (0); +} + static void fbt_load(void *dummy) { @@ -1359,8 +1368,10 @@ fbt_load(void *dummy) if (dtrace_register("fbt", &fbt_attr, DTRACE_PRIV_USER, NULL, &fbt_pops, NULL, &fbt_id) != 0) return; -} + /* Create probes for the kernel and already-loaded modules. */ + linker_file_foreach(fbt_linker_file_cb, NULL); +} static int fbt_unload() |