1 /* MIB service - vm.c - implementation of the CTL_VM subtree */
5 #include <sys/resource.h>
6 #include <uvm/uvm_extern.h>
9 * Implementation of CTL_VM VM_LOADAVG.
12 mib_vm_loadavg(struct mib_call
* call __unused
,
13 struct mib_node
* node __unused
, struct mib_oldp
* oldp
,
14 struct mib_newp
* newp __unused
)
16 struct loadavg loadavg
;
17 struct loadinfo loadinfo
;
18 unsigned long proc_load
;
19 u32_t ticks_per_slot
, ticks
;
22 int h
, slots
, latest
, slot
;
23 int minutes
[3] = { 1, 5, 15 };
25 assert(__arraycount(loadavg
.ldavg
) == __arraycount(minutes
));
27 if (sys_getloadinfo(&loadinfo
) != OK
)
30 memset(&loadavg
, 0, sizeof(loadavg
));
33 * The following code is inherited from the old MINIX libc.
36 /* How many ticks are missing from the newest-filled slot? */
37 ticks_per_slot
= _LOAD_UNIT_SECS
* sys_hz();
39 ticks_per_slot
- (loadinfo
.last_clock
% ticks_per_slot
);
41 for (p
= 0; p
< __arraycount(loadavg
.ldavg
); p
++) {
42 latest
= loadinfo
.proc_last_slot
;
43 slots
= minutes
[p
] * 60 / _LOAD_UNIT_SECS
;
47 * Add up the total number of process ticks for this number
48 * of minutes (minutes[p]). Start with the newest slot, which
49 * is latest, and count back for the number of slots that
50 * correspond to the right number of minutes. Take wraparound
51 * into account by calculating the index modulo _LOAD_HISTORY,
52 * which is the number of slots of history kept.
54 for (h
= 0; h
< slots
; h
++) {
55 slot
= (latest
- h
+ _LOAD_HISTORY
) % _LOAD_HISTORY
;
56 proc_load
+= loadinfo
.proc_load_history
[slot
];
60 * The load average over this number of minutes is the number
61 * of process-ticks divided by the number of ticks, not
62 * counting the number of ticks the last slot hasn't been
65 ticks
= slots
* ticks_per_slot
- unfilled_ticks
;
67 loadavg
.ldavg
[p
] = 100UL * proc_load
/ ticks
;
70 loadavg
.fscale
= 100L;
72 return mib_copyout(oldp
, 0, &loadavg
, sizeof(loadavg
));
76 * Implementation of CTL_VM VM_UVMEXP2.
79 mib_vm_uvmexp2(struct mib_call
* call __unused
,
80 struct mib_node
* node __unused
, struct mib_oldp
* oldp
,
81 struct mib_newp
* newp __unused
)
83 struct vm_stats_info vsi
;
84 struct uvmexp_sysctl ues
;
87 if (vm_info_stats(&vsi
) != OK
)
90 memset(&ues
, 0, sizeof(ues
));
93 * TODO: by far most of the structure is not filled correctly yet,
94 * since the MINIX3 system does not provide much of the information
95 * exposed by NetBSD. This will gradually have to be filled in.
96 * For now, we provide just some basic information used by top(1).
98 ues
.pagesize
= vsi
.vsi_pagesize
;
99 ues
.pagemask
= vsi
.vsi_pagesize
- 1;
100 for (shift
= 0; shift
< CHAR_BIT
* sizeof(void *); shift
++)
101 if ((1U << shift
) == vsi
.vsi_pagesize
)
103 if (shift
< CHAR_BIT
* sizeof(void *))
104 ues
.pageshift
= shift
;
105 ues
.npages
= vsi
.vsi_total
;
106 ues
.free
= vsi
.vsi_free
;
107 ues
.filepages
= vsi
.vsi_cached
;
109 * We use one of the structure's unused fields to expose information
110 * not exposed by NetBSD, namely the largest area of physically
111 * contiguous memory. If NetBSD repurposes this field, we have to find
112 * another home for it (or expose it through a separate node or so).
114 ues
.unused1
= vsi
.vsi_largest
;
116 return mib_copyout(oldp
, 0, &ues
, sizeof(ues
));
119 /* The CTL_VM nodes. */
120 static struct mib_node mib_vm_table
[] = {
121 /* 1*/ /* VM_METER: not yet supported */
122 /* 2*/ [VM_LOADAVG
] = MIB_FUNC(_P
| _RO
| CTLTYPE_STRUCT
,
123 sizeof(struct loadavg
), mib_vm_loadavg
,
124 "loadavg", "System load average history"),
125 /* 3*/ /* VM_UVMEXP: not yet supported */
126 /* 4*/ /* VM_NKMEMPAGES: not yet supported */
127 /* 5*/ [VM_UVMEXP2
] = MIB_FUNC(_P
| _RO
| CTLTYPE_STRUCT
,
128 sizeof(struct uvmexp_sysctl
),
129 mib_vm_uvmexp2
, "uvmexp2",
130 "Detailed system-wide virtual memory "
132 /* 6*/ /* VM_ANONMIN: not yet supported */
133 /* 7*/ /* VM_EXECMIN: not yet supported */
134 /* 8*/ /* VM_FILEMIN: not yet supported */
135 /* 9*/ [VM_MAXSLP
] = MIB_INT(_P
| _RO
, MAXSLP
, "maxslp",
136 "Maximum process sleep time before being "
138 /*10*/ [VM_USPACE
] = MIB_INT(_P
| _RO
, 0, "uspace", "Number of "
139 "bytes allocated for a kernel stack"),
140 /* MINIX3 processes don't have k-stacks */
141 /*11*/ /* VM_ANONMAX: not yet supported */
142 /*12*/ /* VM_EXECMAX: not yet supported */
143 /*13*/ /* VM_FILEMAX: not yet supported */
147 * Initialize the CTL_VM subtree.
150 mib_vm_init(struct mib_node
* node
)
153 MIB_INIT_ENODE(node
, mib_vm_table
);