Print this page
Add boot_hrtime to global and zone kstats.


   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         }