summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/brand/lx/syscall/lx_sysinfo.c84
1 files changed, 55 insertions, 29 deletions
diff --git a/usr/src/uts/common/brand/lx/syscall/lx_sysinfo.c b/usr/src/uts/common/brand/lx/syscall/lx_sysinfo.c
index 9fdb734805..d3bb237c99 100644
--- a/usr/src/uts/common/brand/lx/syscall/lx_sysinfo.c
+++ b/usr/src/uts/common/brand/lx/syscall/lx_sysinfo.c
@@ -21,10 +21,9 @@
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2014 Joyent, Inc. All rights reserved.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <vm/anon.h>
#include <sys/systm.h>
#include <sys/sysmacros.h>
@@ -46,35 +45,25 @@ struct lx_sysinfo {
uint32_t si_mem_unit; /* Unit size of memory fields */
};
+extern pgcnt_t swapfs_minfree;
+
long
lx_sysinfo(struct lx_sysinfo *sip)
{
struct lx_sysinfo si;
- hrtime_t birthtime;
zone_t *zone = curthread->t_procp->p_zone;
- proc_t *init_proc;
+ uint64_t zphysmem, zfreemem, ztotswap, zfreeswap;
- /*
- * We don't record the time a zone was booted, so we use the
- * birthtime of that zone's init process instead.
- */
- mutex_enter(&pidlock);
- init_proc = prfind(zone->zone_proc_initpid);
- if (init_proc != NULL)
- birthtime = init_proc->p_mstart;
- else
- birthtime = p0.p_mstart;
- mutex_exit(&pidlock);
- si.si_uptime = (gethrtime() - birthtime) / NANOSEC;
+ si.si_uptime = gethrestime_sec() - zone->zone_boot_time;
/*
* We scale down the load in avenrun to allow larger load averages
* to fit in 32 bits. Linux doesn't, so we remove the scaling
* here.
*/
- si.si_loads[0] = avenrun[0] << FSHIFT;
- si.si_loads[1] = avenrun[1] << FSHIFT;
- si.si_loads[2] = avenrun[2] << FSHIFT;
+ si.si_loads[0] = zone->zone_avenrun[0] << FSHIFT;
+ si.si_loads[1] = zone->zone_avenrun[1] << FSHIFT;
+ si.si_loads[2] = zone->zone_avenrun[2] << FSHIFT;
/*
* In linux each thread looks like a process, so we conflate the
@@ -83,22 +72,59 @@ lx_sysinfo(struct lx_sysinfo *sip)
si.si_procs = (int32_t)zone->zone_nlwps;
/*
+ * If memory or swap limits are set on the zone, use those, otherwise
+ * use the system values. physmem and freemem are in pages, but the
+ * zone values are in bytes. Likewise, ani_max and ani_free are in
+ * pages.
+ */
+ if (zone->zone_phys_mem_ctl == UINT64_MAX) {
+ zphysmem = physmem;
+ zfreemem = freemem;
+ } else {
+ zphysmem = btop(zone->zone_phys_mem_ctl);
+ zfreemem = btop(zone->zone_phys_mem_ctl - zone->zone_phys_mem);
+ }
+
+ if (zone->zone_max_swap_ctl == UINT64_MAX) {
+ ztotswap = k_anoninfo.ani_max;
+ zfreeswap = k_anoninfo.ani_free;
+ } else {
+ /*
+ * See the comment in swapctl for a description of how free is
+ * calculated within a zone.
+ */
+ rctl_qty_t used;
+ spgcnt_t avail;
+ uint64_t max;
+
+ avail = MAX((spgcnt_t)(availrmem - swapfs_minfree), 0);
+ max = k_anoninfo.ani_max + k_anoninfo.ani_mem_resv + avail;
+
+ mutex_enter(&zone->zone_mem_lock);
+ ztotswap = btop(zone->zone_max_swap_ctl);
+ used = btop(zone->zone_max_swap);
+ mutex_exit(&zone->zone_mem_lock);
+
+ zfreeswap = MIN(ztotswap, max) - used;
+ }
+
+ /*
* If the maximum memory stat is less than 1^20 pages (i.e. 4GB),
* then we report the result in bytes. Otherwise we use pages.
- * Once we start supporting >1TB x86 systems, we'll need a third
+ * Once we start supporting >1TB systems/zones, we'll need a third
* option.
*/
- if (MAX(physmem, k_anoninfo.ani_max) < 1024 * 1024) {
- si.si_totalram = physmem * PAGESIZE;
- si.si_freeram = freemem * PAGESIZE;
- si.si_totalswap = k_anoninfo.ani_max * PAGESIZE;
- si.si_freeswap = k_anoninfo.ani_free * PAGESIZE;
+ if (MAX(zphysmem, ztotswap) < 1024 * 1024) {
+ si.si_totalram = ptob(zphysmem);
+ si.si_freeram = ptob(zfreemem);
+ si.si_totalswap = ptob(ztotswap);
+ si.si_freeswap = ptob(zfreeswap);
si.si_mem_unit = 1;
} else {
- si.si_totalram = physmem;
- si.si_freeram = freemem;
- si.si_totalswap = k_anoninfo.ani_max;
- si.si_freeswap = k_anoninfo.ani_free;
+ si.si_totalram = zphysmem;
+ si.si_freeram = zfreemem;
+ si.si_totalswap = ztotswap;
+ si.si_freeswap = zfreeswap;
si.si_mem_unit = PAGESIZE;
}
si.si_bufferram = 0;