David van Moolenbroek 25d39513e7 MIB: initial tree population
Change-Id: I28ef0a81a59faaf341bfc15178df89474779a136
2016-01-13 20:32:44 +01:00

155 lines
4.5 KiB
C

/* MIB service - vm.c - implementation of the CTL_VM subtree */
#include "mib.h"
#include <sys/resource.h>
#include <uvm/uvm_extern.h>
/*
* Implementation of CTL_VM VM_LOADAVG.
*/
static ssize_t
mib_vm_loadavg(struct mib_call * call __unused,
struct mib_node * node __unused, struct mib_oldp * oldp,
struct mib_newp * newp __unused)
{
struct loadavg loadavg;
struct loadinfo loadinfo;
unsigned long proc_load;
u32_t ticks_per_slot, ticks;
unsigned int p;
int unfilled_ticks;
int h, slots, latest, slot;
int minutes[3] = { 1, 5, 15 };
assert(__arraycount(loadavg.ldavg) == __arraycount(minutes));
if (sys_getloadinfo(&loadinfo) != OK)
return EINVAL;
memset(&loadavg, 0, sizeof(loadavg));
/*
* The following code is inherited from the old MINIX libc.
*/
/* How many ticks are missing from the newest-filled slot? */
ticks_per_slot = _LOAD_UNIT_SECS * sys_hz();
unfilled_ticks =
ticks_per_slot - (loadinfo.last_clock % ticks_per_slot);
for (p = 0; p < __arraycount(loadavg.ldavg); p++) {
latest = loadinfo.proc_last_slot;
slots = minutes[p] * 60 / _LOAD_UNIT_SECS;
proc_load = 0;
/*
* Add up the total number of process ticks for this number
* of minutes (minutes[p]). Start with the newest slot, which
* is latest, and count back for the number of slots that
* correspond to the right number of minutes. Take wraparound
* into account by calculating the index modulo _LOAD_HISTORY,
* which is the number of slots of history kept.
*/
for (h = 0; h < slots; h++) {
slot = (latest - h + _LOAD_HISTORY) % _LOAD_HISTORY;
proc_load += loadinfo.proc_load_history[slot];
}
/*
* The load average over this number of minutes is the number
* of process-ticks divided by the number of ticks, not
* counting the number of ticks the last slot hasn't been
* around yet.
*/
ticks = slots * ticks_per_slot - unfilled_ticks;
loadavg.ldavg[p] = 100UL * proc_load / ticks;
}
loadavg.fscale = 100L;
return mib_copyout(oldp, 0, &loadavg, sizeof(loadavg));
}
/*
* Implementation of CTL_VM VM_UVMEXP2.
*/
static ssize_t
mib_vm_uvmexp2(struct mib_call * call __unused,
struct mib_node * node __unused, struct mib_oldp * oldp,
struct mib_newp * newp __unused)
{
struct vm_stats_info vsi;
struct uvmexp_sysctl ues;
unsigned int shift;
if (vm_info_stats(&vsi) != OK)
return EINVAL;
memset(&ues, 0, sizeof(ues));
/*
* TODO: by far most of the structure is not filled correctly yet,
* since the MINIX3 system does not provide much of the information
* exposed by NetBSD. This will gradually have to be filled in.
* For now, we provide just some basic information used by top(1).
*/
ues.pagesize = vsi.vsi_pagesize;
ues.pagemask = vsi.vsi_pagesize - 1;
for (shift = 0; shift < CHAR_BIT * sizeof(void *); shift++)
if ((1U << shift) == vsi.vsi_pagesize)
break;
if (shift < CHAR_BIT * sizeof(void *))
ues.pageshift = shift;
ues.npages = vsi.vsi_total;
ues.free = vsi.vsi_free;
ues.filepages = vsi.vsi_cached;
/*
* We use one of the structure's unused fields to expose information
* not exposed by NetBSD, namely the largest area of physically
* contiguous memory. If NetBSD repurposes this field, we have to find
* another home for it (or expose it through a separate node or so).
*/
ues.unused1 = vsi.vsi_largest;
return mib_copyout(oldp, 0, &ues, sizeof(ues));
}
/* The CTL_VM nodes. */
static struct mib_node mib_vm_table[] = {
/* 1*/ /* VM_METER: not yet supported */
/* 2*/ [VM_LOADAVG] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT,
sizeof(struct loadavg), mib_vm_loadavg,
"loadavg", "System load average history"),
/* 3*/ /* VM_UVMEXP: not yet supported */
/* 4*/ /* VM_NKMEMPAGES: not yet supported */
/* 5*/ [VM_UVMEXP2] = MIB_FUNC(_P | _RO | CTLTYPE_STRUCT,
sizeof(struct uvmexp_sysctl),
mib_vm_uvmexp2, "uvmexp2",
"Detailed system-wide virtual memory "
"statistics (MI)"),
/* 6*/ /* VM_ANONMIN: not yet supported */
/* 7*/ /* VM_EXECMIN: not yet supported */
/* 8*/ /* VM_FILEMIN: not yet supported */
/* 9*/ [VM_MAXSLP] = MIB_INT(_P | _RO, MAXSLP, "maxslp",
"Maximum process sleep time before being "
"swapped"),
/*10*/ [VM_USPACE] = MIB_INT(_P | _RO, 0, "uspace", "Number of "
"bytes allocated for a kernel stack"),
/* MINIX3 processes don't have k-stacks */
/*11*/ /* VM_ANONMAX: not yet supported */
/*12*/ /* VM_EXECMAX: not yet supported */
/*13*/ /* VM_FILEMAX: not yet supported */
};
/*
* Initialize the CTL_VM subtree.
*/
void
mib_vm_init(struct mib_node * node)
{
MIB_INIT_ENODE(node, mib_vm_table);
}