1433d6423SLionel Sambuc /* Debugging dump procedures for the VM server. */
2433d6423SLionel Sambuc
3433d6423SLionel Sambuc #include "inc.h"
4433d6423SLionel Sambuc #include <sys/mman.h>
5433d6423SLionel Sambuc #include <minix/vm.h>
6433d6423SLionel Sambuc #include <minix/timers.h>
7433d6423SLionel Sambuc #include "kernel/proc.h"
8433d6423SLionel Sambuc
9433d6423SLionel Sambuc #define LINES 24
10433d6423SLionel Sambuc
print_region(struct vm_region_info * vri,int * n)11433d6423SLionel Sambuc static void print_region(struct vm_region_info *vri, int *n)
12433d6423SLionel Sambuc {
13433d6423SLionel Sambuc static int vri_count, vri_prev_set;
14433d6423SLionel Sambuc static struct vm_region_info vri_prev;
15433d6423SLionel Sambuc int is_repeat;
16433d6423SLionel Sambuc
17433d6423SLionel Sambuc /* part of a contiguous identical run? */
18433d6423SLionel Sambuc is_repeat =
19433d6423SLionel Sambuc vri &&
20433d6423SLionel Sambuc vri_prev_set &&
21433d6423SLionel Sambuc vri->vri_prot == vri_prev.vri_prot &&
22433d6423SLionel Sambuc vri->vri_flags == vri_prev.vri_flags &&
23433d6423SLionel Sambuc vri->vri_length == vri_prev.vri_length &&
24433d6423SLionel Sambuc vri->vri_addr == vri_prev.vri_addr + vri_prev.vri_length;
25433d6423SLionel Sambuc if (vri) {
26433d6423SLionel Sambuc vri_prev_set = 1;
27433d6423SLionel Sambuc vri_prev = *vri;
28433d6423SLionel Sambuc } else {
29433d6423SLionel Sambuc vri_prev_set = 0;
30433d6423SLionel Sambuc }
31433d6423SLionel Sambuc if (is_repeat) {
32433d6423SLionel Sambuc vri_count++;
33433d6423SLionel Sambuc return;
34433d6423SLionel Sambuc }
35433d6423SLionel Sambuc
36433d6423SLionel Sambuc if (vri_count > 0) {
37433d6423SLionel Sambuc printf(" (contiguously repeated %d more times)\n", vri_count);
38433d6423SLionel Sambuc (*n)++;
39433d6423SLionel Sambuc vri_count = 0;
40433d6423SLionel Sambuc }
41433d6423SLionel Sambuc
42433d6423SLionel Sambuc /* NULL indicates the end of a list of mappings, nothing else to do */
43433d6423SLionel Sambuc if (!vri) return;
44433d6423SLionel Sambuc
45433d6423SLionel Sambuc printf(" %08lx-%08lx %c%c%c (%lu kB)\n", vri->vri_addr,
46433d6423SLionel Sambuc vri->vri_addr + vri->vri_length,
47433d6423SLionel Sambuc (vri->vri_prot & PROT_READ) ? 'r' : '-',
48433d6423SLionel Sambuc (vri->vri_prot & PROT_WRITE) ? 'w' : '-',
49433d6423SLionel Sambuc (vri->vri_prot & PROT_EXEC) ? 'x' : '-',
50433d6423SLionel Sambuc vri->vri_length / 1024L);
51433d6423SLionel Sambuc (*n)++;
52433d6423SLionel Sambuc }
53433d6423SLionel Sambuc
54*4aa48abaSRichard Sailer void
vm_dmp(void)55*4aa48abaSRichard Sailer vm_dmp(void)
56433d6423SLionel Sambuc {
57433d6423SLionel Sambuc static struct proc proc[NR_TASKS + NR_PROCS];
58433d6423SLionel Sambuc static struct vm_region_info vri[LINES];
59433d6423SLionel Sambuc struct vm_stats_info vsi;
60433d6423SLionel Sambuc struct vm_usage_info vui;
61433d6423SLionel Sambuc static int prev_i = -1;
62433d6423SLionel Sambuc static vir_bytes prev_base = 0;
63433d6423SLionel Sambuc int r, r2, i, j, first, n = 0;
64433d6423SLionel Sambuc
65433d6423SLionel Sambuc if (prev_i == -1) {
66433d6423SLionel Sambuc if ((r = vm_info_stats(&vsi)) != OK) {
67433d6423SLionel Sambuc printf("IS: warning: couldn't talk to VM: %d\n", r);
68433d6423SLionel Sambuc return;
69433d6423SLionel Sambuc }
70433d6423SLionel Sambuc
71433d6423SLionel Sambuc printf("Total %lu kB, free %lu kB, largest free %lu kB, cached %lu kB\n",
72433d6423SLionel Sambuc vsi.vsi_total * (vsi.vsi_pagesize / 1024),
73433d6423SLionel Sambuc vsi.vsi_free * (vsi.vsi_pagesize / 1024),
74433d6423SLionel Sambuc vsi.vsi_largest * (vsi.vsi_pagesize / 1024),
75433d6423SLionel Sambuc vsi.vsi_cached * (vsi.vsi_pagesize / 1024));
76433d6423SLionel Sambuc n++;
77433d6423SLionel Sambuc printf("\n");
78433d6423SLionel Sambuc n++;
79433d6423SLionel Sambuc
80433d6423SLionel Sambuc prev_i++;
81433d6423SLionel Sambuc }
82433d6423SLionel Sambuc
83433d6423SLionel Sambuc if ((r = sys_getproctab(proc)) != OK) {
84433d6423SLionel Sambuc printf("IS: warning: couldn't get copy of process table: %d\n", r);
85433d6423SLionel Sambuc return;
86433d6423SLionel Sambuc }
87433d6423SLionel Sambuc
88433d6423SLionel Sambuc for (i = prev_i; i < NR_TASKS + NR_PROCS && n < LINES; i++, prev_base = 0) {
89433d6423SLionel Sambuc if (i < NR_TASKS || isemptyp(&proc[i])) continue;
90433d6423SLionel Sambuc
91433d6423SLionel Sambuc /* The first batch dump for each process contains a header line. */
92433d6423SLionel Sambuc first = prev_base == 0;
93433d6423SLionel Sambuc
94433d6423SLionel Sambuc r = vm_info_region(proc[i].p_endpoint, vri, LINES - first, &prev_base);
95433d6423SLionel Sambuc
96433d6423SLionel Sambuc if (r < 0) {
97433d6423SLionel Sambuc printf("Process %d (%s): error %d\n",
98433d6423SLionel Sambuc proc[i].p_endpoint, proc[i].p_name, r);
99433d6423SLionel Sambuc n++;
100433d6423SLionel Sambuc continue;
101433d6423SLionel Sambuc }
102433d6423SLionel Sambuc
103433d6423SLionel Sambuc if (first) {
104433d6423SLionel Sambuc /* The entire batch should fit on the screen. */
105433d6423SLionel Sambuc if (n + 1 + r > LINES) {
106433d6423SLionel Sambuc prev_base = 0; /* restart on next page */
107433d6423SLionel Sambuc break;
108433d6423SLionel Sambuc }
109433d6423SLionel Sambuc
110433d6423SLionel Sambuc if ((r2 = vm_info_usage(proc[i].p_endpoint, &vui)) != OK) {
111433d6423SLionel Sambuc printf("Process %d (%s): error %d\n",
112433d6423SLionel Sambuc proc[i].p_endpoint, proc[i].p_name, r2);
113433d6423SLionel Sambuc n++;
114433d6423SLionel Sambuc continue;
115433d6423SLionel Sambuc }
116433d6423SLionel Sambuc
117433d6423SLionel Sambuc printf("Process %d (%s): total %lu kB, common %lu kB, "
118433d6423SLionel Sambuc "shared %lu kB\n",
119433d6423SLionel Sambuc proc[i].p_endpoint, proc[i].p_name,
120433d6423SLionel Sambuc vui.vui_total / 1024L, vui.vui_common / 1024L,
121433d6423SLionel Sambuc vui.vui_shared / 1024L);
122433d6423SLionel Sambuc n++;
123433d6423SLionel Sambuc }
124433d6423SLionel Sambuc
125433d6423SLionel Sambuc while (r > 0) {
126433d6423SLionel Sambuc for (j = 0; j < r; j++) {
127433d6423SLionel Sambuc print_region(&vri[j], &n);
128433d6423SLionel Sambuc }
129433d6423SLionel Sambuc
130433d6423SLionel Sambuc if (LINES - n - 1 <= 0) break;
131433d6423SLionel Sambuc r = vm_info_region(proc[i].p_endpoint, vri, LINES - n - 1,
132433d6423SLionel Sambuc &prev_base);
133433d6423SLionel Sambuc
134433d6423SLionel Sambuc if (r < 0) {
135433d6423SLionel Sambuc printf("Process %d (%s): error %d\n",
136433d6423SLionel Sambuc proc[i].p_endpoint, proc[i].p_name, r);
137433d6423SLionel Sambuc n++;
138433d6423SLionel Sambuc }
139433d6423SLionel Sambuc }
140433d6423SLionel Sambuc print_region(NULL, &n);
141433d6423SLionel Sambuc
142433d6423SLionel Sambuc if (n > LINES) printf("IS: internal error\n");
143433d6423SLionel Sambuc if (n == LINES) break;
144433d6423SLionel Sambuc
145433d6423SLionel Sambuc /* This may have to wipe out the "--more--" from below. */
146433d6423SLionel Sambuc printf(" \n");
147433d6423SLionel Sambuc n++;
148433d6423SLionel Sambuc }
149433d6423SLionel Sambuc
150433d6423SLionel Sambuc if (i >= NR_TASKS + NR_PROCS) {
151433d6423SLionel Sambuc i = -1;
152433d6423SLionel Sambuc prev_base = 0;
153433d6423SLionel Sambuc }
154433d6423SLionel Sambuc else printf("--more--\r");
155433d6423SLionel Sambuc prev_i = i;
156433d6423SLionel Sambuc }
157433d6423SLionel Sambuc
158