diff options
author | rstone <rstone@FreeBSD.org> | 2012-03-27 15:07:43 +0000 |
---|---|---|
committer | rstone <rstone@FreeBSD.org> | 2012-03-27 15:07:43 +0000 |
commit | 0ee65aa24ed3bff9fc4a2b3f62e35821de1fa15f (patch) | |
tree | 3e88342c0b877113ee02c840d3b675a1e232f253 /sys/cddl | |
parent | 126e29ce5f4fb39d333b4d155af4acb71eeb38e4 (diff) | |
download | FreeBSD-src-0ee65aa24ed3bff9fc4a2b3f62e35821de1fa15f.zip FreeBSD-src-0ee65aa24ed3bff9fc4a2b3f62e35821de1fa15f.tar.gz |
Instead of only iterating over the set of known SDT probes when sdt.ko is
loaded and unloaded, also have sdt.ko register callbacks with kern_sdt.c
that will be called when a newly loaded KLD module adds more probes or
a module with probes is unloaded.
This fixes two issues: first, if a module with SDT probes was loaded after
sdt.ko was loaded, those new probes would not be available in DTrace.
Second, if a module with SDT probes was unloaded while sdt.ko was loaded,
the kernel would panic the next time DTrace had cause to try and do
anything with the no-longer-existent probes.
This makes it possible to create SDT probes in KLD modules, although there
are still two caveats: first, any SDT probes in a KLD module must be part
of a DTrace provider that is defined in that module. At present DTrace
only destroys probes when the provider is destroyed, so you can still
panic the system if a KLD module creates new probes in a provider from a
different module(including the kernel) and then unload the the first module.
Second, the system will panic if you unload a module containing SDT probes
while there is an active D script that has enabled those probes.
MFC after: 1 month
Diffstat (limited to 'sys/cddl')
-rw-r--r-- | sys/cddl/dev/sdt/sdt.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/sys/cddl/dev/sdt/sdt.c b/sys/cddl/dev/sdt/sdt.c index d5d4172..395daf7 100644 --- a/sys/cddl/dev/sdt/sdt.c +++ b/sys/cddl/dev/sdt/sdt.c @@ -52,6 +52,8 @@ static void sdt_destroy(void *, dtrace_id_t, void *); static void sdt_enable(void *, dtrace_id_t, void *); static void sdt_disable(void *, dtrace_id_t, void *); static void sdt_load(void *); +static int sdt_provider_unreg_callback(struct sdt_provider *prov, + void *arg); static struct cdevsw sdt_cdevsw = { .d_version = D_VERSION, @@ -190,7 +192,8 @@ sdt_load(void *dummy) sdt_probe_func = dtrace_probe; - (void) sdt_provider_listall(sdt_provider_reg_callback, NULL); + sdt_register_callbacks(sdt_provider_reg_callback, NULL, + sdt_provider_unreg_callback, NULL, sdt_probe_callback, NULL); } static int @@ -206,7 +209,7 @@ sdt_unload() sdt_probe_func = sdt_probe_stub; - (void) sdt_provider_listall(sdt_provider_unreg_callback, NULL); + sdt_deregister_callbacks(); destroy_dev(sdt_cdev); |