]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/kern/dtio_kdtrace.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / kern / dtio_kdtrace.c
1 /*-
2  * Copyright (c) 2012 Advanced Computing Technologies LLC
3  * Written by George Neville-Neil gnn@freebsd.org
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/conf.h>
34 #include <sys/kernel.h>
35 #include <sys/malloc.h>
36 #include <sys/module.h>
37
38 #include <sys/dtrace.h>
39 #include "../sys/dtrace_bsd.h"
40
41
42 static int      dtio_unload(void);
43 static void     dtio_getargdesc(void *, dtrace_id_t, void *,
44                     dtrace_argdesc_t *);
45 static void     dtio_provide(void *, dtrace_probedesc_t *);
46 static void     dtio_destroy(void *, dtrace_id_t, void *);
47 static void     dtio_enable(void *, dtrace_id_t, void *);
48 static void     dtio_disable(void *, dtrace_id_t, void *);
49 static void     dtio_load(void *);
50
51 static dtrace_pattr_t dtio_attr = {
52 { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
53 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
54 { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
55 { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
56 { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
57 };
58
59 static char    *kernel = "kernel";
60
61 /*
62  * Name strings.
63  */
64 static char     *dtio_start_str = "start";
65 static char     *dtio_done_str = "done";
66 static char     *dtio_wait_start_str = "wait-start";
67 static char     *dtio_wait_done_str = "wait-done";
68
69 static dtrace_pops_t dtio_pops = {
70         dtio_provide,
71         NULL,
72         dtio_enable,
73         dtio_disable,
74         NULL,
75         NULL,
76         dtio_getargdesc,
77         NULL,
78         NULL,
79         dtio_destroy
80 };
81
82 static dtrace_provider_id_t     dtio_id;
83
84 extern uint32_t dtio_start_id;
85 extern uint32_t dtio_done_id;
86 extern uint32_t dtio_wait_start_id;
87 extern uint32_t dtio_wait_done_id;
88
89 static void
90 dtio_getargdesc(void *arg, dtrace_id_t id, void *parg,
91     dtrace_argdesc_t *desc)
92 {
93         const char *p = NULL;
94
95         switch (desc->dtargd_ndx) {
96         case 0:
97                 p = "struct bio *";
98                 break;
99         case 1:
100                 p = "struct devstat *";
101                 break;
102         default:
103                 desc->dtargd_ndx = DTRACE_ARGNONE;
104         }
105
106         if (p != NULL)
107                 strlcpy(desc->dtargd_native, p, sizeof(desc->dtargd_native));
108 }
109
110 static void
111 dtio_provide(void *arg, dtrace_probedesc_t *desc)
112 {
113         if (desc != NULL)
114                 return;
115
116         if (dtrace_probe_lookup(dtio_id, kernel, NULL, 
117                                 dtio_start_str) == 0) {
118                 dtio_start_id = dtrace_probe_create(dtio_id, kernel, NULL, 
119                                                    dtio_start_str, 0, NULL);
120         }
121         if (dtrace_probe_lookup(dtio_id, kernel, NULL, dtio_done_str) == 0) {
122                 dtio_done_id = dtrace_probe_create(dtio_id, kernel, NULL, 
123                                                    dtio_done_str, 0, NULL);
124         }
125         if (dtrace_probe_lookup(dtio_id, kernel, NULL, 
126                                 dtio_wait_start_str) == 0) {
127                 dtio_wait_start_id = dtrace_probe_create(dtio_id, kernel, 
128                                                          NULL, 
129                                                          dtio_wait_start_str, 
130                                                          0, NULL);
131         }
132         if (dtrace_probe_lookup(dtio_id, kernel, NULL, 
133                                 dtio_wait_done_str) == 0) {
134                 dtio_wait_done_id = dtrace_probe_create(dtio_id, kernel, NULL, 
135                                                    dtio_wait_done_str, 0, NULL);
136         }
137
138 }
139
140 static void
141 dtio_destroy(void *arg, dtrace_id_t id, void *parg)
142 {
143 }
144
145 static void
146 dtio_enable(void *arg, dtrace_id_t id, void *parg)
147 {
148         if (id == dtio_start_id)
149                 dtrace_io_start_probe =
150                         (dtrace_io_start_probe_func_t)dtrace_probe;
151         else if (id == dtio_done_id)
152                 dtrace_io_done_probe =
153                         (dtrace_io_done_probe_func_t)dtrace_probe;
154         else if (id == dtio_wait_start_id)
155                 dtrace_io_wait_start_probe =
156                         (dtrace_io_wait_start_probe_func_t)dtrace_probe;
157         else if (id == dtio_wait_done_id)
158                 dtrace_io_wait_done_probe =
159                         (dtrace_io_wait_done_probe_func_t)dtrace_probe;
160         else
161                 printf("dtrace io provider: unknown ID\n");
162
163 }
164
165 static void
166 dtio_disable(void *arg, dtrace_id_t id, void *parg)
167 {
168         if (id == dtio_start_id)
169                 dtrace_io_start_probe = NULL;
170         else if (id == dtio_done_id)
171                 dtrace_io_done_probe = NULL;
172         else if (id == dtio_wait_start_id)
173                 dtrace_io_wait_start_probe = NULL;
174         else if (id == dtio_wait_done_id)
175                 dtrace_io_wait_done_probe = NULL;
176         else 
177                 printf("dtrace io provider: unknown ID\n");
178         
179 }
180
181 static void
182 dtio_load(void *dummy)
183 {
184         if (dtrace_register("io", &dtio_attr, DTRACE_PRIV_USER, NULL, 
185                             &dtio_pops, NULL, &dtio_id) != 0)
186                 return;
187 }
188
189
190 static int
191 dtio_unload()
192 {
193         dtrace_io_start_probe = NULL;
194         dtrace_io_done_probe = NULL;
195         dtrace_io_wait_start_probe = NULL;
196         dtrace_io_wait_done_probe = NULL;
197
198         return (dtrace_unregister(dtio_id));
199 }
200
201 static int
202 dtio_modevent(module_t mod __unused, int type, void *data __unused)
203 {
204         int error = 0;
205
206         switch (type) {
207         case MOD_LOAD:
208                 break;
209
210         case MOD_UNLOAD:
211                 break;
212
213         case MOD_SHUTDOWN:
214                 break;
215
216         default:
217                 error = EOPNOTSUPP;
218                 break;
219         }
220
221         return (error);
222 }
223
224 SYSINIT(dtio_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
225     dtio_load, NULL);
226 SYSUNINIT(dtio_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
227     dtio_unload, NULL);
228
229 DEV_MODULE(dtio, dtio_modevent, NULL);
230 MODULE_VERSION(dtio, 1);
231 MODULE_DEPEND(dtio, dtrace, 1, 1, 1);
232 MODULE_DEPEND(dtio, opensolaris, 1, 1, 1);