? 2014/5/9 16:02, Atsushi Kumagai ??: >> When converting paddr to pfn, makedumpfile firstly minuses the >> offset of physical memory, and then do the right shift. But the >> kernel only does the right shift. > > Did you mean the patch below is wrong? > > commit 1e93ee75f9d47c219e833210eb31e4a747cc3a8d > Author: Mika Westerberg <ext-mika.1.westerberg at nokia.com> > Date: Tue Jun 22 09:59:10 2010 +0300 > > use ARCH_PFN_OFFSET for pfn_to_paddr/paddr_to_pfn translations > > Your description sounds we should fix the way to convert paddr to pfn, > but there is no such fix in your patch. Yes, my first version does just as what you say. But the patch is huge. I thing this patch is much better. Though commit 1e93ee75f9d47c219e833210eb31e4a747cc3a8d brings some problems . But we can easy fix them. Make my platform for example: ARCH_PFN_OFFSET=0x80000 sparse memory model. mem 1G ; SECTION_SIZE_BITS 26 (a) for the kernel section number |phy start | start pfn | end pfn | valid | mem_section | 0 |0 | 0 | 3fff | 0 | [0] | 1 |4000000 | 4000 | 7fff | 0 | [1] | 2 |8000000 | 8000 | bfff | 0 | [2] | [cut ...] 32 |80000000 | 80000 | 83fff | 1 | [32] | 33 |84000000 | 84000 | 87fff | 1 | [33] | [cut ...] 47 |bfc00000 | bfc000 | bffff | 1 | [47] | (b) for makedumpfile 0 |80000000 | 0 | 3fff | 0 | [0] | 1 |84000000 | 4000 | 7fff | 0 | [1] | [cut ...] 15 |bfc00000 | 3c000 | 3ffff | 1 | [15] | So makedumpfile removes the offset of section number and pfn. The relationship between pfn and section number remains as before. So this will not introduce problem. But the section nember and mem_section array do not match each other. For paddr 80000000 kernel : pfn 8000: mem_section: 32 makedumpfile : pfn 0 : mem_section: 0 And we do not remove the offset of array mem_section. So makedumofile can not get the right page struct. When fix this offset, everything is ok. But If we revert 1e93ee75f9d: (a) codes likes "for(pfn = 0" ,"for_each_cycle(0" and "for (section_nr = 0" should be changed; (b) Due to "set_bit_on_1st_bitmap(pfn, cycle)", we will waste some bits. (c) crash utility should also be changed. BTW, when ARCH_PFN_OFFSET=0, section nember and mem_section matches each other.. So no problem was intrduced > >> For the cases of ARCH_PFN_OFFSET=0 or non sparse memormy model, >> this introduces no problem. >> >> But for my arma9 platform with ARCH_PFN_OFFSET=0x80000 and sparse >> memory model. Makedumfile can not get the mem_map correctly. It it >> due to there is still offset for mem_map array. > > Why the other memory models are OK? There is no offset even if ARCH_PFN_OFFSET!=0? > I need more explanation to understand this issue. (1) For flatmem, the mem_map is continuous, And the start address of mem_map comes from the kernel symbol. For paddr 80000000 kernel : pfn 8000: mem_map[0] makedumpfile : pfn 0 : mem_map[0] This will not introduce problem. (2) For discontigmem, it manages the mem_map with node_memblk. commit 1e93ee75f9d47c21 also does no harm. What do you think? Thanks, Liu Hua > > > Thanks > Atsushi Kumagai > >> >> This patch introduces the offset of the mem_map. >> >> But I have no environment to test this patch for other paltfrom. >> So I am not sure this patch works on other platforms. >> >> Signed-off-by: Liu Hua <sdu.liu at huawei.com> >> --- >> makedumpfile.c | 6 ++++-- >> 1 file changed, 4 insertions(+), 2 deletions(-) >> >> diff --git a/makedumpfile.c b/makedumpfile.c >> index 94515f6..6cf6e24 100644 >> --- a/makedumpfile.c >> +++ b/makedumpfile.c >> @@ -2807,6 +2807,7 @@ int >> get_mm_sparsemem(void) >> { >> unsigned int section_nr, mem_section_size, num_section; >> + unsigned int section_start; >> mdf_pfn_t pfn_start, pfn_end; >> unsigned long section, mem_map; >> unsigned long *mem_sec = NULL; >> @@ -2817,6 +2818,7 @@ get_mm_sparsemem(void) >> * Get the address of the symbol "mem_section". >> */ >> num_section = divideup(info->max_mapnr, PAGES_PER_SECTION()); >> + section_start = ARCH_PFN_OFFSET / PAGES_PER_SECTION(); >> if (is_sparsemem_extreme()) { >> info->sections_per_root = _SECTIONS_PER_ROOT_EXTREME(); >> mem_section_size = sizeof(void *) * NR_SECTION_ROOTS(); >> @@ -2842,7 +2844,7 @@ get_mm_sparsemem(void) >> goto out; >> } >> for (section_nr = 0; section_nr < num_section; section_nr++) { >> - section = nr_to_section(section_nr, mem_sec); >> + section = nr_to_section(section_nr + section_start, mem_sec); >> if (section == NOT_KV_ADDR) { >> mem_map = NOT_MEMMAP_ADDR; >> } else { >> @@ -2851,7 +2853,7 @@ get_mm_sparsemem(void) >> mem_map = NOT_MEMMAP_ADDR; >> } else { >> mem_map = sparse_decode_mem_map(mem_map, >> - section_nr); >> + section_nr + section_start); >> if (!is_kvaddr(mem_map)) >> mem_map = NOT_MEMMAP_ADDR; >> } >> -- >> 1.9.0 > >