1 /* 2 * CDDL HEADER START 3 * 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. 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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <vm/anon.h> 29 #include <sys/systm.h> 30 #include <sys/sysmacros.h> 31 #include <sys/zone.h> 32 #include <sys/time.h> 33 34 struct lx_sysinfo { 35 int32_t si_uptime; /* Seconds since boot */ 36 uint32_t si_loads[3]; /* 1, 5, and 15 minute avg runq length */ 37 uint32_t si_totalram; /* Total memory size */ 38 uint32_t si_freeram; /* Available memory */ 39 uint32_t si_sharedram; /* Shared memory */ 40 uint32_t si_bufferram; /* Buffer memory */ 41 uint32_t si_totalswap; /* Total swap space */ 42 uint32_t si_freeswap; /* Avail swap space */ 43 uint16_t si_procs; /* Process count */ 44 uint32_t si_totalhigh; /* High memory size */ 45 uint32_t si_freehigh; /* Avail high memory */ 46 uint32_t si_mem_unit; /* Unit size of memory fields */ 47 }; 48 49 long 50 lx_sysinfo(struct lx_sysinfo *sip) 51 { 52 struct lx_sysinfo si; 53 hrtime_t birthtime; 54 zone_t *zone = curthread->t_procp->p_zone; 55 proc_t *init_proc; 56 57 /* 58 * We don't record the time a zone was booted, so we use the 59 * birthtime of that zone's init process instead. 60 */ 61 mutex_enter(&pidlock); 62 init_proc = prfind(zone->zone_proc_initpid); 63 if (init_proc != NULL) 64 birthtime = init_proc->p_mstart; 65 else 66 birthtime = p0.p_mstart; 67 mutex_exit(&pidlock); 68 si.si_uptime = (gethrtime() - birthtime) / NANOSEC; 69 70 /* 71 * We scale down the load in avenrun to allow larger load averages 72 * to fit in 32 bits. Linux doesn't, so we remove the scaling 73 * here. 74 */ 75 si.si_loads[0] = avenrun[0] << FSHIFT; 76 si.si_loads[1] = avenrun[1] << FSHIFT; 77 si.si_loads[2] = avenrun[2] << FSHIFT; 78 79 /* 80 * In linux each thread looks like a process, so we conflate the 81 * two in this stat as well. 82 */ 83 si.si_procs = (int32_t)zone->zone_nlwps; 84 85 /* 86 * If the maximum memory stat is less than 1^20 pages (i.e. 4GB), 87 * then we report the result in bytes. Otherwise we use pages. 88 * Once we start supporting >1TB x86 systems, we'll need a third 89 * option. 90 */ 91 if (MAX(physmem, k_anoninfo.ani_max) < 1024 * 1024) { 92 si.si_totalram = physmem * PAGESIZE; 93 si.si_freeram = freemem * PAGESIZE; 94 si.si_totalswap = k_anoninfo.ani_max * PAGESIZE; 95 si.si_freeswap = k_anoninfo.ani_free * PAGESIZE; 96 si.si_mem_unit = 1; 97 } else { 98 si.si_totalram = physmem; 99 si.si_freeram = freemem; 100 si.si_totalswap = k_anoninfo.ani_max; 101 si.si_freeswap = k_anoninfo.ani_free; 102 si.si_mem_unit = PAGESIZE; 103 } 104 si.si_bufferram = 0; 105 si.si_sharedram = 0; 106 107 /* 108 * These two stats refer to high physical memory. If an 109 * application running in a Linux zone cares about this, then 110 * either it or we are broken. 111 */ 112 si.si_totalhigh = 0; 113 si.si_freehigh = 0; 114 115 if (copyout(&si, sip, sizeof (si)) != 0) 116 return (set_errno(EFAULT)); 117 return (0); 118 }