path: root/sys/cddl/dev/sdt/sdt.c
diff options
authorRyan Stone <rstone@FreeBSD.org>2012-03-27 15:07:43 +0000
committerRyan Stone <rstone@FreeBSD.org>2012-03-27 15:07:43 +0000
commit974241079704e313fe2424a2c31e7e9342979ca7 (patch)
tree3e88342c0b877113ee02c840d3b675a1e232f253 /sys/cddl/dev/sdt/sdt.c
parent250a19126063fc5d69757aaa927d6dbf04e91dc9 (diff)
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
Notes: svn path=/head/; revision=233552
Diffstat (limited to 'sys/cddl/dev/sdt/sdt.c')
1 files changed, 5 insertions, 2 deletions
diff --git a/sys/cddl/dev/sdt/sdt.c b/sys/cddl/dev/sdt/sdt.c
index d5d41724593f..395daf7ec59a 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();