4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
30 #include <sys/inttypes.h>
37 #include "sdbc_stats.h"
43 * Return the number of ticks delta between two hrtime_t
44 * values. Attempt to cater for various kinds of overflow
45 * in hrtime_t - no matter how improbable.
48 hrtime_delta(hrtime_t old
, hrtime_t
new)
53 if ((new >= old
) && (old
>= 0L)) {
57 * We've overflowed the positive portion of an
62 * The new value is negative. Handle the
63 * case where the old value is positive or
80 * Either we've just gone from being negative
81 * to positive *or* the last entry was positive
82 * and the new entry is also positive but *less*
83 * than the old entry. This implies we waited
84 * quite a few days on a very fast system between
91 del
= UINT64_MAX
- o2
;
93 del
= UINT64_MAX
- old
;
104 * Take the difference of an unsigned 32
105 * bit int attempting to cater for
109 u32_delta(uint32_t old
, uint32_t new)
115 return ((UINT32_MAX
- old
) + new + 1);
119 * Take the difference of an unsigned 64
120 * bit int attempting to cater for
124 u64_delta(uint64_t old
, uint64_t new)
130 return ((UINT64_MAX
- old
) + new + 1);
134 * io_report() - diffs and reports data contained in
135 * kstat_io_t structures.
138 * kstat_io_t *cur - pointer to current data
140 * kstat_io_t *pre - pointer to data as it was
141 * at the beginning of an interval.
144 io_report(kstat_t
*cur_kstat
, kstat_t
*pre_kstat
, sdbcstat_t
*sdbcstat
)
148 double rd_cnt
, wr_cnt
;
149 double rd_kb
, wr_kb
, hr_etime
;
151 double rtm
, tps
, avs
, etime
;
153 kstat_io_t
*cur
= cur_kstat
->ks_data
;
154 kstat_io_t
*pre
= pre_kstat
->ks_data
;
157 sdbc_getvalues(sdbcstat
, &vals
, (SDBC_KBYTES
| SDBC_INTAVG
)))
161 hr_etime
= hrtime_delta(pre_kstat
->ks_snaptime
, cur_kstat
->ks_snaptime
);
162 etime
= hr_etime
/ (double)NANOSEC
;
165 rd_cnt
= (double)u32_delta(pre
->reads
, cur
->reads
);
166 if (rd_cnt
) rd_cnt
/= etime
;
169 rd_kb
= (double)u64_delta(pre
->nread
, cur
->nread
) / KILOBYTE
;
170 if (rd_kb
) rd_kb
/= etime
;
173 wr_cnt
= (double)u32_delta(pre
->writes
, cur
->writes
);
174 if (wr_cnt
) wr_cnt
/= etime
;
177 wr_kb
= (double)u64_delta(pre
->nwritten
, cur
->nwritten
) / KILOBYTE
;
178 if (wr_kb
) wr_kb
/= etime
;
180 /* Calculate service times */
181 avs
= (double)hrtime_delta(pre
->rlentime
, cur
->rlentime
) / hr_etime
;
182 tps
= (double)rd_cnt
+ wr_cnt
;
185 rtm
= (1000 / tps
) * avs
;
190 if (dflags
& SUMMARY
) {
191 if ((mode
& MULTI
) && (mode
& SDBC
)) {
193 (void) printf(KPS_INF_FMT
,
194 (float)vals
.total_cache
);
195 (void) printf(KPS_INF_FMT
,
196 (float)vals
.total_disk
);
198 (void) printf(DATA_C6
, NO_INFO
);
199 (void) printf(KPS_INF_FMT
, rd_kb
+ wr_kb
);
202 (void) printf(KPS_INF_FMT
, rd_kb
+ wr_kb
);
204 (void) printf(TPS_INF_FMT
, (uint32_t)(rd_cnt
+ wr_cnt
));
205 (void) printf(SVT_INF_FMT
, rtm
);
211 if ((mode
& MULTI
) && (mode
& SDBC
)) {
213 (void) printf(KPS_INF_FMT
,
214 (float)vals
.cache_read
);
215 (void) printf(KPS_INF_FMT
,
216 (float)vals
.disk_read
);
218 (void) printf(DATA_C6
, NO_INFO
);
219 (void) printf(KPS_INF_FMT
, rd_kb
);
223 (void) printf(KPS_INF_FMT
, rd_kb
);
225 (void) printf(TPS_INF_FMT
, (uint32_t)rd_cnt
);
228 if (dflags
& WRITE
) {
229 if ((mode
& MULTI
) && (mode
& SDBC
)) {
231 (void) printf(KPS_INF_FMT
,
232 (float)vals
.cache_write
);
233 (void) printf(KPS_INF_FMT
,
234 (float)vals
.disk_write
);
236 (void) printf(DATA_C6
, NO_INFO
);
237 (void) printf(KPS_INF_FMT
, wr_kb
);
241 (void) printf(KPS_INF_FMT
, wr_kb
);
243 (void) printf(TPS_INF_FMT
, (uint32_t)wr_cnt
);
246 if (dflags
& TIMING
) {
247 (void) printf(SVT_INF_FMT
, rtm
);
255 io_value_check(kstat_io_t
*pre
, kstat_io_t
*cur
)
257 if (u32_delta(pre
->reads
, cur
->reads
))
259 if (u32_delta(pre
->writes
, cur
->writes
))
266 * cd_report() - reports cache desriptor related statistics
267 * based on the dflags global variable
270 * sdbcstat_t *sdbcstat - pointer to the cache structure
274 cd_report(sdbcstat_t
*sdbcstat
)
278 /* Extract statistics, average for time */
279 if (sdbc_getvalues(sdbcstat
, &vals
, (SDBC_KBYTES
| SDBC_INTAVG
)))
283 if (rflags
& MULTI
) {
284 (void) printf(VOL_HDR_FMT
, "");
286 if (dflags
& FLAGS
) {
287 (void) printf(STAT_HDR_FMT
, "");
288 (void) printf(STAT_HDR_FMT
, "");
292 (void) printf(PCT_HDR_FMT
, "");
294 if (dflags
& SUMMARY
) {
295 (void) printf(KPS_INF_FMT
, (float)vals
.total_cache
);
296 (void) printf(DATA_C4
, NO_INFO
);
297 (void) printf(DATA_C4
, NO_INFO
);
304 (void) printf(KPS_INF_FMT
, (float)vals
.cache_read
);
305 (void) printf(DATA_C4
, NO_INFO
);
308 if (dflags
& WRITE
) {
309 (void) printf(KPS_INF_FMT
, (float)vals
.cache_write
);
310 (void) printf(DATA_C4
, NO_INFO
);
313 if (dflags
& TIMING
) {
314 (void) printf(DATA_C4
, NO_INFO
);
322 if (dflags
& SUMMARY
) {
323 (void) printf(DATA_I32
, vals
.total_cache
);
324 (void) printf(DATA_I32
, vals
.total_disk
);
325 (void) printf(HIT_INF_FMT
, vals
.cache_hit
);
333 (void) printf(DATA_I32
, vals
.cache_read
);
334 (void) printf(DATA_I32
, vals
.disk_read
);
335 (void) printf(HIT_INF_FMT
, vals
.read_hit
);
338 if (dflags
& WRITE
) {
339 (void) printf(DATA_I32
, vals
.cache_write
);
340 (void) printf(DATA_I32
, vals
.disk_write
);
341 (void) printf(HIT_INF_FMT
, vals
.write_hit
);
344 if (dflags
& DESTAGED
)
345 (void) printf(DATA_I32
, vals
.destaged
);
347 if (dflags
& WRCANCEL
)
348 (void) printf(DATA_I32
, vals
.write_cancellations
);
355 * header() - outputs an appropriate header by referencing the
356 * global variables dflsgs and rflags
362 if (hflags
& HEADERS_EXL
)
363 if ((linesout
% DISPLAY_LINES
) != 0)
366 if (hflags
& HEADERS_BOR
)
370 if (hflags
& HEADERS_ATT
)
371 if (hflags
& HEADERS_OUT
)
374 hflags
|= HEADERS_OUT
;
379 (void) printf(VOL_HDR_FMT
, SET_HDR_TXT
);
381 if (dflags
& FLAGS
) {
382 (void) printf(STAT_HDR_FMT
, TYPE_HDR_TXT
);
383 (void) printf(STAT_HDR_FMT
, STAT_HDR_TXT
);
386 if (dflags
& ASYNC_QUEUE
)
387 (void) printf(STAT_HDR_FMT
, QUEUE_HDR_TXT
);
390 (void) printf(PCT_HDR_FMT
, PCT_HDR_TXT
);
392 (void) printf(ROLE_HDR_FMT
, ROLE_HDR_TXT
);
394 if (dflags
& ASYNC_QUEUE
) {
395 (void) printf(TPS_HDR_FMT
, QUEUE_ITEMS_TXT
);
396 (void) printf(KPS_HDR_FMT
, QUEUE_KBYTES_TXT
);
397 (void) printf(TPS_HDR_FMT
, QUEUE_ITEMS_HW_TXT
);
398 (void) printf(KPS_HDR_FMT
, QUEUE_KBYTES_HW_TXT
);
401 if (dflags
& SUMMARY
) {
402 if ((mode
& MULTI
) && (mode
& SDBC
)) {
403 (void) printf(KPS_HDR_FMT
, CKPS_HDR_TXT
);
404 (void) printf(KPS_HDR_FMT
, DKPS_HDR_TXT
);
406 (void) printf(KPS_HDR_FMT
, KPS_HDR_TXT
);
407 (void) printf(TPS_HDR_FMT
, TPS_HDR_TXT
);
408 (void) printf(SVT_HDR_FMT
, SVT_HDR_TXT
);
416 if ((mode
& MULTI
) && (mode
& SDBC
)) {
417 (void) printf(KPS_HDR_FMT
, CRKPS_HDR_TXT
);
418 (void) printf(KPS_HDR_FMT
, DRKPS_HDR_TXT
);
420 (void) printf(KPS_HDR_FMT
, RKPS_HDR_TXT
);
422 (void) printf(TPS_HDR_FMT
, RTPS_HDR_TXT
);
425 if (dflags
& WRITE
) {
426 if ((mode
& MULTI
) && (mode
& SDBC
)) {
427 (void) printf(KPS_HDR_FMT
, CWKPS_HDR_TXT
);
428 (void) printf(KPS_HDR_FMT
, DWKPS_HDR_TXT
);
430 (void) printf(KPS_HDR_FMT
, WKPS_HDR_TXT
);
432 (void) printf(TPS_HDR_FMT
, WTPS_HDR_TXT
);
436 (void) printf(SVT_HDR_FMT
, SVT_HDR_TXT
);