PERFORCE change 95729 for review

John Birrell jb at FreeBSD.org
Thu Apr 20 21:54:01 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=95729

Change 95729 by jb at jb_freebsd2 on 2006/04/20 21:53:46

	Use macros to translate Solaris kmem_zalloc(), kmem_alloc() and
	kmem_free() calls into their FreeBSD equivalents. This turns out to
	be a neat way to port their code.
	
	Most memory allocations in this driver occur with one or more
	mutex/es locked. Since dtrace is part of a released product, I'm
	porting this on the assumption that the locking strategy works.
	With witness enabled, I can't have it downgrade a M_WAITOK call
	to a M_NOWAIT call just because it thinks it's a not a good idea
	to sleep with locks held. For this code, we need to do that and
	we can't afford to fail because the thing that we might be trying
	to trace is the low memory situation. We might not be too
	successful, but we need to try. Anyway... that's why the mutexes
	are initialised with M_NOWITNESS.
	
	As a hack, I've created two mutexes (cpu_lock and mod_lock) just
	so that I don't have to comment them out in all the places where
	they are referenced. I havn't started looking for the FreeBSD
	equivalent of those.
	
	Use macros for the mutex_enter() and mutex_exit() calls to translate
	them to mtx_lock() and mtx_unlock(). Again, this avoids having to
	change the code in lots of places.
	
	Unfortunately dtrace_load() doesn't exist as a function in Sun's
	dtrace.c. They have this code in dtrace_attach(). I don't want to
	use that name in FreeBSD beacuse it implies that the device is
	attaching to a bus.
	
	I would prefer it if Sun would abstract their Solaris-specific
	device model from the meaty bits of code. They could do this by
	making their dtrace_attach() call this function.

Affected files ...

.. //depot/projects/dtrace/src/sys/cddl/dev/dtrace/dtrace_load.c#3 edit

Differences ...

==== //depot/projects/dtrace/src/sys/cddl/dev/dtrace/dtrace_load.c#3 (text+ko) ====

@@ -37,19 +37,32 @@
 #endif
 	int error = 0;
 
-	mtx_init(&dtrace_lock,"dtrace probe state",NULL,MTX_RECURSE);
-	mtx_init(&dtrace_provider_lock,"dtrace provider state",NULL,MTX_RECURSE);
-	mtx_init(&dtrace_meta_lock,"dtrace meta-provider state",NULL,MTX_RECURSE);
+	/*
+	 * XXX This is a short term hack to avoid having to comment
+	 * out lots and lots of lock/unlock calls.
+	 */
+	mtx_init(&cpu_lock,"XXX hack",NULL,MTX_RECURSE | MTX_NOWITNESS);
+	mtx_init(&mod_lock,"XXX hack",NULL,MTX_RECURSE | MTX_NOWITNESS);
+
+	/*
+	 * Initialise the mutexes without 'witness' because the dtrace
+	 * code is mostly written to wait for memory. To have the
+	 * witness code change a malloc() from M_WAITOK to M_NOWAIT
+	 * because a lock is held would surely create a panic in a
+	 * low memory situation. And that low memory situation might be
+	 * the very problem we are trying to trace.
+	 */
+	mtx_init(&dtrace_lock,"dtrace probe state",NULL,MTX_RECURSE | MTX_NOWITNESS);
+	mtx_init(&dtrace_provider_lock,"dtrace provider state",NULL,MTX_RECURSE | MTX_NOWITNESS);
+	mtx_init(&dtrace_meta_lock,"dtrace meta-provider state",NULL,MTX_RECURSE | MTX_NOWITNESS);
 
 	/* Create the /dev/dtrace entry. */
 	dtrace_dev = make_dev(&dtrace_cdevsw, DTRACE_MINOR, UID_ROOT,
 	    GID_WHEEL, 0660, "dtrace");
 
-#ifdef DOODAD
-	mtx_lock(&cpu_lock);
-#endif
-	mtx_lock(&dtrace_provider_lock);
-	mtx_lock(&dtrace_lock);
+	mutex_enter(&cpu_lock);
+	mutex_enter(&dtrace_provider_lock);
+	mutex_enter(&dtrace_lock);
 
 #ifdef DOODAD
 	if (ddi_soft_state_init(&dtrace_softstate,
@@ -104,6 +117,7 @@
 	dtrace_state_cache = kmem_cache_create("dtrace_state_cache",
 	    sizeof (dtrace_dstate_percpu_t) * NCPU, DTRACE_STATE_ALIGN,
 	    NULL, NULL, NULL, NULL, NULL, 0);
+#endif
 
 	ASSERT(MUTEX_HELD(&cpu_lock));
 	dtrace_bymod = dtrace_hash_create(offsetof(dtrace_probe_t, dtpr_mod),
@@ -124,6 +138,7 @@
 		dtrace_retain_max = 1;
 	}
 
+#ifdef DOODAD
 	/*
 	 * Now discover our toxic ranges.
 	 */
@@ -140,7 +155,6 @@
 	(void) dtrace_register("dtrace", &dtrace_provider_attr,
 	    DTRACE_PRIV_NONE, 0, &dtrace_provider_ops, NULL, &id);
 
-#ifdef DOODAD
 	ASSERT(dtrace_provider != NULL);
 	ASSERT((dtrace_provider_id_t)dtrace_provider == id);
 
@@ -161,10 +175,11 @@
 	if (dtrace_helptrace_enabled) {
 		ASSERT(dtrace_helptrace_buffer == NULL);
 		dtrace_helptrace_buffer =
-		    kmem_zalloc(dtrace_helptrace_bufsize, KM_SLEEP);
+		    malloc(dtrace_helptrace_bufsize, M_DTRACE, M_NOWAIT | M_ZERO);
 		dtrace_helptrace_next = 0;
 	}
 
+#ifdef DOODAD
 	/*
 	 * If there are already providers, we must ask them to provide their
 	 * probes, and then match any anonymous enabling against them.  Note
@@ -199,8 +214,8 @@
 	}
 #endif
 
-	mtx_unlock(&dtrace_lock);
-	mtx_unlock(&dtrace_provider_lock);
+	mutex_exit(&dtrace_lock);
+	mutex_exit(&dtrace_provider_lock);
 
 #ifdef DOODAD
 	if (state != NULL) {


More information about the p4-projects mailing list