Changeset View
Changeset View
Standalone View
Standalone View
sys/powerpc/powerpc/minidump_machdep.c
Show First 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | |||||
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, | &dump_retry_count, 0, | ||||
"Number of times dump has to retry before bailing out"); | "Number of times dump has to retry before bailing out"); | ||||
static struct kerneldumpheader kdh; | static struct kerneldumpheader kdh; | ||||
static char pgbuf[PAGE_SIZE]; | static char pgbuf[PAGE_SIZE]; | ||||
static struct { | static size_t dumpsize; | ||||
int min_per; | |||||
int max_per; | |||||
int visited; | |||||
} progress_track[10] = { | |||||
{ 0, 10, 0}, | |||||
{ 10, 20, 0}, | |||||
{ 20, 30, 0}, | |||||
{ 30, 40, 0}, | |||||
{ 40, 50, 0}, | |||||
{ 50, 60, 0}, | |||||
{ 60, 70, 0}, | |||||
{ 70, 80, 0}, | |||||
{ 80, 90, 0}, | |||||
{ 90, 100, 0} | |||||
}; | |||||
static size_t counter, dumpsize, progress; | |||||
/* Handle chunked writes. */ | /* Handle chunked writes. */ | ||||
static size_t fragsz; | static size_t fragsz; | ||||
static void | static void | ||||
pmap_kenter_temporary(vm_offset_t va, vm_paddr_t pa) | pmap_kenter_temporary(vm_offset_t va, vm_paddr_t pa) | ||||
{ | { | ||||
pmap_kremove(va); | pmap_kremove(va); | ||||
pmap_kenter(va, pa); | pmap_kenter(va, pa); | ||||
} | } | ||||
static void | |||||
report_progress(void) | |||||
{ | |||||
int sofar, i; | |||||
sofar = 100 - ((progress * 100) / dumpsize); | |||||
for (i = 0; i < nitems(progress_track); i++) { | |||||
if (sofar < progress_track[i].min_per || | |||||
sofar > progress_track[i].max_per) | |||||
continue; | |||||
if (progress_track[i].visited) | |||||
return; | |||||
progress_track[i].visited = 1; | |||||
printf("..%d%%", sofar); | |||||
return; | |||||
} | |||||
} | |||||
static int | static int | ||||
blk_flush(struct dumperinfo *di) | blk_flush(struct dumperinfo *di) | ||||
{ | { | ||||
int error; | int error; | ||||
if (fragsz == 0) | if (fragsz == 0) | ||||
return (0); | return (0); | ||||
Show All 33 Lines | if (ptr != NULL) { | ||||
error = blk_flush(di); | error = blk_flush(di); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
} | } | ||||
while (sz) { | while (sz) { | ||||
len = maxdumpsz - fragsz; | len = maxdumpsz - fragsz; | ||||
if (len > sz) | if (len > sz) | ||||
len = sz; | len = sz; | ||||
counter += len; | |||||
progress -= len; | |||||
if (counter >> 20) { | |||||
report_progress(); | |||||
counter &= (1<<20) - 1; | |||||
} | |||||
dumpsys_pb_progress(len); | |||||
if (ptr) { | if (ptr) { | ||||
error = dump_append(di, ptr, 0, len); | error = dump_append(di, ptr, 0, len); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
DBG(dumptotal += len;) | DBG(dumptotal += len;) | ||||
ptr += len; | ptr += len; | ||||
} else { | } else { | ||||
for (i = 0; i < len; i += PAGE_SIZE) | for (i = 0; i < len; i += PAGE_SIZE) | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | dump_pmap(struct dumperinfo *di) | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
minidumpsys(struct dumperinfo *di) | minidumpsys(struct dumperinfo *di) | ||||
{ | { | ||||
vm_paddr_t pa; | vm_paddr_t pa; | ||||
int error, i, retry_count; | int error, retry_count; | ||||
uint32_t pmapsize; | uint32_t pmapsize; | ||||
struct minidumphdr mdhdr; | struct minidumphdr mdhdr; | ||||
retry_count = 0; | retry_count = 0; | ||||
retry: | retry: | ||||
retry_count++; | retry_count++; | ||||
fragsz = 0; | fragsz = 0; | ||||
DBG(total = dumptotal = 0;) | DBG(total = dumptotal = 0;) | ||||
/* Reset progress */ | |||||
counter = 0; | |||||
for (i = 0; i < nitems(progress_track); i++) | |||||
progress_track[i].visited = 0; | |||||
/* Build set of dumpable pages from kernel pmap */ | /* Build set of dumpable pages from kernel pmap */ | ||||
pmapsize = dumpsys_scan_pmap(); | pmapsize = dumpsys_scan_pmap(); | ||||
if (pmapsize % PAGE_SIZE != 0) { | if (pmapsize % PAGE_SIZE != 0) { | ||||
printf("pmapsize not page aligned: 0x%x\n", pmapsize); | printf("pmapsize not page aligned: 0x%x\n", pmapsize); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
/* Calculate dump size */ | /* Calculate dump size */ | ||||
dumpsize = PAGE_SIZE; /* header */ | dumpsize = PAGE_SIZE; /* header */ | ||||
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)); | ||||
dumpsize += pmapsize; | dumpsize += pmapsize; | ||||
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 (dump_page_is_dumpable(pa)) | if (dump_page_is_dumpable(pa)) | ||||
dumpsize += PAGE_SIZE; | dumpsize += PAGE_SIZE; | ||||
else | else | ||||
dump_drop_page(pa); | dump_drop_page(pa); | ||||
} | } | ||||
progress = dumpsize; | dumpsys_pb_init(dumpsize); | ||||
/* Initialize mdhdr */ | /* Initialize mdhdr */ | ||||
bzero(&mdhdr, sizeof(mdhdr)); | bzero(&mdhdr, sizeof(mdhdr)); | ||||
strcpy(mdhdr.magic, MINIDUMP_MAGIC); | strcpy(mdhdr.magic, MINIDUMP_MAGIC); | ||||
strncpy(mdhdr.mmu_name, pmap_mmu_name(), sizeof(mdhdr.mmu_name) - 1); | strncpy(mdhdr.mmu_name, pmap_mmu_name(), sizeof(mdhdr.mmu_name) - 1); | ||||
mdhdr.version = MINIDUMP_VERSION; | mdhdr.version = MINIDUMP_VERSION; | ||||
mdhdr.msgbufsize = msgbufp->msg_size; | mdhdr.msgbufsize = msgbufp->msg_size; | ||||
mdhdr.bitmapsize = round_page(BITSET_SIZE(vm_page_dump_pages)); | mdhdr.bitmapsize = round_page(BITSET_SIZE(vm_page_dump_pages)); | ||||
▲ Show 20 Lines • Show All 105 Lines • Show Last 20 Lines |