Hi Jay, Thank you so much for many tests and reports. Jay Lan wrote: > The latest patch worked on my 2p A350 IA64 as well as on my 128p 256G > memory A4700 machines! And it still took less than 2 minutes to > complete makedumpfile on the freshly booted A4700 (compared to >6 > minutes doing 'cp --sparse=always' :) It would be fun to see how much > time to run makedumpfile on a 1TB system ;) Oh, It makes me happy :-) The latest patch will be merged to the next release. Thanks Ken'ichi Ohmichi >> The last patch contained a bug yet, so please use this patch. >> Sorry for my mistake. >> >> Ken'ichi Ohmichi wrote: >>> Yes, your test data helps me. >>> Your test informed me that there was the buffer-handling problem >>> referring different page yet, so the last patch is not enough. >>> I created the attached patch for fixing it. Could you test the >>> attached patch again ? Sorry for many tests. >>> >>> This patch is for makedumpfile-1.2.9. >>> >>> >>> Thanks >>> Ken'ichi Ohmichi >>> >>> diff -puN a/makedumpfile.c b/makedumpfile.c >>> --- a/makedumpfile.c 2008-09-25 15:39:00.000000000 +0900 >>> +++ b/makedumpfile.c 2008-09-25 15:39:17.000000000 +0900 >>> @@ -4133,6 +4133,7 @@ exclude_unnecessary_pages(void) >>> unsigned int mm; >>> unsigned long mem_map; >>> unsigned long long pfn, paddr, pfn_mm; >>> + unsigned long long pfn_read_start, pfn_read_end, index_pg; >>> unsigned char *page_cache = NULL, *pcache; >>> unsigned int _count; >>> unsigned long flags, mapping; >>> @@ -4156,6 +4157,12 @@ exclude_unnecessary_pages(void) >>> if (mem_map == NOT_MEMMAP_ADDR) >>> continue; >>> >>> + /* >>> + * Refresh the buffer of struct page, when changing mem_map. >>> + */ >>> + pfn_read_start = ULONGLONG_MAX; >>> + pfn_read_end = 0; >>> + >>> for (; pfn < mmd->pfn_end; >>> pfn++, mem_map += SIZE(page), >>> paddr += info->page_size) { >>> @@ -4166,16 +4173,23 @@ exclude_unnecessary_pages(void) >>> if (!is_in_segs(paddr)) >>> continue; >>> >>> - if ((pfn % PGMM_CACHED) == 0) { >>> - if (pfn + PGMM_CACHED < mmd->pfn_end) >>> - pfn_mm = PGMM_CACHED; >>> + index_pg = pfn % PGMM_CACHED; >>> + if (pfn < pfn_read_start || pfn_read_end < pfn) { >>> + if (roundup(pfn, PGMM_CACHED) < mmd->pfn_end) >> ~~~~~~~~~~~~~~~~~~~~~~~~~ This is a bug. >> The above should be roundup(pfn + 1, PGMM_CACHED). >> >> >> Thanks >> Ken'ichi Ohmichi >> >> --- >> diff -puN a/makedumpfile.c b/makedumpfile.c >> --- a/makedumpfile.c 2008-09-04 16:31:58.000000000 +0900 >> +++ b/makedumpfile.c 2008-09-25 20:27:48.000000000 +0900 >> @@ -4133,6 +4133,7 @@ exclude_unnecessary_pages(void) >> unsigned int mm; >> unsigned long mem_map; >> unsigned long long pfn, paddr, pfn_mm; >> + unsigned long long pfn_read_start, pfn_read_end, index_pg; >> unsigned char *page_cache = NULL, *pcache; >> unsigned int _count; >> unsigned long flags, mapping; >> @@ -4156,6 +4157,12 @@ exclude_unnecessary_pages(void) >> if (mem_map == NOT_MEMMAP_ADDR) >> continue; >> >> + /* >> + * Refresh the buffer of struct page, when changing mem_map. >> + */ >> + pfn_read_start = ULONGLONG_MAX; >> + pfn_read_end = 0; >> + >> for (; pfn < mmd->pfn_end; >> pfn++, mem_map += SIZE(page), >> paddr += info->page_size) { >> @@ -4166,16 +4173,24 @@ exclude_unnecessary_pages(void) >> if (!is_in_segs(paddr)) >> continue; >> >> - if ((pfn % PGMM_CACHED) == 0) { >> - if (pfn + PGMM_CACHED < mmd->pfn_end) >> - pfn_mm = PGMM_CACHED; >> + index_pg = pfn % PGMM_CACHED; >> + if (pfn < pfn_read_start || pfn_read_end < pfn) { >> + if (roundup(pfn + 1, PGMM_CACHED) < mmd->pfn_end) >> + pfn_mm = PGMM_CACHED - index_pg; >> else >> pfn_mm = mmd->pfn_end - pfn; >> - if (!readmem(VADDR, mem_map, page_cache, >> - SIZE(page) * pfn_mm)) >> + >> + if (!readmem(VADDR, mem_map, >> + page_cache + (index_pg * SIZE(page)), >> + SIZE(page) * pfn_mm)) { >> + ERRMSG("Can't read the buffer of struct page.\n"); >> goto out; >> + } >> + pfn_read_start = pfn; >> + pfn_read_end = pfn + pfn_mm - 1; >> } >> - pcache = page_cache + ((pfn%PGMM_CACHED) * SIZE(page)); >> + pcache = page_cache + (index_pg * SIZE(page)); >> + >> flags = ULONG(pcache + OFFSET(page.flags)); >> _count = UINT(pcache + OFFSET(page._count)); >> mapping = ULONG(pcache + OFFSET(page.mapping)); >> > >