xref: /minix3/minix/servers/is/dmp_vm.c (revision 4aa48abab95b2c3bef55ef84ec4b7c49368fb6f8)
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