Annotation of src/sys/dev/lockstat.h, Revision 1.9.8.1
1.9.8.1 ! skrll 1: /* $NetBSD: lockstat.h,v 1.10 2009/01/20 14:49:00 yamt Exp $ */
1.1 ad 2:
3: /*-
4: * Copyright (c) 2006 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Andrew Doran.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29: * POSSIBILITY OF SUCH DAMAGE.
30: */
31:
32: #ifndef _SYS_LOCKSTAT_H_
33: #define _SYS_LOCKSTAT_H_
34:
35: #ifdef _KERNEL_OPT
36: #include <lockstat.h>
37: #endif
38:
39: #include <sys/types.h>
40: #include <sys/ioccom.h>
41: #include <sys/queue.h>
42: #include <sys/time.h>
43:
44: #if defined(_KERNEL) && defined(__HAVE_CPU_COUNTER)
45: #include <machine/cpu_counter.h>
46: #endif
47:
48: /*
49: * Interface version. The interface is not designed to provide
50: * compatibility across NetBSD releases.
51: */
52:
53: #define IOC_LOCKSTAT_GVERSION _IOR('L', 0, int)
54:
1.9.8.1 ! skrll 55: #define LS_VERSION 5
1.1 ad 56:
57: /*
58: * Enable request. We can limit tracing by the call site and by
59: * the lock. We also specify the number of event buffers to
60: * allocate up front, and what kind of events to track.
61: */
62:
63: #define IOC_LOCKSTAT_ENABLE _IOW('L', 1, lsenable_t)
64:
65: #define LE_CALLSITE 0x01 /* track call sites */
66: #define LE_ONE_CALLSITE 0x02 /* specific call site */
67: #define LE_ONE_LOCK 0x04 /* specific lock */
1.5 ad 68: #define LE_LOCK 0x08 /* track locks */
1.1 ad 69:
70: typedef struct lsenable {
71: uintptr_t le_csstart; /* callsite start */
72: uintptr_t le_csend; /* callsite end */
1.2 ad 73: uintptr_t le_lockstart; /* lock address start */
74: uintptr_t le_lockend; /* lock address end */
1.1 ad 75: uintptr_t le_nbufs; /* buffers to allocate, 0 = default */
76: u_int le_flags; /* request flags */
77: u_int le_mask; /* event mask (LB_*) */
78: } lsenable_t;
79:
80: /*
81: * Disable request.
82: */
83:
84: #define IOC_LOCKSTAT_DISABLE _IOR('L', 2, lsdisable_t)
85:
86: typedef struct lsdisable {
87: size_t ld_size; /* buffer space allocated */
88: struct timespec ld_time; /* time spent enabled */
89: uint64_t ld_freq[64]; /* counter HZ by CPU number */
90: } lsdisable_t;
91:
92: /*
93: * Event buffers returned from reading from the devices.
94: */
95:
96: /*
97: * Event types, for lockstat_event(). Stored in lb_flags but should be
98: * meaningless to the consumer, also provided with the enable request
99: * in le_mask.
100: */
101: #define LB_SPIN 0x00000001
1.2 ad 102: #define LB_SLEEP1 0x00000002
103: #define LB_SLEEP2 0x00000003
104: #define LB_NEVENT 0x00000003
1.1 ad 105: #define LB_EVENT_MASK 0x000000ff
106:
107: /*
108: * Lock types, the only part of lb_flags that should be inspected. Also
109: * provided with the enable request in le_mask.
110: */
111: #define LB_ADAPTIVE_MUTEX 0x00000100
1.2 ad 112: #define LB_SPIN_MUTEX 0x00000200
113: #define LB_RWLOCK 0x00000300
1.8 ad 114: #define LB_NOPREEMPT 0x00000400
1.2 ad 115: #define LB_KERNEL_LOCK 0x00000500
1.4 ad 116: #define LB_MISC 0x00000600
117: #define LB_NLOCK 0x00000600
1.1 ad 118: #define LB_LOCK_MASK 0x0000ff00
119: #define LB_LOCK_SHIFT 8
120:
121: typedef struct lsbuf {
122: union {
123: LIST_ENTRY(lsbuf) list;
124: SLIST_ENTRY(lsbuf) slist;
125: TAILQ_ENTRY(lsbuf) tailq;
126: } lb_chain;
127: uintptr_t lb_lock; /* lock address */
128: uintptr_t lb_callsite; /* call site */
129: uint64_t lb_times[LB_NEVENT]; /* cumulative times */
130: uint32_t lb_counts[LB_NEVENT]; /* count of events */
131: uint16_t lb_flags; /* lock type */
132: uint16_t lb_cpu; /* CPU number */
133: } lsbuf_t;
134:
135: /*
1.6 ad 136: * Tracing stubs used by lock providers.
1.1 ad 137: */
138:
139: #if defined(_KERNEL) && defined(__HAVE_CPU_COUNTER) && NLOCKSTAT > 0
140:
1.4 ad 141: #define LOCKSTAT_EVENT(flag, lock, type, count, time) \
1.1 ad 142: do { \
1.4 ad 143: if (__predict_false(flag)) \
1.1 ad 144: lockstat_event((uintptr_t)(lock), \
145: (uintptr_t)__builtin_return_address(0), \
146: (type), (count), (time)); \
147: } while (/* CONSTCOND */ 0);
148:
1.4 ad 149: #define LOCKSTAT_EVENT_RA(flag, lock, type, count, time, ra) \
1.1 ad 150: do { \
1.4 ad 151: if (__predict_false(flag)) \
1.1 ad 152: lockstat_event((uintptr_t)(lock), (uintptr_t)ra, \
153: (type), (count), (time)); \
154: } while (/* CONSTCOND */ 0);
155:
156: #define LOCKSTAT_TIMER(name) uint64_t name = 0
157: #define LOCKSTAT_COUNTER(name) uint64_t name = 0
1.4 ad 158: #define LOCKSTAT_FLAG(name) int name
159: #define LOCKSTAT_ENTER(name) name = lockstat_enabled
160: #define LOCKSTAT_EXIT(name)
1.1 ad 161:
1.4 ad 162: #define LOCKSTAT_START_TIMER(flag, name) \
1.1 ad 163: do { \
1.4 ad 164: if (__predict_false(flag)) \
165: (name) -= cpu_counter(); \
1.1 ad 166: } while (/* CONSTCOND */ 0)
167:
1.4 ad 168: #define LOCKSTAT_STOP_TIMER(flag, name) \
1.1 ad 169: do { \
1.4 ad 170: if (__predict_false(flag)) \
171: (name) += cpu_counter(); \
1.1 ad 172: } while (/* CONSTCOND */ 0)
173:
174: #define LOCKSTAT_COUNT(name, inc) \
175: do { \
176: (name) += (inc); \
177: } while (/* CONSTCOND */ 0)
178:
179: void lockstat_event(uintptr_t, uintptr_t, u_int, u_int, uint64_t);
180:
181: extern volatile u_int lockstat_enabled;
182:
183: #else
184:
1.4 ad 185: #define LOCKSTAT_FLAG(name) /* nothing */
186: #define LOCKSTAT_ENTER(name) /* nothing */
187: #define LOCKSTAT_EXIT(name) /* nothing */
188: #define LOCKSTAT_EVENT(flag, lock, type, count, time) /* nothing */
189: #define LOCKSTAT_EVENT_RA(flag, lock, type, count, time, ra) /* nothing */
190: #define LOCKSTAT_TIMER(void) /* nothing */
191: #define LOCKSTAT_COUNTER(void) /* nothing */
192: #define LOCKSTAT_START_TIMER(flag, void) /* nothing */
193: #define LOCKSTAT_STOP_TIMER(flag, void) /* nothing */
194: #define LOCKSTAT_COUNT(name, int) /* nothing */
1.1 ad 195:
196: #endif
197:
198: #endif /* _SYS_LOCKSTAT_H_ */
CVSweb <webmaster@jp.NetBSD.org>