Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/amd64/minidump_machdep.c
Show First 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | |||||
static size_t fragsz; | static size_t fragsz; | ||||
static void *dump_va; | static void *dump_va; | ||||
static size_t counter, progress, dumpsize, wdog_next; | static size_t counter, progress, dumpsize, wdog_next; | ||||
static int dump_retry_count = 5; | static int dump_retry_count = 5; | ||||
SYSCTL_INT(_machdep, OID_AUTO, dump_retry_count, CTLFLAG_RWTUN, | SYSCTL_INT(_machdep, OID_AUTO, dump_retry_count, CTLFLAG_RWTUN, | ||||
&dump_retry_count, 0, "Number of times dump has to retry before bailing out"); | &dump_retry_count, 0, "Number of times dump has to retry before bailing out"); | ||||
static int | |||||
is_dumpable(vm_paddr_t pa) | |||||
{ | |||||
vm_page_t m; | |||||
int i; | |||||
if ((m = vm_phys_paddr_to_vm_page(pa)) != NULL) | |||||
return ((m->flags & PG_NODUMP) == 0); | |||||
for (i = 0; dump_avail[i] != 0 || dump_avail[i + 1] != 0; i += 2) { | |||||
if (pa >= dump_avail[i] && pa < dump_avail[i + 1]) | |||||
return (1); | |||||
} | |||||
return (0); | |||||
} | |||||
#define PG2MB(pgs) (((pgs) + (1 << 8) - 1) >> 8) | #define PG2MB(pgs) (((pgs) + (1 << 8) - 1) >> 8) | ||||
static int | static int | ||||
blk_flush(struct dumperinfo *di) | blk_flush(struct dumperinfo *di) | ||||
{ | { | ||||
int error; | int error; | ||||
if (fragsz == 0) | if (fragsz == 0) | ||||
▲ Show 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | for (va = VM_MIN_KERNEL_ADDRESS; va < MAX(KERNBASE + nkpt * NBPDR, | ||||
/* | /* | ||||
* 1GB page is represented as 512 2MB pages in a dump. | * 1GB page is represented as 512 2MB pages in a dump. | ||||
*/ | */ | ||||
if ((pdp[i] & PG_PS) != 0) { | if ((pdp[i] & PG_PS) != 0) { | ||||
va += NBPDP; | va += NBPDP; | ||||
pa = pdp[i] & PG_PS_FRAME; | pa = pdp[i] & PG_PS_FRAME; | ||||
for (n = 0; n < NPDEPG * NPTEPG; n++) { | for (n = 0; n < NPDEPG * NPTEPG; n++) { | ||||
if (is_dumpable(pa)) | if (vm_phys_is_dumpable(pa)) | ||||
dump_add_page(pa); | dump_add_page(pa); | ||||
pa += PAGE_SIZE; | pa += PAGE_SIZE; | ||||
} | } | ||||
continue; | continue; | ||||
} | } | ||||
pd = (uint64_t *)PHYS_TO_DMAP(pdp[i] & PG_FRAME); | pd = (uint64_t *)PHYS_TO_DMAP(pdp[i] & PG_FRAME); | ||||
for (n = 0; n < NPDEPG; n++, va += NBPDR) { | for (n = 0; n < NPDEPG; n++, va += NBPDR) { | ||||
j = pmap_pde_index(va); | j = pmap_pde_index(va); | ||||
if ((pd[j] & PG_V) == 0) | if ((pd[j] & PG_V) == 0) | ||||
continue; | continue; | ||||
if ((pd[j] & PG_PS) != 0) { | if ((pd[j] & PG_PS) != 0) { | ||||
/* This is an entire 2M page. */ | /* This is an entire 2M page. */ | ||||
pa = pd[j] & PG_PS_FRAME; | pa = pd[j] & PG_PS_FRAME; | ||||
for (k = 0; k < NPTEPG; k++) { | for (k = 0; k < NPTEPG; k++) { | ||||
if (is_dumpable(pa)) | if (vm_phys_is_dumpable(pa)) | ||||
dump_add_page(pa); | dump_add_page(pa); | ||||
pa += PAGE_SIZE; | pa += PAGE_SIZE; | ||||
} | } | ||||
continue; | continue; | ||||
} | } | ||||
pa = pd[j] & PG_FRAME; | pa = pd[j] & PG_FRAME; | ||||
/* set bit for this PTE page */ | /* set bit for this PTE page */ | ||||
if (is_dumpable(pa)) | if (vm_phys_is_dumpable(pa)) | ||||
dump_add_page(pa); | dump_add_page(pa); | ||||
/* and for each valid page in this 2MB block */ | /* and for each valid page in this 2MB block */ | ||||
pt = (uint64_t *)PHYS_TO_DMAP(pd[j] & PG_FRAME); | pt = (uint64_t *)PHYS_TO_DMAP(pd[j] & PG_FRAME); | ||||
for (k = 0; k < NPTEPG; k++) { | for (k = 0; k < NPTEPG; k++) { | ||||
if ((pt[k] & PG_V) == 0) | if ((pt[k] & PG_V) == 0) | ||||
continue; | continue; | ||||
pa = pt[k] & PG_FRAME; | pa = pt[k] & PG_FRAME; | ||||
if (is_dumpable(pa)) | if (vm_phys_is_dumpable(pa)) | ||||
dump_add_page(pa); | dump_add_page(pa); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/* Calculate dump size. */ | /* Calculate dump size. */ | ||||
dumpsize = pmapsize; | dumpsize = pmapsize; | ||||
dumpsize += round_page(msgbufp->msg_size); | dumpsize += round_page(msgbufp->msg_size); | ||||
dumpsize += round_page(sizeof(dump_avail)); | dumpsize += round_page(sizeof(dump_avail)); | ||||
dumpsize += round_page(BITSET_SIZE(vm_page_dump_pages)); | dumpsize += round_page(BITSET_SIZE(vm_page_dump_pages)); | ||||
VM_PAGE_DUMP_FOREACH(pa) { | VM_PAGE_DUMP_FOREACH(pa) { | ||||
/* Clear out undumpable pages now if needed */ | /* Clear out undumpable pages now if needed */ | ||||
if (is_dumpable(pa)) { | if (vm_phys_is_dumpable(pa)) { | ||||
dumpsize += PAGE_SIZE; | dumpsize += PAGE_SIZE; | ||||
} else { | } else { | ||||
dump_drop_page(pa); | dump_drop_page(pa); | ||||
} | } | ||||
} | } | ||||
dumpsize += PAGE_SIZE; | dumpsize += PAGE_SIZE; | ||||
wdog_next = progress = dumpsize; | wdog_next = progress = dumpsize; | ||||
▲ Show 20 Lines • Show All 137 Lines • Show Last 20 Lines |