The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_sdt.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright 2006-2008 John Birrell <jb@FreeBSD.org>
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  * 
   13  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   16  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   23  * SUCH DAMAGE.
   24  *
   25  * $FreeBSD$
   26  *
   27  * Backend for the Statically Defined Tracing (SDT) kernel support. This is
   28  * required to allow a module to load even though DTrace kernel support may
   29  * not be present. A module may be built with SDT probes in it which are
   30  * registered and deregistered via SYSINIT/SYSUNINIT.
   31  *
   32  */
   33 
   34 #include "opt_kdtrace.h"
   35 
   36 #include <sys/cdefs.h>
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/kernel.h>
   40 #include <sys/linker.h>
   41 #include <sys/lock.h>
   42 #include <sys/proc.h>
   43 #include <sys/sx.h>
   44 #include <sys/sdt.h>
   45 
   46 /*
   47  * This is the list of statically defined tracing providers.
   48  */
   49 static TAILQ_HEAD(sdt_provider_list_head, sdt_provider) sdt_provider_list;
   50 
   51 /*
   52  * Mutex to serialise access to the SDT provider list.
   53  */
   54 static struct sx sdt_sx;
   55 
   56 /*
   57  * Hook for the DTrace probe function. The 'sdt' provider will set this
   58  * to dtrace_probe when it loads.
   59  */
   60 sdt_probe_func_t sdt_probe_func = sdt_probe_stub;
   61 
   62 /*
   63  * This is a stub for probe calls in case kernel DTrace support isn't
   64  * compiled in. It should never get called because there is no DTrace
   65  * support to enable it.
   66  */
   67 void
   68 sdt_probe_stub(u_int32_t id, uintptr_t arg0, uintptr_t arg1,
   69     uintptr_t arg2, uintptr_t arg3, uintptr_t arg4)
   70 {
   71         printf("sdt_probe_stub: Why did this get called?\n");
   72 }
   73 
   74 /*
   75  * Called from SYSINIT to register a provider.
   76  */
   77 void
   78 sdt_provider_register(void *arg)
   79 {
   80         struct sdt_provider *prov = arg;
   81 
   82         sx_xlock(&sdt_sx);
   83 
   84         TAILQ_INSERT_TAIL(&sdt_provider_list, prov, prov_entry);
   85 
   86         TAILQ_INIT(&prov->probe_list);
   87 
   88         sx_xunlock(&sdt_sx);
   89 }
   90 
   91 /*
   92  * Called from SYSUNINIT to de-register a provider.
   93  */
   94 void
   95 sdt_provider_deregister(void *arg)
   96 {
   97         struct sdt_provider *prov = arg;
   98 
   99         sx_xlock(&sdt_sx);
  100 
  101         TAILQ_REMOVE(&sdt_provider_list, prov, prov_entry);
  102 
  103         sx_xunlock(&sdt_sx);
  104 }
  105 
  106 /*
  107  * Called from SYSINIT to register a statically defined trace probe.
  108  */
  109 void
  110 sdt_probe_register(void *arg)
  111 {
  112         struct sdt_probe *probe = arg;
  113 
  114         /*
  115          * Check the reference structure version. Only version 1 is
  116          * supported at the moment.
  117          */
  118         if (probe->version != sizeof(struct sdt_probe)) {
  119                 printf("%s:%s:%s has version %d when %d required\n", probe->mod, probe->func, probe->name, probe->version, (int) sizeof(struct sdt_probe));
  120                 return;
  121         }
  122 
  123         sx_xlock(&sdt_sx);
  124 
  125         TAILQ_INSERT_TAIL(&probe->prov->probe_list, probe, probe_entry);
  126 
  127         TAILQ_INIT(&probe->argtype_list);
  128 
  129         probe->state = SDT_INIT;
  130 
  131         sx_xunlock(&sdt_sx);
  132 }
  133 
  134 /*
  135  * Called from SYSUNINIT to de-register a statically defined trace probe.
  136  */
  137 void
  138 sdt_probe_deregister(void *arg)
  139 {
  140         struct sdt_probe *probe = arg;
  141 
  142         sx_xlock(&sdt_sx);
  143 
  144         if (probe->state == SDT_INIT) {
  145                 TAILQ_REMOVE(&probe->prov->probe_list, probe, probe_entry);
  146                 probe->state = SDT_UNINIT;
  147         }
  148 
  149         sx_xunlock(&sdt_sx);
  150 }
  151 
  152 /*
  153  * Called from SYSINIT to register a statically defined trace probe argument.
  154  */
  155 void
  156 sdt_argtype_register(void *arg)
  157 {
  158         struct sdt_argtype *argtype = arg;
  159 
  160         sx_xlock(&sdt_sx);
  161 
  162         TAILQ_INSERT_TAIL(&argtype->probe->argtype_list, argtype, argtype_entry);
  163 
  164         argtype->probe->n_args++;
  165 
  166         sx_xunlock(&sdt_sx);
  167 }
  168 
  169 /*
  170  * Called from SYSUNINIT to de-register a statically defined trace probe argument.
  171  */
  172 void
  173 sdt_argtype_deregister(void *arg)
  174 {
  175         struct sdt_argtype *argtype = arg;
  176 
  177         sx_xlock(&sdt_sx);
  178 
  179         TAILQ_REMOVE(&argtype->probe->argtype_list, argtype, argtype_entry);
  180 
  181         sx_xunlock(&sdt_sx);
  182 }
  183 
  184 static void
  185 sdt_init(void *arg)
  186 { 
  187         sx_init_flags(&sdt_sx, "Statically Defined Tracing", SX_NOWITNESS);
  188 
  189         TAILQ_INIT(&sdt_provider_list);
  190 }
  191 
  192 SYSINIT(sdt, SI_SUB_KDTRACE, SI_ORDER_FIRST, sdt_init, NULL);
  193 
  194 static void
  195 sdt_uninit(void *arg)
  196 { 
  197         sx_destroy(&sdt_sx);
  198 }
  199 
  200 SYSUNINIT(sdt, SI_SUB_KDTRACE, SI_ORDER_FIRST, sdt_uninit, NULL);
  201 
  202 /*
  203  * List statically defined tracing providers.
  204  */
  205 int
  206 sdt_provider_listall(sdt_provider_listall_func_t callback_func,void *arg)
  207 {
  208         int error = 0;
  209         struct sdt_provider *prov;
  210 
  211         sx_xlock(&sdt_sx);
  212 
  213         TAILQ_FOREACH(prov, &sdt_provider_list, prov_entry) {
  214                 if ((error = callback_func(prov, arg)) != 0)
  215                         break;
  216         }
  217 
  218         sx_xunlock(&sdt_sx);
  219 
  220         return (error);
  221 }
  222 
  223 /*
  224  * List statically defined tracing probes.
  225  */
  226 int
  227 sdt_probe_listall(struct sdt_provider *prov, 
  228     sdt_probe_listall_func_t callback_func,void *arg)
  229 {
  230         int error = 0;
  231         int locked;
  232         struct sdt_probe *probe;
  233 
  234         locked = sx_xlocked(&sdt_sx);
  235         if (!locked)
  236                 sx_xlock(&sdt_sx);
  237 
  238         TAILQ_FOREACH(probe, &prov->probe_list, probe_entry) {
  239                 if ((error = callback_func(probe, arg)) != 0)
  240                         break;
  241         }
  242 
  243         if (!locked)
  244                 sx_xunlock(&sdt_sx);
  245 
  246         return (error);
  247 }
  248 
  249 /*
  250  * List statically defined tracing probe arguments.
  251  */
  252 int
  253 sdt_argtype_listall(struct sdt_probe *probe, 
  254     sdt_argtype_listall_func_t callback_func,void *arg)
  255 {
  256         int error = 0;
  257         int locked;
  258         struct sdt_argtype *argtype;
  259 
  260         locked = sx_xlocked(&sdt_sx);
  261         if (!locked)
  262                 sx_xlock(&sdt_sx);
  263 
  264         TAILQ_FOREACH(argtype, &probe->argtype_list, argtype_entry) {
  265                 if ((error = callback_func(argtype, arg)) != 0)
  266                         break;
  267         }
  268 
  269         if (!locked)
  270                 sx_xunlock(&sdt_sx);
  271 
  272         return (error);
  273 }

Cache object: 7698c4e330ccc563fed6986ac22f1dbc


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.