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/sys/kernhist.h

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 /*      $NetBSD: kernhist.h,v 1.26 2021/04/17 01:53:58 mrg Exp $        */
    2 
    3 /*
    4  * Copyright (c) 1997 Charles D. Cranor and Washington University.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26  *
   27  * from: NetBSD: uvm_stat.h,v 1.49 2011/04/23 18:14:13 rmind Exp
   28  * from: Id: uvm_stat.h,v 1.1.2.4 1998/02/07 01:16:56 chs Exp
   29  */
   30 
   31 #ifndef _SYS_KERNHIST_H_
   32 #define _SYS_KERNHIST_H_
   33 
   34 #if defined(_KERNEL_OPT)
   35 #include "opt_ddb.h"
   36 #include "opt_kernhist.h"
   37 #endif
   38 
   39 #include <sys/queue.h>
   40 #ifdef KERNHIST
   41 #include <sys/cpu.h>
   42 #endif
   43 
   44 /*
   45  * kernel history/tracing, was uvm_stat
   46  */
   47 
   48 struct kern_history_ent {
   49         struct bintime bt;              /* time stamp */
   50         uint32_t cpunum;
   51         const char *fmt;                /* printf format */
   52         size_t fmtlen;                  /* length of printf format */
   53         const char *fn;                 /* function name */
   54         size_t fnlen;                   /* length of function name */
   55         uint32_t call;                  /* function call number */
   56         uintmax_t v[4];                 /* values */
   57 };
   58 
   59 struct kern_history {
   60         const char *name;               /* name of this history */
   61         size_t namelen;                 /* length of name, not including null */
   62         LIST_ENTRY(kern_history) list;  /* link on list of all histories */
   63         uint32_t n;                     /* number of entries */
   64         uint32_t f;                     /* next free one */
   65         struct kern_history_ent *e;     /* the allocated entries */
   66         int s;                          /* our sysctl number */
   67 };
   68 
   69 /*
   70  * structs for exporting history info via sysctl(3)
   71  */
   72 
   73 /*
   74  * Bump this version definition whenever the contents of the
   75  * sysctl structures change.
   76  */
   77 
   78 #define KERNHIST_SYSCTL_VERSION 1
   79 
   80 /* info for a single history event */
   81 struct sysctl_history_event {
   82         struct bintime  she_bintime;
   83         uintmax_t       she_values[4];
   84         uint32_t        she_callnumber;
   85         uint32_t        she_cpunum;
   86         uint32_t        she_fmtoffset;
   87         uint32_t        she_funcoffset;
   88 };
   89 
   90 /* list of all events for a single history */
   91 struct sysctl_history {
   92         uint32_t        filler;
   93         uint32_t        sh_nameoffset;
   94         uint32_t        sh_numentries;
   95         uint32_t        sh_nextfree;
   96         struct sysctl_history_event
   97                         sh_events[];
   98         /* char         sh_strings[]; */        /* follows last sh_events */
   99 };
  100 
  101 LIST_HEAD(kern_history_head, kern_history);
  102 
  103 /*
  104  * grovelling lists all at once.  we currently do not allow more than
  105  * 32 histories to exist, as the way to dump a number of them at once
  106  * is by calling kern_hist() with a bitmask.
  107  *
  108  * XXX extend this to have a registration function?  however, there
  109  * needs to be static ones as UVM requires this before almost anything
  110  * else is setup.
  111  */
  112 
  113 /* this is used to set the size of some arrays */
  114 #define MAXHISTS                32
  115 
  116 /* and these are the bit values of each history */
  117 #define KERNHIST_UVMMAPHIST     0x00000001      /* maphist */
  118 #define KERNHIST_UVMPDHIST      0x00000002      /* pdhist */
  119 #define KERNHIST_UVMUBCHIST     0x00000004      /* ubchist */
  120 #define KERNHIST_UVMLOANHIST    0x00000008      /* loanhist */
  121 #define KERNHIST_USBHIST        0x00000010      /* usbhist */
  122 #define KERNHIST_SCDEBUGHIST    0x00000020      /* scdebughist */
  123 #define KERNHIST_BIOHIST        0x00000040      /* biohist */
  124 
  125 #ifdef _KERNEL
  126 
  127 /*
  128  * macros to use the history/tracing code.  note that KERNHIST_LOG
  129  * must take 4 arguments (even if they are ignored by the format).
  130  */
  131 #ifndef KERNHIST
  132 #define KERNHIST_DECL(NAME)
  133 #define KERNHIST_DEFINE(NAME)
  134 #define KERNHIST_INIT(NAME,N)
  135 #define KERNHIST_LOG(NAME,FMT,A,B,C,D)
  136 #define KERNHIST_CALLARGS(NAME,FMT,A,B,C,D)
  137 #define KERNHIST_CALLED(NAME)
  138 #define KERNHIST_FUNC(FNAME)
  139 #define KERNHIST_DUMP(NAME)
  140 #else
  141 #include <sys/kernel.h>         /* for "cold" variable */
  142 #include <sys/atomic.h>
  143 #include <sys/kmem.h>
  144 
  145 extern  struct kern_history_head kern_histories;
  146 
  147 #define KERNHIST_DECL(NAME) extern struct kern_history NAME
  148 #define KERNHIST_DEFINE(NAME) struct kern_history NAME
  149 
  150 #define KERNHIST_LINK_STATIC(NAME) \
  151 do { \
  152         LIST_INSERT_HEAD(&kern_histories, &(NAME), list); \
  153         sysctl_kernhist_new(&(NAME)); \
  154 } while (/*CONSTCOND*/ 0)
  155 
  156 #define KERNHIST_INIT(NAME,N) \
  157 do { \
  158         (NAME).name = __STRING(NAME); \
  159         (NAME).namelen = strlen(__STRING(NAME)); \
  160         (NAME).n = (N); \
  161         (NAME).f = 0; \
  162         (NAME).e = (struct kern_history_ent *) \
  163                 kmem_zalloc(sizeof(struct kern_history_ent) * (N), KM_SLEEP); \
  164         (NAME).s = 0; \
  165         KERNHIST_LINK_STATIC(NAME); \
  166 } while (/*CONSTCOND*/ 0)
  167 
  168 #define KERNHIST_INITIALIZER(NAME,BUF) \
  169 { \
  170         .name = __STRING(NAME), \
  171         .namelen = sizeof(__STRING(NAME)) - 1, \
  172         .n = sizeof(BUF) / sizeof(struct kern_history_ent), \
  173         .f = 0, \
  174         .e = (struct kern_history_ent *) (BUF), \
  175         .s = 0, \
  176         /* BUF will inititalized to zeroes by being in .bss */ \
  177 }
  178 
  179 #ifndef KERNHIST_DELAY
  180 #define KERNHIST_DELAY  100000
  181 #endif
  182 
  183 #if defined(KERNHIST_PRINT)
  184 extern int kernhist_print_enabled;
  185 #define KERNHIST_PRINTNOW(E) \
  186 do { \
  187                 if (kernhist_print_enabled) { \
  188                         kernhist_entry_print(E, printf); \
  189                         if (KERNHIST_DELAY != 0) \
  190                                 DELAY(KERNHIST_DELAY); \
  191                 } \
  192 } while (/*CONSTCOND*/ 0)
  193 #else
  194 #define KERNHIST_PRINTNOW(E) /* nothing */
  195 #endif
  196 
  197 #define KERNHIST_LOG(NAME,FMT,A,B,C,D) \
  198 do { \
  199         unsigned int _i_, _j_; \
  200         do { \
  201                 _i_ = (NAME).f; \
  202                 _j_ = (_i_ + 1 < (NAME).n) ? _i_ + 1 : 0; \
  203         } while (atomic_cas_uint(&(NAME).f, _i_, _j_) != _i_); \
  204         struct kern_history_ent * const _e_ = &(NAME).e[_i_]; \
  205         if (__predict_true(!cold)) \
  206                 bintime(&_e_->bt); \
  207         _e_->cpunum = (uint32_t)cpu_number(); \
  208         _e_->fmt = (FMT); \
  209         _e_->fmtlen = strlen(FMT); \
  210         _e_->fn = _kernhist_name; \
  211         _e_->fnlen = strlen(_kernhist_name); \
  212         _e_->call = _kernhist_call; \
  213         _e_->v[0] = (uintmax_t)(A); \
  214         _e_->v[1] = (uintmax_t)(B); \
  215         _e_->v[2] = (uintmax_t)(C); \
  216         _e_->v[3] = (uintmax_t)(D); \
  217         KERNHIST_PRINTNOW(_e_); \
  218 } while (/*CONSTCOND*/ 0)
  219 
  220 #define KERNHIST_CALLED(NAME) \
  221 do { \
  222         _kernhist_call = atomic_inc_32_nv(&_kernhist_cnt); \
  223         KERNHIST_LOG(NAME, "called!", 0, 0, 0, 0); \
  224 } while (/*CONSTCOND*/ 0)
  225 
  226 /*
  227  * This extends kernhist to avoid wasting a separate "called!" entry on every
  228  * function.
  229  */
  230 #define KERNHIST_CALLARGS(NAME, FMT, A, B, C, D) \
  231 do { \
  232         _kernhist_call = atomic_inc_32_nv(&_kernhist_cnt); \
  233         KERNHIST_LOG(NAME, "called: "FMT, (A), (B), (C), (D)); \
  234 } while (/*CONSTCOND*/ 0)
  235 
  236 #define KERNHIST_FUNC(FNAME) \
  237         static uint32_t _kernhist_cnt = 0; \
  238         static const char *const _kernhist_name = FNAME; \
  239         uint32_t _kernhist_call = 0;
  240 
  241 #ifdef DDB
  242 #define KERNHIST_DUMP(NAME)     kernhist_dump(&NAME, 0, printf)
  243 #else
  244 #define KERNHIST_DUMP(NAME)
  245 #endif
  246 
  247 static __inline void
  248 kernhist_entry_print(const struct kern_history_ent *e, void (*pr)(const char *, ...) __printflike(1, 2))
  249 {
  250         struct timeval tv;
  251 
  252         bintime2timeval(&e->bt, &tv);
  253         pr("%06ld.%06ld ", (long int)tv.tv_sec, (long int)tv.tv_usec);
  254         pr("%s#%" PRIu32 "@%" PRIu32 ": ", e->fn, e->call, e->cpunum);
  255         pr(e->fmt, e->v[0], e->v[1], e->v[2], e->v[3]);
  256         pr("\n");
  257 }
  258 
  259 #if defined(DDB)
  260 void    kernhist_dump(struct kern_history *, size_t, void (*)(const char *, ...) __printflike(1, 2));
  261 void    kernhist_print(void *, size_t, const char *, void (*)(const char *, ...) __printflike(1, 2));
  262 #endif /* DDB */
  263 
  264 void sysctl_kernhist_init(void);
  265 void sysctl_kernhist_new(struct kern_history *);
  266 
  267 #endif /* KERNHIST */
  268 
  269 #endif /* _KERNEL */
  270 
  271 #endif /* _SYS_KERNHIST_H_ */

Cache object: 0baf5fe6c573283fbcb54482e5bd60b4


[ 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.