minix/servers/is/dmp_vm.c
Ben Gras d343041caa VM: make mapping types explicit
Introduce explicit abstractions for different mapping types,
handling the instantiation, forking, pagefaults and freeing of
anonymous memory, direct physical mappings, shared memory and
physically contiguous anonymous memory as separate types, making
region.c more generic.

Also some other genericification like merging the 3 munmap cases
into one.

COW and SMAP safemap code is still implicit in region.c.
2012-10-12 14:52:01 +02:00

157 lines
3.5 KiB
C

/* Debugging dump procedures for the VM server. */
#include "inc.h"
#include <sys/mman.h>
#include <minix/vm.h>
#include <timers.h>
#include "kernel/proc.h"
#define LINES 24
static void print_region(struct vm_region_info *vri, int *n)
{
static int vri_count, vri_prev_set;
static struct vm_region_info vri_prev;
int is_repeat;
/* part of a contiguous identical run? */
is_repeat =
vri &&
vri_prev_set &&
vri->vri_prot == vri_prev.vri_prot &&
vri->vri_flags == vri_prev.vri_flags &&
vri->vri_length == vri_prev.vri_length &&
vri->vri_addr == vri_prev.vri_addr + vri_prev.vri_length;
if (vri) {
vri_prev_set = 1;
vri_prev = *vri;
} else {
vri_prev_set = 0;
}
if (is_repeat) {
vri_count++;
return;
}
if (vri_count > 0) {
printf(" (contiguously repeated %d more times)\n", vri_count);
(*n)++;
vri_count = 0;
}
/* NULL indicates the end of a list of mappings, nothing else to do */
if (!vri) return;
printf(" %08lx-%08lx %c%c%c (%lu kB)\n", vri->vri_addr,
vri->vri_addr + vri->vri_length,
(vri->vri_prot & PROT_READ) ? 'r' : '-',
(vri->vri_prot & PROT_WRITE) ? 'w' : '-',
(vri->vri_prot & PROT_EXEC) ? 'x' : '-',
vri->vri_length / 1024L);
(*n)++;
}
void vm_dmp()
{
static struct proc proc[NR_TASKS + NR_PROCS];
static struct vm_region_info vri[LINES];
struct vm_stats_info vsi;
struct vm_usage_info vui;
static int prev_i = -1;
static vir_bytes prev_base = 0;
int r, r2, i, j, first, n = 0;
if (prev_i == -1) {
if ((r = vm_info_stats(&vsi)) != OK) {
printf("IS: warning: couldn't talk to VM: %d\n", r);
return;
}
printf("Total %lu kB, free %lu kB, largest free %lu kB, cached %lu kB\n",
vsi.vsi_total * (vsi.vsi_pagesize / 1024),
vsi.vsi_free * (vsi.vsi_pagesize / 1024),
vsi.vsi_largest * (vsi.vsi_pagesize / 1024),
vsi.vsi_cached * (vsi.vsi_pagesize / 1024));
n++;
printf("\n");
n++;
prev_i++;
}
if ((r = sys_getproctab(proc)) != OK) {
printf("IS: warning: couldn't get copy of process table: %d\n", r);
return;
}
for (i = prev_i; i < NR_TASKS + NR_PROCS && n < LINES; i++, prev_base = 0) {
if (i < NR_TASKS || isemptyp(&proc[i])) continue;
/* The first batch dump for each process contains a header line. */
first = prev_base == 0;
r = vm_info_region(proc[i].p_endpoint, vri, LINES - first, &prev_base);
if (r < 0) {
printf("Process %d (%s): error %d\n",
proc[i].p_endpoint, proc[i].p_name, r);
n++;
continue;
}
if (first) {
/* The entire batch should fit on the screen. */
if (n + 1 + r > LINES) {
prev_base = 0; /* restart on next page */
break;
}
if ((r2 = vm_info_usage(proc[i].p_endpoint, &vui)) != OK) {
printf("Process %d (%s): error %d\n",
proc[i].p_endpoint, proc[i].p_name, r2);
n++;
continue;
}
printf("Process %d (%s): total %lu kB, common %lu kB, "
"shared %lu kB\n",
proc[i].p_endpoint, proc[i].p_name,
vui.vui_total / 1024L, vui.vui_common / 1024L,
vui.vui_shared / 1024L);
n++;
}
while (r > 0) {
for (j = 0; j < r; j++) {
print_region(&vri[j], &n);
}
if (LINES - n - 1 <= 0) break;
r = vm_info_region(proc[i].p_endpoint, vri, LINES - n - 1,
&prev_base);
if (r < 0) {
printf("Process %d (%s): error %d\n",
proc[i].p_endpoint, proc[i].p_name, r);
n++;
}
}
print_region(NULL, &n);
if (n > LINES) printf("IS: internal error\n");
if (n == LINES) break;
/* This may have to wipe out the "--more--" from below. */
printf(" \n");
n++;
}
if (i >= NR_TASKS + NR_PROCS) {
i = -1;
prev_base = 0;
}
else printf("--more--\r");
prev_i = i;
}