rf_acctrace.c revision 1.1 1 1.1 oster /* $NetBSD: rf_acctrace.c,v 1.1 1998/11/13 04:20:26 oster Exp $ */
2 1.1 oster /*
3 1.1 oster * Copyright (c) 1995 Carnegie-Mellon University.
4 1.1 oster * All rights reserved.
5 1.1 oster *
6 1.1 oster * Author: Mark Holland
7 1.1 oster *
8 1.1 oster * Permission to use, copy, modify and distribute this software and
9 1.1 oster * its documentation is hereby granted, provided that both the copyright
10 1.1 oster * notice and this permission notice appear in all copies of the
11 1.1 oster * software, derivative works or modified versions, and any portions
12 1.1 oster * thereof, and that both notices appear in supporting documentation.
13 1.1 oster *
14 1.1 oster * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 1.1 oster * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
16 1.1 oster * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 1.1 oster *
18 1.1 oster * Carnegie Mellon requests users of this software to return to
19 1.1 oster *
20 1.1 oster * Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
21 1.1 oster * School of Computer Science
22 1.1 oster * Carnegie Mellon University
23 1.1 oster * Pittsburgh PA 15213-3890
24 1.1 oster *
25 1.1 oster * any improvements or extensions that they make and grant Carnegie the
26 1.1 oster * rights to redistribute these changes.
27 1.1 oster */
28 1.1 oster
29 1.1 oster /*****************************************************************************
30 1.1 oster *
31 1.1 oster * acctrace.c -- code to support collecting information about each access
32 1.1 oster *
33 1.1 oster *****************************************************************************/
34 1.1 oster
35 1.1 oster /* :
36 1.1 oster * Log: rf_acctrace.c,v
37 1.1 oster * Revision 1.29 1996/07/27 23:36:08 jimz
38 1.1 oster * Solaris port of simulator
39 1.1 oster *
40 1.1 oster * Revision 1.28 1996/07/17 21:00:58 jimz
41 1.1 oster * clean up timer interface, tracing
42 1.1 oster *
43 1.1 oster * Revision 1.27 1996/06/14 14:35:24 jimz
44 1.1 oster * clean up dfstrace protection
45 1.1 oster *
46 1.1 oster * Revision 1.26 1996/06/13 19:09:04 jimz
47 1.1 oster * remove trace.dat file before beginning
48 1.1 oster *
49 1.1 oster * Revision 1.25 1996/06/12 04:41:26 jimz
50 1.1 oster * tweaks to make genplot work with user-level driver
51 1.1 oster * (mainly change stat collection)
52 1.1 oster *
53 1.1 oster * Revision 1.24 1996/06/10 11:55:47 jimz
54 1.1 oster * Straightened out some per-array/not-per-array distinctions, fixed
55 1.1 oster * a couple bugs related to confusion. Added shutdown lists. Removed
56 1.1 oster * layout shutdown function (now subsumed by shutdown lists).
57 1.1 oster *
58 1.1 oster * Revision 1.23 1996/06/09 02:36:46 jimz
59 1.1 oster * lots of little crufty cleanup- fixup whitespace
60 1.1 oster * issues, comment #ifdefs, improve typing in some
61 1.1 oster * places (esp size-related)
62 1.1 oster *
63 1.1 oster * Revision 1.22 1996/06/05 18:06:02 jimz
64 1.1 oster * Major code cleanup. The Great Renaming is now done.
65 1.1 oster * Better modularity. Better typing. Fixed a bunch of
66 1.1 oster * synchronization bugs. Made a lot of global stuff
67 1.1 oster * per-desc or per-array. Removed dead code.
68 1.1 oster *
69 1.1 oster * Revision 1.21 1996/05/31 22:26:54 jimz
70 1.1 oster * fix a lot of mapping problems, memory allocation problems
71 1.1 oster * found some weird lock issues, fixed 'em
72 1.1 oster * more code cleanup
73 1.1 oster *
74 1.1 oster * Revision 1.20 1996/05/30 23:22:16 jimz
75 1.1 oster * bugfixes of serialization, timing problems
76 1.1 oster * more cleanup
77 1.1 oster *
78 1.1 oster * Revision 1.19 1996/05/30 12:59:18 jimz
79 1.1 oster * make etimer happier, more portable
80 1.1 oster *
81 1.1 oster * Revision 1.18 1996/05/27 18:56:37 jimz
82 1.1 oster * more code cleanup
83 1.1 oster * better typing
84 1.1 oster * compiles in all 3 environments
85 1.1 oster *
86 1.1 oster * Revision 1.17 1996/05/23 00:33:23 jimz
87 1.1 oster * code cleanup: move all debug decls to rf_options.c, all extern
88 1.1 oster * debug decls to rf_options.h, all debug vars preceded by rf_
89 1.1 oster *
90 1.1 oster * Revision 1.16 1996/05/20 16:15:49 jimz
91 1.1 oster * switch to rf_{mutex,cond}_{init,destroy}
92 1.1 oster *
93 1.1 oster * Revision 1.15 1996/05/18 20:10:00 jimz
94 1.1 oster * bit of cleanup to compile cleanly in kernel, once again
95 1.1 oster *
96 1.1 oster * Revision 1.14 1996/05/18 19:51:34 jimz
97 1.1 oster * major code cleanup- fix syntax, make some types consistent,
98 1.1 oster * add prototypes, clean out dead code, et cetera
99 1.1 oster *
100 1.1 oster * Revision 1.13 1995/11/30 16:26:43 wvcii
101 1.1 oster * added copyright info
102 1.1 oster *
103 1.1 oster */
104 1.1 oster
105 1.1 oster #ifdef _KERNEL
106 1.1 oster #define KERNEL
107 1.1 oster #endif
108 1.1 oster
109 1.1 oster #include "rf_threadstuff.h"
110 1.1 oster #include "rf_types.h"
111 1.1 oster #include <sys/stat.h>
112 1.1 oster #include <sys/types.h>
113 1.1 oster
114 1.1 oster #ifdef KERNEL
115 1.1 oster #ifndef __NetBSD__
116 1.1 oster #include <dfstrace.h>
117 1.1 oster #endif /* !__NetBSD__ */
118 1.1 oster #if DFSTRACE > 0
119 1.1 oster #include <sys/dfs_log.h>
120 1.1 oster #include <sys/dfstracebuf.h>
121 1.1 oster #endif /* DFSTRACE > 0 */
122 1.1 oster #endif /* KERNEL */
123 1.1 oster
124 1.1 oster #include "rf_debugMem.h"
125 1.1 oster #include "rf_acctrace.h"
126 1.1 oster #include "rf_general.h"
127 1.1 oster #include "rf_raid.h"
128 1.1 oster #include "rf_etimer.h"
129 1.1 oster #include "rf_hist.h"
130 1.1 oster #include "rf_shutdown.h"
131 1.1 oster #include "rf_sys.h"
132 1.1 oster
133 1.1 oster static long numTracesSoFar;
134 1.1 oster static int accessTraceBufCount = 0;
135 1.1 oster static RF_AccTraceEntry_t *access_tracebuf;
136 1.1 oster static long traceCount;
137 1.1 oster
138 1.1 oster int rf_stopCollectingTraces;
139 1.1 oster RF_DECLARE_MUTEX(rf_tracing_mutex)
140 1.1 oster int rf_trace_fd;
141 1.1 oster
142 1.1 oster static void rf_ShutdownAccessTrace(void *);
143 1.1 oster
144 1.1 oster static void rf_ShutdownAccessTrace(ignored)
145 1.1 oster void *ignored;
146 1.1 oster {
147 1.1 oster if (rf_accessTraceBufSize) {
148 1.1 oster if (accessTraceBufCount) rf_FlushAccessTraceBuf();
149 1.1 oster #ifndef KERNEL
150 1.1 oster close(rf_trace_fd);
151 1.1 oster #endif /* !KERNEL */
152 1.1 oster RF_Free(access_tracebuf, rf_accessTraceBufSize * sizeof(RF_AccTraceEntry_t));
153 1.1 oster }
154 1.1 oster rf_mutex_destroy(&rf_tracing_mutex);
155 1.1 oster #if defined(KERNEL) && DFSTRACE > 0
156 1.1 oster printf("RAIDFRAME: %d trace entries were sent to dfstrace\n",traceCount);
157 1.1 oster #endif /* KERNEL && DFSTRACE > 0 */
158 1.1 oster }
159 1.1 oster
160 1.1 oster int rf_ConfigureAccessTrace(listp)
161 1.1 oster RF_ShutdownList_t **listp;
162 1.1 oster {
163 1.1 oster int rc;
164 1.1 oster
165 1.1 oster numTracesSoFar = accessTraceBufCount = rf_stopCollectingTraces = 0;
166 1.1 oster if (rf_accessTraceBufSize) {
167 1.1 oster RF_Malloc(access_tracebuf, rf_accessTraceBufSize * sizeof(RF_AccTraceEntry_t), (RF_AccTraceEntry_t *));
168 1.1 oster accessTraceBufCount = 0;
169 1.1 oster #ifndef KERNEL
170 1.1 oster rc = unlink("trace.dat");
171 1.1 oster if (rc && (errno != ENOENT)) {
172 1.1 oster perror("unlink");
173 1.1 oster RF_ERRORMSG("Unable to remove existing trace.dat\n");
174 1.1 oster return(errno);
175 1.1 oster }
176 1.1 oster if ((rf_trace_fd = open("trace.dat",O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0 ) {
177 1.1 oster perror("Unable to open trace.dat for output");
178 1.1 oster return(errno);
179 1.1 oster }
180 1.1 oster #endif /* !KERNEL */
181 1.1 oster }
182 1.1 oster traceCount = 0;
183 1.1 oster numTracesSoFar = 0;
184 1.1 oster rc = rf_mutex_init(&rf_tracing_mutex);
185 1.1 oster if (rc) {
186 1.1 oster RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d\n", __FILE__,
187 1.1 oster __LINE__, rc);
188 1.1 oster }
189 1.1 oster rc = rf_ShutdownCreate(listp, rf_ShutdownAccessTrace, NULL);
190 1.1 oster if (rc) {
191 1.1 oster RF_ERRORMSG3("Unable to add to shutdown list file %s line %d rc=%d\n", __FILE__,
192 1.1 oster __LINE__, rc);
193 1.1 oster if (rf_accessTraceBufSize) {
194 1.1 oster RF_Free(access_tracebuf, rf_accessTraceBufSize * sizeof(RF_AccTraceEntry_t));
195 1.1 oster #ifndef KERNEL
196 1.1 oster close(rf_trace_fd);
197 1.1 oster #endif /* !KERNEL */
198 1.1 oster rf_mutex_destroy(&rf_tracing_mutex);
199 1.1 oster }
200 1.1 oster }
201 1.1 oster return(rc);
202 1.1 oster }
203 1.1 oster
204 1.1 oster /* install a trace record. cause a flush to disk or to the trace collector daemon
205 1.1 oster * if the trace buffer is at least 1/2 full.
206 1.1 oster */
207 1.1 oster void rf_LogTraceRec(raid, rec)
208 1.1 oster RF_Raid_t *raid;
209 1.1 oster RF_AccTraceEntry_t *rec;
210 1.1 oster {
211 1.1 oster RF_AccTotals_t *acc = &raid->acc_totals;
212 1.1 oster #if 0
213 1.1 oster RF_Etimer_t timer;
214 1.1 oster int i, n;
215 1.1 oster #endif
216 1.1 oster
217 1.1 oster if (rf_stopCollectingTraces || ((rf_maxNumTraces >= 0) && (numTracesSoFar >= rf_maxNumTraces)))
218 1.1 oster return;
219 1.1 oster
220 1.1 oster #ifndef KERNEL
221 1.1 oster if (rf_accessTraceBufSize) {
222 1.1 oster RF_LOCK_MUTEX(rf_tracing_mutex);
223 1.1 oster numTracesSoFar++;
224 1.1 oster bcopy((char *)rec, (char *)&access_tracebuf[ accessTraceBufCount++ ], sizeof(RF_AccTraceEntry_t));
225 1.1 oster if (accessTraceBufCount == rf_accessTraceBufSize)
226 1.1 oster rf_FlushAccessTraceBuf();
227 1.1 oster RF_UNLOCK_MUTEX(rf_tracing_mutex);
228 1.1 oster }
229 1.1 oster #endif /* !KERNEL */
230 1.1 oster #if defined(KERNEL) && DFSTRACE > 0
231 1.1 oster rec->index = traceCount++;
232 1.1 oster if (traceon & DFS_TRACE_RAIDFRAME) {
233 1.1 oster dfs_log(DFS_NOTE, (char *) rec, (int) sizeof(*rec), 0);
234 1.1 oster }
235 1.1 oster #endif /* KERNEL && DFSTRACE > 0 */
236 1.1 oster /* update AccTotals for this device */
237 1.1 oster if (!raid->keep_acc_totals)
238 1.1 oster return;
239 1.1 oster acc->num_log_ents++;
240 1.1 oster if (rec->reconacc) {
241 1.1 oster acc->recon_start_to_fetch_us += rec->specific.recon.recon_start_to_fetch_us;
242 1.1 oster acc->recon_fetch_to_return_us += rec->specific.recon.recon_fetch_to_return_us;
243 1.1 oster acc->recon_return_to_submit_us += rec->specific.recon.recon_return_to_submit_us;
244 1.1 oster acc->recon_num_phys_ios += rec->num_phys_ios;
245 1.1 oster acc->recon_phys_io_us += rec->phys_io_us;
246 1.1 oster acc->recon_diskwait_us += rec->diskwait_us;
247 1.1 oster acc->recon_reccount++;
248 1.1 oster }
249 1.1 oster else {
250 1.1 oster RF_HIST_ADD(acc->tot_hist, rec->total_us);
251 1.1 oster RF_HIST_ADD(acc->dw_hist, rec->diskwait_us);
252 1.1 oster /* count of physical ios which are too big. often due to thermal recalibration */
253 1.1 oster /* if bigvals > 0, you should probably ignore this data set */
254 1.1 oster if (rec->diskwait_us > 100000)
255 1.1 oster acc->bigvals++;
256 1.1 oster acc->total_us += rec->total_us;
257 1.1 oster acc->suspend_ovhd_us += rec->specific.user.suspend_ovhd_us;
258 1.1 oster acc->map_us += rec->specific.user.map_us;
259 1.1 oster acc->lock_us += rec->specific.user.lock_us;
260 1.1 oster acc->dag_create_us += rec->specific.user.dag_create_us;
261 1.1 oster acc->dag_retry_us += rec->specific.user.dag_retry_us;
262 1.1 oster acc->exec_us += rec->specific.user.exec_us;
263 1.1 oster acc->cleanup_us += rec->specific.user.cleanup_us;
264 1.1 oster acc->exec_engine_us += rec->specific.user.exec_engine_us;
265 1.1 oster acc->xor_us += rec->xor_us;
266 1.1 oster acc->q_us += rec->q_us;
267 1.1 oster acc->plog_us += rec->plog_us;
268 1.1 oster acc->diskqueue_us += rec->diskqueue_us;
269 1.1 oster acc->diskwait_us += rec->diskwait_us;
270 1.1 oster acc->num_phys_ios += rec->num_phys_ios;
271 1.1 oster acc->phys_io_us = rec->phys_io_us;
272 1.1 oster acc->user_reccount++;
273 1.1 oster }
274 1.1 oster }
275 1.1 oster
276 1.1 oster
277 1.1 oster /* assumes the tracing mutex is locked at entry. In order to allow this to be called
278 1.1 oster * from interrupt context, we don't do any copyouts here, but rather just wake trace
279 1.1 oster * buffer collector thread.
280 1.1 oster */
281 1.1 oster void rf_FlushAccessTraceBuf()
282 1.1 oster {
283 1.1 oster #ifndef KERNEL
284 1.1 oster int size = accessTraceBufCount * sizeof(RF_AccTraceEntry_t);
285 1.1 oster
286 1.1 oster if (write(rf_trace_fd, (char *) access_tracebuf, size) < size ) {
287 1.1 oster fprintf(stderr, "Unable to write traces to file. tracing disabled\n");
288 1.1 oster RF_Free(access_tracebuf, rf_accessTraceBufSize * sizeof(RF_AccTraceEntry_t));
289 1.1 oster rf_accessTraceBufSize = 0;
290 1.1 oster close(rf_trace_fd);
291 1.1 oster }
292 1.1 oster #endif /* !KERNEL */
293 1.1 oster accessTraceBufCount = 0;
294 1.1 oster }
295