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 * $FreeBSD$
23 */
24
25/*
26 * DTrace Anonymous Enabling Functions
27 */
28static void
29dtrace_anon_init(void *dummy)
30{
31	dtrace_state_t *state = NULL;
32	dtrace_enabling_t *enab;
33
34	mutex_enter(&cpu_lock);
35	mutex_enter(&dtrace_provider_lock);
36	mutex_enter(&dtrace_lock);
37
38	dtrace_anon_property();
39
40	mutex_exit(&cpu_lock);
41
42	/*
43	 * If there are already providers, we must ask them to provide their
44	 * probes, and then match any anonymous enabling against them.  Note
45	 * that there should be no other retained enablings at this time:
46	 * the only retained enablings at this time should be the anonymous
47	 * enabling.
48	 */
49	if (dtrace_anon.dta_enabling != NULL) {
50		ASSERT(dtrace_retained == dtrace_anon.dta_enabling);
51
52		dtrace_enabling_provide(NULL);
53		state = dtrace_anon.dta_state;
54
55		/*
56		 * We couldn't hold cpu_lock across the above call to
57		 * dtrace_enabling_provide(), but we must hold it to actually
58		 * enable the probes.  We have to drop all of our locks, pick
59		 * up cpu_lock, and regain our locks before matching the
60		 * retained anonymous enabling.
61		 */
62		mutex_exit(&dtrace_lock);
63		mutex_exit(&dtrace_provider_lock);
64
65		mutex_enter(&cpu_lock);
66		mutex_enter(&dtrace_provider_lock);
67		mutex_enter(&dtrace_lock);
68
69		if ((enab = dtrace_anon.dta_enabling) != NULL)
70			(void) dtrace_enabling_match(enab, NULL);
71
72		mutex_exit(&cpu_lock);
73	}
74
75	mutex_exit(&dtrace_provider_lock);
76	mutex_exit(&dtrace_lock);
77
78	if (state != NULL) {
79		/*
80		 * If we created any anonymous state, set it going now.
81		 */
82		(void) dtrace_state_go(state, &dtrace_anon.dta_beganon);
83	}
84}
85