5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
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.
25 */
26
27 /*
28 * Kernel statistics framework
29 */
30
31 #include <sys/types.h>
32 #include <sys/time.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>
38 #include <sys/vmem.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>
131
132 #define KSTAT_ALIGN (sizeof (uint64_t))
133
134 static avl_tree_t kstat_avl_bykid;
135 static avl_tree_t kstat_avl_byname;
136
137 /*
138 * Various pointers we need to create kstats at boot time in kstat_init()
139 */
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;
147
148 extern int vac;
149 extern uint_t nproc;
150 extern time_t boot_time;
151 extern sysinfo_t sysinfo;
152 extern vminfo_t vminfo;
153
154 struct {
155 kstat_named_t ncpus;
156 kstat_named_t lbolt;
157 kstat_named_t deficit;
158 kstat_named_t clk_intr;
159 kstat_named_t vac;
160 kstat_named_t nproc;
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 },
178 };
179
180 struct {
181 kstat_named_t physmem;
182 kstat_named_t nalloc;
183 kstat_named_t nfree;
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;
195 kstat_named_t nscan;
196 kstat_named_t desscan;
793
794 zoneid = getzoneid();
795 for (e = avl_first(t); e != NULL; e = avl_walk(t, e, AVL_AFTER)) {
796 if (kstat_zone_find((kstat_t *)e, zoneid) &&
797 (e->e_ks.ks_flags & KSTAT_FLAG_INVALID) == 0) {
798 bcopy(&e->e_ks, buf, sizeof (kstat_t));
799 buf = (char *)buf + sizeof (kstat_t);
800 }
801 }
802
803 return (0);
804 }
805
806 /* ARGSUSED */
807 static int
808 system_misc_kstat_update(kstat_t *ksp, int rw)
809 {
810 int myncpus = ncpus;
811 int *loadavgp = &avenrun[0];
812 time_t zone_boot_time;
813 clock_t zone_lbolt;
814 hrtime_t zone_hrtime;
815 size_t zone_nproc;
816
817 if (rw == KSTAT_WRITE)
818 return (EACCES);
819
820 if (!INGLOBALZONE(curproc)) {
821 /*
822 * Here we grab cpu_lock which is OK as long as no-one in the
823 * future attempts to lookup this particular kstat
824 * (unix:0:system_misc) while holding cpu_lock.
825 */
826 mutex_enter(&cpu_lock);
827 if (pool_pset_enabled()) {
828 myncpus = zone_ncpus_get(curproc->p_zone);
829 ASSERT(myncpus > 0);
830 }
831 mutex_exit(&cpu_lock);
832 loadavgp = &curproc->p_zone->zone_avenrun[0];
833 }
834
835 if (INGLOBALZONE(curproc)) {
836 zone_boot_time = boot_time;
837 zone_lbolt = ddi_get_lbolt();
838 zone_nproc = nproc;
839 } else {
840 zone_boot_time = curproc->p_zone->zone_boot_time;
841
842 zone_hrtime = gethrtime();
843 zone_lbolt = (clock_t)(NSEC_TO_TICK(zone_hrtime) -
844 NSEC_TO_TICK(curproc->p_zone->zone_zsched->p_mstart));
845 mutex_enter(&curproc->p_zone->zone_nlwps_lock);
846 zone_nproc = curproc->p_zone->zone_nprocs;
847 mutex_exit(&curproc->p_zone->zone_nlwps_lock);
848 }
849
850 system_misc_kstat.ncpus.value.ui32 = (uint32_t)myncpus;
851 system_misc_kstat.lbolt.value.ui32 = (uint32_t)zone_lbolt;
852 system_misc_kstat.deficit.value.ui32 = (uint32_t)deficit;
853 system_misc_kstat.clk_intr.value.ui32 = (uint32_t)zone_lbolt;
854 system_misc_kstat.vac.value.ui32 = (uint32_t)vac;
855 system_misc_kstat.nproc.value.ui32 = (uint32_t)zone_nproc;
856 system_misc_kstat.avenrun_1min.value.ui32 = (uint32_t)loadavgp[0];
857 system_misc_kstat.avenrun_5min.value.ui32 = (uint32_t)loadavgp[1];
858 system_misc_kstat.avenrun_15min.value.ui32 = (uint32_t)loadavgp[2];
859 system_misc_kstat.boot_time.value.ui32 = (uint32_t)
860 zone_boot_time;
861 system_misc_kstat.nsec_per_tick.value.ui32 = (uint32_t)
862 nsec_per_tick;
863 return (0);
864 }
865
866 #ifdef __sparc
867 extern caddr_t econtig32;
868 #else /* !__sparc */
869 extern caddr_t econtig;
870 #endif /* __sparc */
871
872 /* ARGSUSED */
873 static int
874 system_pages_kstat_update(kstat_t *ksp, int rw)
875 {
876 kobj_stat_t kobj_stat;
877
878 if (rw == KSTAT_WRITE) {
879 return (EACCES);
880 }
|
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21 /*
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.
25 * Copyright 2016 Garrett D'Amore
26 */
27
28 /*
29 * Kernel statistics framework
30 */
31
32 #include <sys/types.h>
33 #include <sys/time.h>
34 #include <sys/systm.h>
35 #include <sys/vmsystm.h>
36 #include <sys/t_lock.h>
37 #include <sys/param.h>
38 #include <sys/errno.h>
39 #include <sys/vmem.h>
40 #include <sys/sysmacros.h>
41 #include <sys/cmn_err.h>
42 #include <sys/kstat.h>
43 #include <sys/sysinfo.h>
44 #include <sys/cpuvar.h>
45 #include <sys/fcntl.h>
132
133 #define KSTAT_ALIGN (sizeof (uint64_t))
134
135 static avl_tree_t kstat_avl_bykid;
136 static avl_tree_t kstat_avl_byname;
137
138 /*
139 * Various pointers we need to create kstats at boot time in kstat_init()
140 */
141 extern kstat_named_t *segmapcnt_ptr;
142 extern uint_t segmapcnt_ndata;
143 extern int segmap_kstat_update(kstat_t *, int);
144 extern kstat_named_t *biostats_ptr;
145 extern uint_t biostats_ndata;
146 extern kstat_named_t *pollstats_ptr;
147 extern uint_t pollstats_ndata;
148
149 extern int vac;
150 extern uint_t nproc;
151 extern time_t boot_time;
152 extern hrtime_t boot_hrtime;
153 extern sysinfo_t sysinfo;
154 extern vminfo_t vminfo;
155
156 struct {
157 kstat_named_t ncpus;
158 kstat_named_t lbolt;
159 kstat_named_t deficit;
160 kstat_named_t clk_intr;
161 kstat_named_t vac;
162 kstat_named_t nproc;
163 kstat_named_t avenrun_1min;
164 kstat_named_t avenrun_5min;
165 kstat_named_t avenrun_15min;
166 kstat_named_t boot_time;
167 kstat_named_t boot_hrtime;
168 kstat_named_t nsec_per_tick;
169 } system_misc_kstat = {
170 { "ncpus", KSTAT_DATA_UINT32 },
171 { "lbolt", KSTAT_DATA_UINT32 },
172 { "deficit", KSTAT_DATA_UINT32 },
173 { "clk_intr", KSTAT_DATA_UINT32 },
174 { "vac", KSTAT_DATA_UINT32 },
175 { "nproc", KSTAT_DATA_UINT32 },
176 { "avenrun_1min", KSTAT_DATA_UINT32 },
177 { "avenrun_5min", KSTAT_DATA_UINT32 },
178 { "avenrun_15min", KSTAT_DATA_UINT32 },
179 { "boot_time", KSTAT_DATA_UINT32 },
180 { "boot_hrtime", KSTAT_DATA_TIME },
181 { "nsec_per_tick", KSTAT_DATA_UINT32 },
182 };
183
184 struct {
185 kstat_named_t physmem;
186 kstat_named_t nalloc;
187 kstat_named_t nfree;
188 kstat_named_t nalloc_calls;
189 kstat_named_t nfree_calls;
190 kstat_named_t kernelbase;
191 kstat_named_t econtig;
192 kstat_named_t freemem;
193 kstat_named_t availrmem;
194 kstat_named_t lotsfree;
195 kstat_named_t desfree;
196 kstat_named_t minfree;
197 kstat_named_t fastscan;
198 kstat_named_t slowscan;
199 kstat_named_t nscan;
200 kstat_named_t desscan;
797
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);
804 }
805 }
806
807 return (0);
808 }
809
810 /* ARGSUSED */
811 static int
812 system_misc_kstat_update(kstat_t *ksp, int rw)
813 {
814 int myncpus = ncpus;
815 int *loadavgp = &avenrun[0];
816 time_t zone_boot_time;
817 hrtime_t zone_boot_hrtime;
818 clock_t zone_lbolt;
819 hrtime_t zone_hrtime;
820 size_t zone_nproc;
821
822 if (rw == KSTAT_WRITE)
823 return (EACCES);
824
825 if (!INGLOBALZONE(curproc)) {
826 /*
827 * Here we grab cpu_lock which is OK as long as no-one in the
828 * future attempts to lookup this particular kstat
829 * (unix:0:system_misc) while holding cpu_lock.
830 */
831 mutex_enter(&cpu_lock);
832 if (pool_pset_enabled()) {
833 myncpus = zone_ncpus_get(curproc->p_zone);
834 ASSERT(myncpus > 0);
835 }
836 mutex_exit(&cpu_lock);
837 loadavgp = &curproc->p_zone->zone_avenrun[0];
838 }
839
840 if (INGLOBALZONE(curproc)) {
841 zone_boot_time = boot_time;
842 zone_lbolt = ddi_get_lbolt();
843 zone_nproc = nproc;
844 zone_boot_hrtime = boot_hrtime;
845 } else {
846 zone_boot_time = curproc->p_zone->zone_boot_time;
847 zone_boot_hrtime = curproc->p_zone->zone_boot_hrtime;
848
849 zone_hrtime = gethrtime();
850 zone_lbolt = (clock_t)(NSEC_TO_TICK(zone_hrtime) -
851 NSEC_TO_TICK(curproc->p_zone->zone_zsched->p_mstart));
852 mutex_enter(&curproc->p_zone->zone_nlwps_lock);
853 zone_nproc = curproc->p_zone->zone_nprocs;
854 mutex_exit(&curproc->p_zone->zone_nlwps_lock);
855 }
856
857 system_misc_kstat.ncpus.value.ui32 = (uint32_t)myncpus;
858 system_misc_kstat.lbolt.value.ui32 = (uint32_t)zone_lbolt;
859 system_misc_kstat.deficit.value.ui32 = (uint32_t)deficit;
860 system_misc_kstat.clk_intr.value.ui32 = (uint32_t)zone_lbolt;
861 system_misc_kstat.vac.value.ui32 = (uint32_t)vac;
862 system_misc_kstat.nproc.value.ui32 = (uint32_t)zone_nproc;
863 system_misc_kstat.avenrun_1min.value.ui32 = (uint32_t)loadavgp[0];
864 system_misc_kstat.avenrun_5min.value.ui32 = (uint32_t)loadavgp[1];
865 system_misc_kstat.avenrun_15min.value.ui32 = (uint32_t)loadavgp[2];
866 system_misc_kstat.boot_time.value.ui32 = (uint32_t)
867 zone_boot_time;
868 system_misc_kstat.boot_hrtime.value.t = zone_boot_hrtime;
869 system_misc_kstat.nsec_per_tick.value.ui32 = (uint32_t)
870 nsec_per_tick;
871 return (0);
872 }
873
874 #ifdef __sparc
875 extern caddr_t econtig32;
876 #else /* !__sparc */
877 extern caddr_t econtig;
878 #endif /* __sparc */
879
880 /* ARGSUSED */
881 static int
882 system_pages_kstat_update(kstat_t *ksp, int rw)
883 {
884 kobj_stat_t kobj_stat;
885
886 if (rw == KSTAT_WRITE) {
887 return (EACCES);
888 }
|