svn commit: r368726 - stable/12/sys/cddl/dev/sdt

Mark Johnston markj at FreeBSD.org
Thu Dec 17 17:21:12 UTC 2020


Author: markj
Date: Thu Dec 17 17:21:12 2020
New Revision: 368726
URL: https://svnweb.freebsd.org/changeset/base/368726

Log:
  MFC r368306:
  sdt: Create providers and probes in separate passes when loading sdt.ko

Modified:
  stable/12/sys/cddl/dev/sdt/sdt.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/cddl/dev/sdt/sdt.c
==============================================================================
--- stable/12/sys/cddl/dev/sdt/sdt.c	Thu Dec 17 17:11:14 2020	(r368725)
+++ stable/12/sys/cddl/dev/sdt/sdt.c	Thu Dec 17 17:21:12 2020	(r368726)
@@ -271,26 +271,24 @@ 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) {
 		for (probe = p_begin; probe < p_end; probe++) {
@@ -310,7 +308,21 @@ sdt_kld_load(void *arg __unused, struct linker_file *l
 	}
 }
 
+/*
+ * 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)
 {
 	struct sdt_provider *prov, **curr, **begin, **end, *tmp;
@@ -348,16 +360,21 @@ sdt_kld_unload_try(void *arg __unused, struct linker_f
 }
 
 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;


More information about the svn-src-stable mailing list