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 }