summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2020-12-17 17:21:12 +0000
committerMark Johnston <markj@FreeBSD.org>2020-12-17 17:21:12 +0000
commit3d116ad2c21e87d02acb2904a7a4c5def3442ef1 (patch)
tree1ffd9f6d02dc3fe8377de6b461153d93e9143eb2
parentcc644ecca2d8d2666a53d810d00badefb1c8b0ad (diff)
downloadsrc-test2-3d116ad2c21e87d02acb2904a7a4c5def3442ef1.tar.gz
src-test2-3d116ad2c21e87d02acb2904a7a4c5def3442ef1.zip
MFC r368306:
sdt: Create providers and probes in separate passes when loading sdt.ko
Notes
Notes: svn path=/stable/12/; revision=368726
-rw-r--r--sys/cddl/dev/sdt/sdt.c56
1 files changed, 39 insertions, 17 deletions
diff --git a/sys/cddl/dev/sdt/sdt.c b/sys/cddl/dev/sdt/sdt.c
index 9e3053d90073..3f85099f16d4 100644
--- a/sys/cddl/dev/sdt/sdt.c
+++ b/sys/cddl/dev/sdt/sdt.c
@@ -271,25 +271,23 @@ sdt_destroy(void *arg, dtrace_id_t id, void *parg)
{
}
-/*
- * Called from the kernel linker when a module is loaded, before
- * dtrace_module_loaded() is called. This is done so that it's possible to
- * register new providers when modules are loaded. The DTrace framework
- * explicitly disallows calling into the framework from the provide_module
- * provider method, so we cannot do this there.
- */
static void
-sdt_kld_load(void *arg __unused, struct linker_file *lf)
+sdt_kld_load_providers(struct linker_file *lf)
{
struct sdt_provider **prov, **begin, **end;
- struct sdt_probe **probe, **p_begin, **p_end;
- struct sdt_argtype **argtype, **a_begin, **a_end;
if (linker_file_lookup_set(lf, "sdt_providers_set", &begin, &end,
NULL) == 0) {
for (prov = begin; prov < end; prov++)
sdt_create_provider(*prov);
}
+}
+
+static void
+sdt_kld_load_probes(struct linker_file *lf)
+{
+ struct sdt_probe **probe, **p_begin, **p_end;
+ struct sdt_argtype **argtype, **a_begin, **a_end;
if (linker_file_lookup_set(lf, "sdt_probes_set", &p_begin, &p_end,
NULL) == 0) {
@@ -310,6 +308,20 @@ sdt_kld_load(void *arg __unused, struct linker_file *lf)
}
}
+/*
+ * Called from the kernel linker when a module is loaded, before
+ * dtrace_module_loaded() is called. This is done so that it's possible to
+ * register new providers when modules are loaded. The DTrace framework
+ * explicitly disallows calling into the framework from the provide_module
+ * provider method, so we cannot do this there.
+ */
+static void
+sdt_kld_load(void *arg __unused, struct linker_file *lf)
+{
+ sdt_kld_load_providers(lf);
+ sdt_kld_load_probes(lf);
+}
+
static void
sdt_kld_unload_try(void *arg __unused, struct linker_file *lf, int *error)
{
@@ -348,16 +360,21 @@ sdt_kld_unload_try(void *arg __unused, struct linker_file *lf, int *error)
}
static int
-sdt_linker_file_cb(linker_file_t lf, void *arg __unused)
+sdt_load_providers_cb(linker_file_t lf, void *arg __unused)
{
+ sdt_kld_load_providers(lf);
+ return (0);
+}
- sdt_kld_load(NULL, lf);
-
+static int
+sdt_load_probes_cb(linker_file_t lf, void *arg __unused)
+{
+ sdt_kld_load_probes(lf);
return (0);
}
static void
-sdt_load()
+sdt_load(void)
{
TAILQ_INIT(&sdt_prov_list);
@@ -369,12 +386,17 @@ sdt_load()
sdt_kld_unload_try_tag = EVENTHANDLER_REGISTER(kld_unload_try,
sdt_kld_unload_try, NULL, EVENTHANDLER_PRI_ANY);
- /* Pick up probes from the kernel and already-loaded linker files. */
- linker_file_foreach(sdt_linker_file_cb, NULL);
+ /*
+ * Pick up probes from the kernel and already-loaded linker files.
+ * Define providers in a separate pass since a linker file may be using
+ * providers defined in a file that appears later in the list.
+ */
+ linker_file_foreach(sdt_load_providers_cb, NULL);
+ linker_file_foreach(sdt_load_probes_cb, NULL);
}
static int
-sdt_unload()
+sdt_unload(void)
{
struct sdt_provider *prov, *tmp;
int ret;