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 (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2014, Joyent, Inc. All rights reserved.
24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
28 * Kernel statistics framework
31 #include <sys/types.h>
33 #include <sys/systm.h>
34 #include <sys/vmsystm.h>
35 #include <sys/t_lock.h>
36 #include <sys/param.h>
37 #include <sys/errno.h>
39 #include <sys/sysmacros.h>
40 #include <sys/cmn_err.h>
41 #include <sys/kstat.h>
42 #include <sys/sysinfo.h>
43 #include <sys/cpuvar.h>
44 #include <sys/fcntl.h>
45 #include <sys/flock.h>
46 #include <sys/vnode.h>
50 #include <sys/debug.h>
53 #include <sys/pool_pset.h>
54 #include <sys/cpupart.h>
56 #include <sys/loadavg.h>
59 #include <vm/seg_kmem.h>
62 * Global lock to protect the AVL trees and kstat_chain_id.
64 static kmutex_t kstat_chain_lock
;
67 * Every install/delete kstat bumps kstat_chain_id. This is used by:
69 * (1) /dev/kstat, to detect changes in the kstat chain across ioctls;
71 * (2) kstat_create(), to assign a KID (kstat ID) to each new kstat.
72 * /dev/kstat uses the KID as a cookie for kstat lookups.
74 * We reserve the first two IDs because some kstats are created before
75 * the well-known ones (kstat_headers = 0, kstat_types = 1).
77 * We also bump the kstat_chain_id if a zone is gaining or losing visibility
78 * into a particular kstat, which is logically equivalent to a kstat being
82 kid_t kstat_chain_id
= 2;
85 * As far as zones are concerned, there are 3 types of kstat:
87 * 1) Those which have a well-known name, and which should return per-zone data
88 * depending on which zone is doing the kstat_read(). sockfs:0:sock_unix_list
89 * is an example of this type of kstat.
91 * 2) Those which should only be exported to a particular list of zones.
92 * For example, in the case of nfs:*:mntinfo, we don't want zone A to be
93 * able to see NFS mounts associated with zone B, while we want the
94 * global zone to be able to see all mounts on the system.
96 * 3) Those that can be exported to all zones. Most system-related
97 * kstats fall within this category.
99 * An ekstat_t thus contains a list of kstats that the zone is to be
100 * exported to. The lookup of a name:instance:module thus translates to a
101 * lookup of name:instance:module:myzone; if the kstat is not exported
102 * to all zones, and does not have the caller's zoneid explicitly
103 * enumerated in the list of zones to be exported to, it is the same as
104 * if the kstat didn't exist.
106 * Writing to kstats is currently disallowed from within a non-global
107 * zone, although this restriction could be removed in the future.
109 typedef struct kstat_zone
{
111 struct kstat_zone
*next
;
115 * Extended kstat structure -- for internal use only.
117 typedef struct ekstat
{
118 kstat_t e_ks
; /* the kstat itself */
119 size_t e_size
; /* total allocation size */
120 kthread_t
*e_owner
; /* thread holding this kstat */
121 kcondvar_t e_cv
; /* wait for owner == NULL */
122 avl_node_t e_avl_bykid
; /* AVL tree to sort by KID */
123 avl_node_t e_avl_byname
; /* AVL tree to sort by name */
124 kstat_zone_t e_zone
; /* zone to export stats to */
127 static uint64_t kstat_initial
[8192];
128 static void *kstat_initial_ptr
= kstat_initial
;
129 static size_t kstat_initial_avail
= sizeof (kstat_initial
);
130 static vmem_t
*kstat_arena
;
132 #define KSTAT_ALIGN (sizeof (uint64_t))
134 static avl_tree_t kstat_avl_bykid
;
135 static avl_tree_t kstat_avl_byname
;
138 * Various pointers we need to create kstats at boot time in kstat_init()
140 extern kstat_named_t
*segmapcnt_ptr
;
141 extern uint_t segmapcnt_ndata
;
142 extern int segmap_kstat_update(kstat_t
*, int);
143 extern kstat_named_t
*biostats_ptr
;
144 extern uint_t biostats_ndata
;
145 extern kstat_named_t
*pollstats_ptr
;
146 extern uint_t pollstats_ndata
;
150 extern time_t boot_time
;
151 extern sysinfo_t sysinfo
;
152 extern vminfo_t vminfo
;
157 kstat_named_t deficit
;
158 kstat_named_t clk_intr
;
161 kstat_named_t avenrun_1min
;
162 kstat_named_t avenrun_5min
;
163 kstat_named_t avenrun_15min
;
164 kstat_named_t boot_time
;
165 kstat_named_t nsec_per_tick
;
166 } system_misc_kstat
= {
167 { "ncpus", KSTAT_DATA_UINT32
},
168 { "lbolt", KSTAT_DATA_UINT32
},
169 { "deficit", KSTAT_DATA_UINT32
},
170 { "clk_intr", KSTAT_DATA_UINT32
},
171 { "vac", KSTAT_DATA_UINT32
},
172 { "nproc", KSTAT_DATA_UINT32
},
173 { "avenrun_1min", KSTAT_DATA_UINT32
},
174 { "avenrun_5min", KSTAT_DATA_UINT32
},
175 { "avenrun_15min", KSTAT_DATA_UINT32
},
176 { "boot_time", KSTAT_DATA_UINT32
},
177 { "nsec_per_tick", KSTAT_DATA_UINT32
},
181 kstat_named_t physmem
;
182 kstat_named_t nalloc
;
184 kstat_named_t nalloc_calls
;
185 kstat_named_t nfree_calls
;
186 kstat_named_t kernelbase
;
187 kstat_named_t econtig
;
188 kstat_named_t freemem
;
189 kstat_named_t availrmem
;
190 kstat_named_t lotsfree
;
191 kstat_named_t desfree
;
192 kstat_named_t minfree
;
193 kstat_named_t fastscan
;
194 kstat_named_t slowscan
;
196 kstat_named_t desscan
;
197 kstat_named_t pp_kernel
;
198 kstat_named_t pagesfree
;
199 kstat_named_t pageslocked
;
200 kstat_named_t pagestotal
;
201 kstat_named_t lowmemscan
;
202 kstat_named_t nthrottle
;
203 } system_pages_kstat
= {
204 { "physmem", KSTAT_DATA_ULONG
},
205 { "nalloc", KSTAT_DATA_ULONG
},
206 { "nfree", KSTAT_DATA_ULONG
},
207 { "nalloc_calls", KSTAT_DATA_ULONG
},
208 { "nfree_calls", KSTAT_DATA_ULONG
},
209 { "kernelbase", KSTAT_DATA_ULONG
},
210 { "econtig", KSTAT_DATA_ULONG
},
211 { "freemem", KSTAT_DATA_ULONG
},
212 { "availrmem", KSTAT_DATA_ULONG
},
213 { "lotsfree", KSTAT_DATA_ULONG
},
214 { "desfree", KSTAT_DATA_ULONG
},
215 { "minfree", KSTAT_DATA_ULONG
},
216 { "fastscan", KSTAT_DATA_ULONG
},
217 { "slowscan", KSTAT_DATA_ULONG
},
218 { "nscan", KSTAT_DATA_ULONG
},
219 { "desscan", KSTAT_DATA_ULONG
},
220 { "pp_kernel", KSTAT_DATA_ULONG
},
221 { "pagesfree", KSTAT_DATA_ULONG
},
222 { "pageslocked", KSTAT_DATA_ULONG
},
223 { "pagestotal", KSTAT_DATA_ULONG
},
224 { "low_mem_scan", KSTAT_DATA_ULONG
},
225 { "n_throttle", KSTAT_DATA_ULONG
},
228 static int header_kstat_update(kstat_t
*, int);
229 static int header_kstat_snapshot(kstat_t
*, void *, int);
230 static int system_misc_kstat_update(kstat_t
*, int);
231 static int system_pages_kstat_update(kstat_t
*, int);
234 char name
[KSTAT_STRLEN
];
238 } kstat_data_type
[KSTAT_NUM_TYPES
] = {
239 { "raw", 1, 0, INT_MAX
},
240 { "name=value", sizeof (kstat_named_t
), 0, INT_MAX
},
241 { "interrupt", sizeof (kstat_intr_t
), 1, 1 },
242 { "i/o", sizeof (kstat_io_t
), 1, 1 },
243 { "event_timer", sizeof (kstat_timer_t
), 0, INT_MAX
},
247 kstat_zone_find(kstat_t
*k
, zoneid_t zoneid
)
249 ekstat_t
*e
= (ekstat_t
*)k
;
252 ASSERT(MUTEX_HELD(&kstat_chain_lock
));
253 for (kz
= &e
->e_zone
; kz
!= NULL
; kz
= kz
->next
) {
254 if (zoneid
== ALL_ZONES
|| kz
->zoneid
== ALL_ZONES
)
256 if (zoneid
== kz
->zoneid
)
263 kstat_zone_remove(kstat_t
*k
, zoneid_t zoneid
)
265 ekstat_t
*e
= (ekstat_t
*)k
;
266 kstat_zone_t
*kz
, *t
= NULL
;
268 mutex_enter(&kstat_chain_lock
);
269 if (zoneid
== e
->e_zone
.zoneid
) {
272 e
->e_zone
.zoneid
= kz
->zoneid
;
273 e
->e_zone
.next
= kz
->next
;
276 for (kz
= &e
->e_zone
; kz
->next
!= NULL
; kz
= kz
->next
) {
277 if (kz
->next
->zoneid
== zoneid
) {
283 ASSERT(t
!= NULL
); /* we removed something */
287 mutex_exit(&kstat_chain_lock
);
288 kmem_free(kz
, sizeof (*kz
));
292 kstat_zone_add(kstat_t
*k
, zoneid_t zoneid
)
294 ekstat_t
*e
= (ekstat_t
*)k
;
297 kz
= kmem_alloc(sizeof (*kz
), KM_NOSLEEP
);
300 mutex_enter(&kstat_chain_lock
);
302 kz
->next
= e
->e_zone
.next
;
305 mutex_exit(&kstat_chain_lock
);
309 * Compare the list of zones for the given kstats, returning 0 if they match
310 * (ie, one list contains ALL_ZONES or both lists contain the same zoneid).
311 * In practice, this is called indirectly by kstat_hold_byname(), so one of the
312 * two lists always has one element, and this is an O(n) operation rather than
316 kstat_zone_compare(ekstat_t
*e1
, ekstat_t
*e2
)
318 kstat_zone_t
*kz1
, *kz2
;
320 ASSERT(MUTEX_HELD(&kstat_chain_lock
));
321 for (kz1
= &e1
->e_zone
; kz1
!= NULL
; kz1
= kz1
->next
) {
322 for (kz2
= &e2
->e_zone
; kz2
!= NULL
; kz2
= kz2
->next
) {
323 if (kz1
->zoneid
== ALL_ZONES
||
324 kz2
->zoneid
== ALL_ZONES
)
326 if (kz1
->zoneid
== kz2
->zoneid
)
330 return (e1
->e_zone
.zoneid
< e2
->e_zone
.zoneid
? -1 : 1);
334 * Support for keeping kstats sorted in AVL trees for fast lookups.
337 kstat_compare_bykid(const void *a1
, const void *a2
)
339 const kstat_t
*k1
= a1
;
340 const kstat_t
*k2
= a2
;
342 if (k1
->ks_kid
< k2
->ks_kid
)
344 if (k1
->ks_kid
> k2
->ks_kid
)
346 return (kstat_zone_compare((ekstat_t
*)k1
, (ekstat_t
*)k2
));
350 kstat_compare_byname(const void *a1
, const void *a2
)
352 const kstat_t
*k1
= a1
;
353 const kstat_t
*k2
= a2
;
356 s
= strcmp(k1
->ks_module
, k2
->ks_module
);
362 if (k1
->ks_instance
< k2
->ks_instance
)
364 if (k1
->ks_instance
> k2
->ks_instance
)
367 s
= strcmp(k1
->ks_name
, k2
->ks_name
);
373 return (kstat_zone_compare((ekstat_t
*)k1
, (ekstat_t
*)k2
));
377 kstat_hold(avl_tree_t
*t
, ekstat_t
*template)
382 mutex_enter(&kstat_chain_lock
);
384 ksp
= avl_find(t
, template, NULL
);
388 if (e
->e_owner
== NULL
) {
389 e
->e_owner
= curthread
;
392 cv_wait(&e
->e_cv
, &kstat_chain_lock
);
394 mutex_exit(&kstat_chain_lock
);
399 kstat_rele(kstat_t
*ksp
)
401 ekstat_t
*e
= (ekstat_t
*)ksp
;
403 mutex_enter(&kstat_chain_lock
);
404 ASSERT(e
->e_owner
== curthread
);
406 cv_broadcast(&e
->e_cv
);
407 mutex_exit(&kstat_chain_lock
);
411 kstat_hold_bykid(kid_t kid
, zoneid_t zoneid
)
416 e
.e_zone
.zoneid
= zoneid
;
417 e
.e_zone
.next
= NULL
;
419 return (kstat_hold(&kstat_avl_bykid
, &e
));
423 kstat_hold_byname(const char *ks_module
, int ks_instance
, const char *ks_name
,
428 kstat_set_string(e
.e_ks
.ks_module
, ks_module
);
429 e
.e_ks
.ks_instance
= ks_instance
;
430 kstat_set_string(e
.e_ks
.ks_name
, ks_name
);
431 e
.e_zone
.zoneid
= ks_zoneid
;
432 e
.e_zone
.next
= NULL
;
433 return (kstat_hold(&kstat_avl_byname
, &e
));
437 kstat_alloc(size_t size
)
441 size
= P2ROUNDUP(sizeof (ekstat_t
) + size
, KSTAT_ALIGN
);
443 if (kstat_arena
== NULL
) {
444 if (size
<= kstat_initial_avail
) {
445 e
= kstat_initial_ptr
;
446 kstat_initial_ptr
= (char *)kstat_initial_ptr
+ size
;
447 kstat_initial_avail
-= size
;
450 e
= vmem_alloc(kstat_arena
, size
, VM_NOSLEEP
);
456 cv_init(&e
->e_cv
, NULL
, CV_DEFAULT
, NULL
);
463 kstat_free(ekstat_t
*e
)
465 cv_destroy(&e
->e_cv
);
466 vmem_free(kstat_arena
, e
, e
->e_size
);
470 * Create various system kstats.
477 avl_tree_t
*t
= &kstat_avl_bykid
;
480 * Set up the kstat vmem arena.
482 kstat_arena
= vmem_create("kstat",
483 kstat_initial
, sizeof (kstat_initial
), KSTAT_ALIGN
,
484 segkmem_alloc
, segkmem_free
, heap_arena
, 0, VM_SLEEP
);
487 * Make initial kstats appear as though they were allocated.
489 for (e
= avl_first(t
); e
!= NULL
; e
= avl_walk(t
, e
, AVL_AFTER
))
490 (void) vmem_xalloc(kstat_arena
, e
->e_size
, KSTAT_ALIGN
,
491 0, 0, e
, (char *)e
+ e
->e_size
,
492 VM_NOSLEEP
| VM_BESTFIT
| VM_PANIC
);
495 * The mother of all kstats. The first kstat in the system, which
496 * always has KID 0, has the headers for all kstats (including itself)
497 * as its data. Thus, the kstat driver does not need any special
498 * interface to extract the kstat chain.
501 ksp
= kstat_create("unix", 0, "kstat_headers", "kstat", KSTAT_TYPE_RAW
,
502 0, KSTAT_FLAG_VIRTUAL
| KSTAT_FLAG_VAR_SIZE
);
504 ksp
->ks_lock
= &kstat_chain_lock
;
505 ksp
->ks_update
= header_kstat_update
;
506 ksp
->ks_snapshot
= header_kstat_snapshot
;
509 panic("cannot create kstat 'kstat_headers'");
512 ksp
= kstat_create("unix", 0, "kstat_types", "kstat",
513 KSTAT_TYPE_NAMED
, KSTAT_NUM_TYPES
, 0);
516 kstat_named_t
*kn
= KSTAT_NAMED_PTR(ksp
);
518 for (i
= 0; i
< KSTAT_NUM_TYPES
; i
++) {
519 kstat_named_init(&kn
[i
], kstat_data_type
[i
].name
,
526 ksp
= kstat_create("unix", 0, "sysinfo", "misc", KSTAT_TYPE_RAW
,
527 sizeof (sysinfo_t
), KSTAT_FLAG_VIRTUAL
);
529 ksp
->ks_data
= (void *) &sysinfo
;
533 ksp
= kstat_create("unix", 0, "vminfo", "vm", KSTAT_TYPE_RAW
,
534 sizeof (vminfo_t
), KSTAT_FLAG_VIRTUAL
);
536 ksp
->ks_data
= (void *) &vminfo
;
540 ksp
= kstat_create("unix", 0, "segmap", "vm", KSTAT_TYPE_NAMED
,
541 segmapcnt_ndata
, KSTAT_FLAG_VIRTUAL
);
543 ksp
->ks_data
= (void *) segmapcnt_ptr
;
544 ksp
->ks_update
= segmap_kstat_update
;
548 ksp
= kstat_create("unix", 0, "biostats", "misc", KSTAT_TYPE_NAMED
,
549 biostats_ndata
, KSTAT_FLAG_VIRTUAL
);
551 ksp
->ks_data
= (void *) biostats_ptr
;
555 ksp
= kstat_create("unix", 0, "var", "misc", KSTAT_TYPE_RAW
,
556 sizeof (struct var
), KSTAT_FLAG_VIRTUAL
);
558 ksp
->ks_data
= (void *) &v
;
562 ksp
= kstat_create("unix", 0, "system_misc", "misc", KSTAT_TYPE_NAMED
,
563 sizeof (system_misc_kstat
) / sizeof (kstat_named_t
),
566 ksp
->ks_data
= (void *) &system_misc_kstat
;
567 ksp
->ks_update
= system_misc_kstat_update
;
571 ksp
= kstat_create("unix", 0, "system_pages", "pages", KSTAT_TYPE_NAMED
,
572 sizeof (system_pages_kstat
) / sizeof (kstat_named_t
),
575 ksp
->ks_data
= (void *) &system_pages_kstat
;
576 ksp
->ks_update
= system_pages_kstat_update
;
580 ksp
= kstat_create("poll", 0, "pollstats", "misc", KSTAT_TYPE_NAMED
,
581 pollstats_ndata
, KSTAT_FLAG_VIRTUAL
| KSTAT_FLAG_WRITABLE
);
584 ksp
->ks_data
= pollstats_ptr
;
590 * Caller of this should ensure that the string pointed by src
591 * doesn't change while kstat's lock is held. Not doing so defeats
592 * kstat's snapshot strategy as explained in <sys/kstat.h>
595 kstat_named_setstr(kstat_named_t
*knp
, const char *src
)
597 if (knp
->data_type
!= KSTAT_DATA_STRING
)
598 panic("kstat_named_setstr('%p', '%p'): "
599 "named kstat is not of type KSTAT_DATA_STRING",
600 (void *)knp
, (void *)src
);
602 KSTAT_NAMED_STR_PTR(knp
) = (char *)src
;
604 KSTAT_NAMED_STR_BUFLEN(knp
) = strlen(src
) + 1;
606 KSTAT_NAMED_STR_BUFLEN(knp
) = 0;
610 kstat_set_string(char *dst
, const char *src
)
612 bzero(dst
, KSTAT_STRLEN
);
613 (void) strncpy(dst
, src
, KSTAT_STRLEN
- 1);
617 kstat_named_init(kstat_named_t
*knp
, const char *name
, uchar_t data_type
)
619 kstat_set_string(knp
->name
, name
);
620 knp
->data_type
= data_type
;
622 if (data_type
== KSTAT_DATA_STRING
)
623 kstat_named_setstr(knp
, NULL
);
627 kstat_timer_init(kstat_timer_t
*ktp
, const char *name
)
629 kstat_set_string(ktp
->name
, name
);
634 default_kstat_update(kstat_t
*ksp
, int rw
)
641 * Named kstats with variable-length long strings have a standard
642 * way of determining how much space is needed to hold the snapshot:
644 if (ksp
->ks_data
!= NULL
&& ksp
->ks_type
== KSTAT_TYPE_NAMED
&&
645 (ksp
->ks_flags
& (KSTAT_FLAG_VAR_SIZE
| KSTAT_FLAG_LONGSTRINGS
))) {
648 * Add in the space required for the strings
650 knp
= KSTAT_NAMED_PTR(ksp
);
651 for (i
= 0; i
< ksp
->ks_ndata
; i
++, knp
++) {
652 if (knp
->data_type
== KSTAT_DATA_STRING
)
653 len
+= KSTAT_NAMED_STR_BUFLEN(knp
);
656 ksp
->ks_ndata
* sizeof (kstat_named_t
) + len
;
662 default_kstat_snapshot(kstat_t
*ksp
, void *buf
, int rw
)
668 ksp
->ks_snaptime
= cur_time
= gethrtime();
670 if (rw
== KSTAT_WRITE
) {
671 if (!(ksp
->ks_flags
& KSTAT_FLAG_WRITABLE
))
673 bcopy(buf
, ksp
->ks_data
, ksp
->ks_data_size
);
678 * KSTAT_TYPE_NAMED kstats are defined to have ks_ndata
679 * number of kstat_named_t structures, followed by an optional
680 * string segment. The ks_data generally holds only the
681 * kstat_named_t structures. So we copy it first. The strings,
682 * if any, are copied below. For other kstat types, ks_data holds the
686 namedsz
= sizeof (kstat_named_t
) * ksp
->ks_ndata
;
687 if (ksp
->ks_type
== KSTAT_TYPE_NAMED
&& ksp
->ks_data_size
> namedsz
)
688 bcopy(ksp
->ks_data
, buf
, namedsz
);
690 bcopy(ksp
->ks_data
, buf
, ksp
->ks_data_size
);
693 * Apply kstat type-specific data massaging
695 switch (ksp
->ks_type
) {
699 * Normalize time units and deal with incomplete transactions
701 kiop
= (kstat_io_t
*)buf
;
703 scalehrtime(&kiop
->wtime
);
704 scalehrtime(&kiop
->wlentime
);
705 scalehrtime(&kiop
->wlastupdate
);
706 scalehrtime(&kiop
->rtime
);
707 scalehrtime(&kiop
->rlentime
);
708 scalehrtime(&kiop
->rlastupdate
);
710 if (kiop
->wcnt
!= 0) {
711 /* like kstat_waitq_exit */
712 hrtime_t wfix
= cur_time
- kiop
->wlastupdate
;
713 kiop
->wlastupdate
= cur_time
;
714 kiop
->wlentime
+= kiop
->wcnt
* wfix
;
718 if (kiop
->rcnt
!= 0) {
719 /* like kstat_runq_exit */
720 hrtime_t rfix
= cur_time
- kiop
->rlastupdate
;
721 kiop
->rlastupdate
= cur_time
;
722 kiop
->rlentime
+= kiop
->rcnt
* rfix
;
727 case KSTAT_TYPE_NAMED
:
729 * Massage any long strings in at the end of the buffer
731 if (ksp
->ks_data_size
> namedsz
) {
733 kstat_named_t
*knp
= buf
;
734 char *dst
= (char *)(knp
+ ksp
->ks_ndata
);
736 * Copy strings and update pointers
738 for (i
= 0; i
< ksp
->ks_ndata
; i
++, knp
++) {
739 if (knp
->data_type
== KSTAT_DATA_STRING
&&
740 KSTAT_NAMED_STR_PTR(knp
) != NULL
) {
741 bcopy(KSTAT_NAMED_STR_PTR(knp
), dst
,
742 KSTAT_NAMED_STR_BUFLEN(knp
));
743 KSTAT_NAMED_STR_PTR(knp
) = dst
;
744 dst
+= KSTAT_NAMED_STR_BUFLEN(knp
);
747 ASSERT(dst
<= ((char *)buf
+ ksp
->ks_data_size
));
755 header_kstat_update(kstat_t
*header_ksp
, int rw
)
759 avl_tree_t
*t
= &kstat_avl_bykid
;
762 if (rw
== KSTAT_WRITE
)
765 ASSERT(MUTEX_HELD(&kstat_chain_lock
));
767 zoneid
= getzoneid();
768 for (e
= avl_first(t
); e
!= NULL
; e
= avl_walk(t
, e
, AVL_AFTER
)) {
769 if (kstat_zone_find((kstat_t
*)e
, zoneid
) &&
770 (e
->e_ks
.ks_flags
& KSTAT_FLAG_INVALID
) == 0) {
774 header_ksp
->ks_ndata
= nkstats
;
775 header_ksp
->ks_data_size
= nkstats
* sizeof (kstat_t
);
780 * Copy out the data section of kstat 0, which consists of the list
781 * of all kstat headers. By specification, these headers must be
782 * copied out in order of increasing KID.
785 header_kstat_snapshot(kstat_t
*header_ksp
, void *buf
, int rw
)
788 avl_tree_t
*t
= &kstat_avl_bykid
;
791 header_ksp
->ks_snaptime
= gethrtime();
793 if (rw
== KSTAT_WRITE
)
796 ASSERT(MUTEX_HELD(&kstat_chain_lock
));
798 zoneid
= getzoneid();
799 for (e
= avl_first(t
); e
!= NULL
; e
= avl_walk(t
, e
, AVL_AFTER
)) {
800 if (kstat_zone_find((kstat_t
*)e
, zoneid
) &&
801 (e
->e_ks
.ks_flags
& KSTAT_FLAG_INVALID
) == 0) {
802 bcopy(&e
->e_ks
, buf
, sizeof (kstat_t
));
803 buf
= (char *)buf
+ sizeof (kstat_t
);
812 system_misc_kstat_update(kstat_t
*ksp
, int rw
)
815 int *loadavgp
= &avenrun
[0];
816 time_t zone_boot_time
;
818 hrtime_t zone_hrtime
;
821 if (rw
== KSTAT_WRITE
)
824 if (!INGLOBALZONE(curproc
)) {
826 * Here we grab cpu_lock which is OK as long as no-one in the
827 * future attempts to lookup this particular kstat
828 * (unix:0:system_misc) while holding cpu_lock.
830 mutex_enter(&cpu_lock
);
831 if (pool_pset_enabled()) {
832 myncpus
= zone_ncpus_get(curproc
->p_zone
);
835 mutex_exit(&cpu_lock
);
836 loadavgp
= &curproc
->p_zone
->zone_avenrun
[0];
839 if (INGLOBALZONE(curproc
)) {
840 zone_boot_time
= boot_time
;
841 zone_lbolt
= ddi_get_lbolt();
844 zone_boot_time
= curproc
->p_zone
->zone_boot_time
;
846 zone_hrtime
= gethrtime();
847 zone_lbolt
= (clock_t)(NSEC_TO_TICK(zone_hrtime
) -
848 NSEC_TO_TICK(curproc
->p_zone
->zone_zsched
->p_mstart
));
849 mutex_enter(&curproc
->p_zone
->zone_nlwps_lock
);
850 zone_nproc
= curproc
->p_zone
->zone_nprocs
;
851 mutex_exit(&curproc
->p_zone
->zone_nlwps_lock
);
854 system_misc_kstat
.ncpus
.value
.ui32
= (uint32_t)myncpus
;
855 system_misc_kstat
.lbolt
.value
.ui32
= (uint32_t)zone_lbolt
;
856 system_misc_kstat
.deficit
.value
.ui32
= (uint32_t)deficit
;
857 system_misc_kstat
.clk_intr
.value
.ui32
= (uint32_t)zone_lbolt
;
858 system_misc_kstat
.vac
.value
.ui32
= (uint32_t)vac
;
859 system_misc_kstat
.nproc
.value
.ui32
= (uint32_t)zone_nproc
;
860 system_misc_kstat
.avenrun_1min
.value
.ui32
= (uint32_t)loadavgp
[0];
861 system_misc_kstat
.avenrun_5min
.value
.ui32
= (uint32_t)loadavgp
[1];
862 system_misc_kstat
.avenrun_15min
.value
.ui32
= (uint32_t)loadavgp
[2];
863 system_misc_kstat
.boot_time
.value
.ui32
= (uint32_t)
865 system_misc_kstat
.nsec_per_tick
.value
.ui32
= (uint32_t)
871 extern caddr_t econtig32
;
873 extern caddr_t econtig
;
878 system_pages_kstat_update(kstat_t
*ksp
, int rw
)
880 kobj_stat_t kobj_stat
;
882 if (rw
== KSTAT_WRITE
) {
886 kobj_stat_get(&kobj_stat
);
887 system_pages_kstat
.physmem
.value
.ul
= (ulong_t
)physmem
;
888 system_pages_kstat
.nalloc
.value
.ul
= kobj_stat
.nalloc
;
889 system_pages_kstat
.nfree
.value
.ul
= kobj_stat
.nfree
;
890 system_pages_kstat
.nalloc_calls
.value
.ul
= kobj_stat
.nalloc_calls
;
891 system_pages_kstat
.nfree_calls
.value
.ul
= kobj_stat
.nfree_calls
;
892 system_pages_kstat
.kernelbase
.value
.ul
= (ulong_t
)KERNELBASE
;
896 * kstat should REALLY be modified to also report kmem64_base and
897 * kmem64_end (see sun4u/os/startup.c), as the virtual address range
898 * [ kernelbase .. econtig ] no longer is truly reflective of the
899 * kernel's vallocs...
901 system_pages_kstat
.econtig
.value
.ul
= (ulong_t
)econtig32
;
903 system_pages_kstat
.econtig
.value
.ul
= (ulong_t
)econtig
;
906 system_pages_kstat
.freemem
.value
.ul
= (ulong_t
)freemem
;
907 system_pages_kstat
.availrmem
.value
.ul
= (ulong_t
)availrmem
;
908 system_pages_kstat
.lotsfree
.value
.ul
= (ulong_t
)lotsfree
;
909 system_pages_kstat
.desfree
.value
.ul
= (ulong_t
)desfree
;
910 system_pages_kstat
.minfree
.value
.ul
= (ulong_t
)minfree
;
911 system_pages_kstat
.fastscan
.value
.ul
= (ulong_t
)fastscan
;
912 system_pages_kstat
.slowscan
.value
.ul
= (ulong_t
)slowscan
;
913 system_pages_kstat
.nscan
.value
.ul
= (ulong_t
)nscan
;
914 system_pages_kstat
.desscan
.value
.ul
= (ulong_t
)desscan
;
915 system_pages_kstat
.pagesfree
.value
.ul
= (ulong_t
)freemem
;
916 system_pages_kstat
.pageslocked
.value
.ul
= (ulong_t
)(availrmem_initial
-
918 system_pages_kstat
.pagestotal
.value
.ul
= (ulong_t
)total_pages
;
919 system_pages_kstat
.lowmemscan
.value
.ul
= (ulong_t
)low_mem_scan
;
920 system_pages_kstat
.nthrottle
.value
.ul
= (ulong_t
)n_throttle
;
922 * pp_kernel represents total pages used by the kernel since the
923 * startup. This formula takes into account the boottime kernel
924 * footprint and also considers the availrmem changes because of
925 * user explicit page locking.
927 system_pages_kstat
.pp_kernel
.value
.ul
= (ulong_t
)(physinstalled
-
928 obp_pages
- availrmem
- k_anoninfo
.ani_mem_resv
-
929 anon_segkp_pages_locked
- pages_locked
-
930 pages_claimed
- pages_useclaim
);
936 kstat_create(const char *ks_module
, int ks_instance
, const char *ks_name
,
937 const char *ks_class
, uchar_t ks_type
, uint_t ks_ndata
, uchar_t ks_flags
)
939 return (kstat_create_zone(ks_module
, ks_instance
, ks_name
, ks_class
,
940 ks_type
, ks_ndata
, ks_flags
, ALL_ZONES
));
944 * Allocate and initialize a kstat structure. Or, if a dormant kstat with
945 * the specified name exists, reactivate it. Returns a pointer to the kstat
946 * on success, NULL on failure. The kstat will not be visible to the
947 * kstat driver until kstat_install().
950 kstat_create_zone(const char *ks_module
, int ks_instance
, const char *ks_name
,
951 const char *ks_class
, uchar_t ks_type
, uint_t ks_ndata
, uchar_t ks_flags
,
958 char namebuf
[KSTAT_STRLEN
+ 16];
960 if (avl_numnodes(&kstat_avl_bykid
) == 0) {
961 avl_create(&kstat_avl_bykid
, kstat_compare_bykid
,
962 sizeof (ekstat_t
), offsetof(struct ekstat
, e_avl_bykid
));
964 avl_create(&kstat_avl_byname
, kstat_compare_byname
,
965 sizeof (ekstat_t
), offsetof(struct ekstat
, e_avl_byname
));
969 * If ks_name == NULL, set the ks_name to <module><instance>.
971 if (ks_name
== NULL
) {
972 char buf
[KSTAT_STRLEN
];
973 kstat_set_string(buf
, ks_module
);
974 (void) sprintf(namebuf
, "%s%d", buf
, ks_instance
);
979 * Make sure it's a valid kstat data type
981 if (ks_type
>= KSTAT_NUM_TYPES
) {
982 cmn_err(CE_WARN
, "kstat_create('%s', %d, '%s'): "
983 "invalid kstat type %d",
984 ks_module
, ks_instance
, ks_name
, ks_type
);
989 * Don't allow persistent virtual kstats -- it makes no sense.
990 * ks_data points to garbage when the client goes away.
992 if ((ks_flags
& KSTAT_FLAG_PERSISTENT
) &&
993 (ks_flags
& KSTAT_FLAG_VIRTUAL
)) {
994 cmn_err(CE_WARN
, "kstat_create('%s', %d, '%s'): "
995 "cannot create persistent virtual kstat",
996 ks_module
, ks_instance
, ks_name
);
1001 * Don't allow variable-size physical kstats, since the framework's
1002 * memory allocation for physical kstat data is fixed at creation time.
1004 if ((ks_flags
& KSTAT_FLAG_VAR_SIZE
) &&
1005 !(ks_flags
& KSTAT_FLAG_VIRTUAL
)) {
1006 cmn_err(CE_WARN
, "kstat_create('%s', %d, '%s'): "
1007 "cannot create variable-size physical kstat",
1008 ks_module
, ks_instance
, ks_name
);
1013 * Make sure the number of data fields is within legal range
1015 if (ks_ndata
< kstat_data_type
[ks_type
].min_ndata
||
1016 ks_ndata
> kstat_data_type
[ks_type
].max_ndata
) {
1017 cmn_err(CE_WARN
, "kstat_create('%s', %d, '%s'): "
1018 "ks_ndata=%d out of range [%d, %d]",
1019 ks_module
, ks_instance
, ks_name
, (int)ks_ndata
,
1020 kstat_data_type
[ks_type
].min_ndata
,
1021 kstat_data_type
[ks_type
].max_ndata
);
1025 ks_data_size
= kstat_data_type
[ks_type
].size
* ks_ndata
;
1028 * If the named kstat already exists and is dormant, reactivate it.
1030 ksp
= kstat_hold_byname(ks_module
, ks_instance
, ks_name
, ks_zoneid
);
1032 if (!(ksp
->ks_flags
& KSTAT_FLAG_DORMANT
)) {
1034 * The named kstat exists but is not dormant --
1035 * this is a kstat namespace collision.
1039 "kstat_create('%s', %d, '%s'): namespace collision",
1040 ks_module
, ks_instance
, ks_name
);
1043 if ((strcmp(ksp
->ks_class
, ks_class
) != 0) ||
1044 (ksp
->ks_type
!= ks_type
) ||
1045 (ksp
->ks_ndata
!= ks_ndata
) ||
1046 (ks_flags
& KSTAT_FLAG_VIRTUAL
)) {
1048 * The name is the same, but the other key parameters
1049 * differ from those of the dormant kstat -- bogus.
1052 cmn_err(CE_WARN
, "kstat_create('%s', %d, '%s'): "
1053 "invalid reactivation of dormant kstat",
1054 ks_module
, ks_instance
, ks_name
);
1058 * Return dormant kstat pointer to caller. As usual,
1059 * the kstat is marked invalid until kstat_install().
1061 ksp
->ks_flags
|= KSTAT_FLAG_INVALID
;
1067 * Allocate memory for the new kstat header and, if this is a physical
1068 * kstat, the data section.
1070 e
= kstat_alloc(ks_flags
& KSTAT_FLAG_VIRTUAL
? 0 : ks_data_size
);
1072 cmn_err(CE_NOTE
, "kstat_create('%s', %d, '%s'): "
1073 "insufficient kernel memory",
1074 ks_module
, ks_instance
, ks_name
);
1079 * Initialize as many fields as we can. The caller may reset
1080 * ks_lock, ks_update, ks_private, and ks_snapshot as necessary.
1081 * Creators of virtual kstats may also reset ks_data. It is
1082 * also up to the caller to initialize the kstat data section,
1083 * if necessary. All initialization must be complete before
1084 * calling kstat_install().
1086 e
->e_zone
.zoneid
= ks_zoneid
;
1087 e
->e_zone
.next
= NULL
;
1090 ksp
->ks_crtime
= gethrtime();
1091 kstat_set_string(ksp
->ks_module
, ks_module
);
1092 ksp
->ks_instance
= ks_instance
;
1093 kstat_set_string(ksp
->ks_name
, ks_name
);
1094 ksp
->ks_type
= ks_type
;
1095 kstat_set_string(ksp
->ks_class
, ks_class
);
1096 ksp
->ks_flags
= ks_flags
| KSTAT_FLAG_INVALID
;
1097 if (ks_flags
& KSTAT_FLAG_VIRTUAL
)
1098 ksp
->ks_data
= NULL
;
1100 ksp
->ks_data
= (void *)(e
+ 1);
1101 ksp
->ks_ndata
= ks_ndata
;
1102 ksp
->ks_data_size
= ks_data_size
;
1103 ksp
->ks_snaptime
= ksp
->ks_crtime
;
1104 ksp
->ks_update
= default_kstat_update
;
1105 ksp
->ks_private
= NULL
;
1106 ksp
->ks_snapshot
= default_kstat_snapshot
;
1107 ksp
->ks_lock
= NULL
;
1109 mutex_enter(&kstat_chain_lock
);
1112 * Add our kstat to the AVL trees.
1114 if (avl_find(&kstat_avl_byname
, e
, &where
) != NULL
) {
1115 mutex_exit(&kstat_chain_lock
);
1117 "kstat_create('%s', %d, '%s'): namespace collision",
1118 ks_module
, ks_instance
, ks_name
);
1122 avl_insert(&kstat_avl_byname
, e
, where
);
1125 * Loop around until we find an unused KID.
1128 ksp
->ks_kid
= kstat_chain_id
++;
1129 } while (avl_find(&kstat_avl_bykid
, e
, &where
) != NULL
);
1130 avl_insert(&kstat_avl_bykid
, e
, where
);
1132 mutex_exit(&kstat_chain_lock
);
1138 * Activate a fully initialized kstat and make it visible to /dev/kstat.
1141 kstat_install(kstat_t
*ksp
)
1143 zoneid_t zoneid
= ((ekstat_t
*)ksp
)->e_zone
.zoneid
;
1146 * If this is a variable-size kstat, it MUST provide kstat data locking
1147 * to prevent data-size races with kstat readers.
1149 if ((ksp
->ks_flags
& KSTAT_FLAG_VAR_SIZE
) && ksp
->ks_lock
== NULL
) {
1150 panic("kstat_install('%s', %d, '%s'): "
1151 "cannot create variable-size kstat without data lock",
1152 ksp
->ks_module
, ksp
->ks_instance
, ksp
->ks_name
);
1155 if (kstat_hold_bykid(ksp
->ks_kid
, zoneid
) != ksp
) {
1156 cmn_err(CE_WARN
, "kstat_install(%p): does not exist",
1161 if (ksp
->ks_type
== KSTAT_TYPE_NAMED
&& ksp
->ks_data
!= NULL
) {
1163 kstat_named_t
*knp
= KSTAT_NAMED_PTR(ksp
);
1165 for (i
= 0; i
< ksp
->ks_ndata
; i
++, knp
++) {
1166 if (knp
->data_type
== KSTAT_DATA_STRING
) {
1167 ksp
->ks_flags
|= KSTAT_FLAG_LONGSTRINGS
;
1172 * The default snapshot routine does not handle KSTAT_WRITE
1175 if ((ksp
->ks_flags
& KSTAT_FLAG_LONGSTRINGS
) &&
1176 (ksp
->ks_flags
& KSTAT_FLAG_WRITABLE
) &&
1177 (ksp
->ks_snapshot
== default_kstat_snapshot
)) {
1178 panic("kstat_install('%s', %d, '%s'): "
1179 "named kstat containing KSTAT_DATA_STRING "
1180 "is writable but uses default snapshot routine",
1181 ksp
->ks_module
, ksp
->ks_instance
, ksp
->ks_name
);
1185 if (ksp
->ks_flags
& KSTAT_FLAG_DORMANT
) {
1188 * We are reactivating a dormant kstat. Initialize the
1189 * caller's underlying data to the value it had when the
1190 * kstat went dormant, and mark the kstat as active.
1191 * Grab the provider's kstat lock if it's not already held.
1193 kmutex_t
*lp
= ksp
->ks_lock
;
1194 if (lp
!= NULL
&& MUTEX_NOT_HELD(lp
)) {
1196 (void) KSTAT_UPDATE(ksp
, KSTAT_WRITE
);
1199 (void) KSTAT_UPDATE(ksp
, KSTAT_WRITE
);
1201 ksp
->ks_flags
&= ~KSTAT_FLAG_DORMANT
;
1205 * Now that the kstat is active, make it visible to the kstat driver.
1206 * When copying out kstats the count is determined in
1207 * header_kstat_update() and actually copied into kbuf in
1208 * header_kstat_snapshot(). kstat_chain_lock is held across the two
1209 * calls to ensure that this list doesn't change. Thus, we need to
1210 * also take the lock to ensure that the we don't copy the new kstat
1211 * in the 2nd pass and overrun the buf.
1213 mutex_enter(&kstat_chain_lock
);
1214 ksp
->ks_flags
&= ~KSTAT_FLAG_INVALID
;
1215 mutex_exit(&kstat_chain_lock
);
1220 * Remove a kstat from the system. Or, if it's a persistent kstat,
1221 * just update the data and mark it as dormant.
1224 kstat_delete(kstat_t
*ksp
)
1227 ekstat_t
*e
= (ekstat_t
*)ksp
;
1231 ASSERT(ksp
!= NULL
);
1236 zoneid
= e
->e_zone
.zoneid
;
1240 if (lp
!= NULL
&& MUTEX_HELD(lp
)) {
1241 panic("kstat_delete(%p): caller holds data lock %p",
1242 (void *)ksp
, (void *)lp
);
1245 if (kstat_hold_bykid(ksp
->ks_kid
, zoneid
) != ksp
) {
1246 cmn_err(CE_WARN
, "kstat_delete(%p): does not exist",
1251 if (ksp
->ks_flags
& KSTAT_FLAG_PERSISTENT
) {
1253 * Update the data one last time, so that all activity
1254 * prior to going dormant has been accounted for.
1257 (void) KSTAT_UPDATE(ksp
, KSTAT_READ
);
1261 * Mark the kstat as dormant and restore caller-modifiable
1262 * fields to default values, so the kstat is readable during
1263 * the dormant phase.
1265 ksp
->ks_flags
|= KSTAT_FLAG_DORMANT
;
1266 ksp
->ks_lock
= NULL
;
1267 ksp
->ks_update
= default_kstat_update
;
1268 ksp
->ks_private
= NULL
;
1269 ksp
->ks_snapshot
= default_kstat_snapshot
;
1275 * Remove the kstat from the framework's AVL trees,
1276 * free the allocated memory, and increment kstat_chain_id so
1277 * /dev/kstat clients can detect the event.
1279 mutex_enter(&kstat_chain_lock
);
1280 avl_remove(&kstat_avl_bykid
, e
);
1281 avl_remove(&kstat_avl_byname
, e
);
1283 mutex_exit(&kstat_chain_lock
);
1285 kz
= e
->e_zone
.next
;
1286 while (kz
!= NULL
) {
1287 kstat_zone_t
*t
= kz
;
1290 kmem_free(t
, sizeof (*t
));
1297 kstat_delete_byname_zone(const char *ks_module
, int ks_instance
,
1298 const char *ks_name
, zoneid_t ks_zoneid
)
1302 ksp
= kstat_hold_byname(ks_module
, ks_instance
, ks_name
, ks_zoneid
);
1310 kstat_delete_byname(const char *ks_module
, int ks_instance
, const char *ks_name
)
1312 kstat_delete_byname_zone(ks_module
, ks_instance
, ks_name
, ALL_ZONES
);
1316 * The sparc V9 versions of these routines can be much cheaper than
1317 * the poor 32-bit compiler can comprehend, so they're in sparcv9_subr.s.
1318 * For simplicity, however, we always feed the C versions to lint.
1320 #if !defined(__sparc) || defined(lint) || defined(__lint)
1323 kstat_waitq_enter(kstat_io_t
*kiop
)
1325 hrtime_t
new, delta
;
1328 new = gethrtime_unscaled();
1329 delta
= new - kiop
->wlastupdate
;
1330 kiop
->wlastupdate
= new;
1331 wcnt
= kiop
->wcnt
++;
1333 kiop
->wlentime
+= delta
* wcnt
;
1334 kiop
->wtime
+= delta
;
1339 kstat_waitq_exit(kstat_io_t
*kiop
)
1341 hrtime_t
new, delta
;
1344 new = gethrtime_unscaled();
1345 delta
= new - kiop
->wlastupdate
;
1346 kiop
->wlastupdate
= new;
1347 wcnt
= kiop
->wcnt
--;
1348 ASSERT((int)wcnt
> 0);
1349 kiop
->wlentime
+= delta
* wcnt
;
1350 kiop
->wtime
+= delta
;
1354 kstat_runq_enter(kstat_io_t
*kiop
)
1356 hrtime_t
new, delta
;
1359 new = gethrtime_unscaled();
1360 delta
= new - kiop
->rlastupdate
;
1361 kiop
->rlastupdate
= new;
1362 rcnt
= kiop
->rcnt
++;
1364 kiop
->rlentime
+= delta
* rcnt
;
1365 kiop
->rtime
+= delta
;
1370 kstat_runq_exit(kstat_io_t
*kiop
)
1372 hrtime_t
new, delta
;
1375 new = gethrtime_unscaled();
1376 delta
= new - kiop
->rlastupdate
;
1377 kiop
->rlastupdate
= new;
1378 rcnt
= kiop
->rcnt
--;
1379 ASSERT((int)rcnt
> 0);
1380 kiop
->rlentime
+= delta
* rcnt
;
1381 kiop
->rtime
+= delta
;
1385 kstat_waitq_to_runq(kstat_io_t
*kiop
)
1387 hrtime_t
new, delta
;
1390 new = gethrtime_unscaled();
1392 delta
= new - kiop
->wlastupdate
;
1393 kiop
->wlastupdate
= new;
1394 wcnt
= kiop
->wcnt
--;
1395 ASSERT((int)wcnt
> 0);
1396 kiop
->wlentime
+= delta
* wcnt
;
1397 kiop
->wtime
+= delta
;
1399 delta
= new - kiop
->rlastupdate
;
1400 kiop
->rlastupdate
= new;
1401 rcnt
= kiop
->rcnt
++;
1403 kiop
->rlentime
+= delta
* rcnt
;
1404 kiop
->rtime
+= delta
;
1409 kstat_runq_back_to_waitq(kstat_io_t
*kiop
)
1411 hrtime_t
new, delta
;
1414 new = gethrtime_unscaled();
1416 delta
= new - kiop
->rlastupdate
;
1417 kiop
->rlastupdate
= new;
1418 rcnt
= kiop
->rcnt
--;
1419 ASSERT((int)rcnt
> 0);
1420 kiop
->rlentime
+= delta
* rcnt
;
1421 kiop
->rtime
+= delta
;
1423 delta
= new - kiop
->wlastupdate
;
1424 kiop
->wlastupdate
= new;
1425 wcnt
= kiop
->wcnt
++;
1427 kiop
->wlentime
+= delta
* wcnt
;
1428 kiop
->wtime
+= delta
;
1435 kstat_timer_start(kstat_timer_t
*ktp
)
1437 ktp
->start_time
= gethrtime();
1441 kstat_timer_stop(kstat_timer_t
*ktp
)
1444 u_longlong_t num_events
;
1446 ktp
->stop_time
= etime
= gethrtime();
1447 etime
-= ktp
->start_time
;
1448 num_events
= ktp
->num_events
;
1449 if (etime
< ktp
->min_time
|| num_events
== 0)
1450 ktp
->min_time
= etime
;
1451 if (etime
> ktp
->max_time
)
1452 ktp
->max_time
= etime
;
1453 ktp
->elapsed_time
+= etime
;
1454 ktp
->num_events
= num_events
+ 1;