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.
156 lines
3.5 KiB
C
156 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;
|
|
}
|
|
|