xref: /freebsd/sys/cddl/dev/dtrace/dtrace_anon.c (revision 61e21613)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  * DTrace Anonymous Enabling Functions
25  */
26 static void
27 dtrace_anon_init(void *dummy)
28 {
29 	dtrace_state_t *state = NULL;
30 	dtrace_enabling_t *enab;
31 
32 	mutex_enter(&cpu_lock);
33 	mutex_enter(&dtrace_provider_lock);
34 	mutex_enter(&dtrace_lock);
35 
36 	dtrace_anon_property();
37 
38 	mutex_exit(&cpu_lock);
39 
40 	/*
41 	 * If there are already providers, we must ask them to provide their
42 	 * probes, and then match any anonymous enabling against them.  Note
43 	 * that there should be no other retained enablings at this time:
44 	 * the only retained enablings at this time should be the anonymous
45 	 * enabling.
46 	 */
47 	if (dtrace_anon.dta_enabling != NULL) {
48 		ASSERT(dtrace_retained == dtrace_anon.dta_enabling);
49 
50 		dtrace_enabling_provide(NULL);
51 		state = dtrace_anon.dta_state;
52 
53 		/*
54 		 * We couldn't hold cpu_lock across the above call to
55 		 * dtrace_enabling_provide(), but we must hold it to actually
56 		 * enable the probes.  We have to drop all of our locks, pick
57 		 * up cpu_lock, and regain our locks before matching the
58 		 * retained anonymous enabling.
59 		 */
60 		mutex_exit(&dtrace_lock);
61 		mutex_exit(&dtrace_provider_lock);
62 
63 		mutex_enter(&cpu_lock);
64 		mutex_enter(&dtrace_provider_lock);
65 		mutex_enter(&dtrace_lock);
66 
67 		if ((enab = dtrace_anon.dta_enabling) != NULL)
68 			(void) dtrace_enabling_match(enab, NULL);
69 
70 		mutex_exit(&cpu_lock);
71 	}
72 
73 	mutex_exit(&dtrace_provider_lock);
74 	mutex_exit(&dtrace_lock);
75 
76 	if (state != NULL) {
77 		/*
78 		 * If we created any anonymous state, set it going now.
79 		 */
80 		(void) dtrace_state_go(state, &dtrace_anon.dta_beganon);
81 	}
82 }
83