On Sun, Mar 24, 2019 at 03:29:04PM +0100, Thomas Gleixner wrote: > >+static int __meminit split_mem_range(struct map_range *mr, unsigned long >start, >+ unsigned long end) >+{ >+ static const struct mapinfo mapinfos[] = { > #ifdef CONFIG_X86_64 >+ { .mask = 1U << PG_LEVEL_1G, .size = PUD_SIZE }, > #endif >+ { .mask = 1U << PG_LEVEL_2M, .size = PMD_SIZE }, >+ { .mask = 0, .size = PAGE_SIZE }, >+ }; >+ const struct mapinfo *mi; >+ struct map_range *curmr; >+ unsigned long addr; >+ int idx; >+ >+ for (idx = 0, addr = start, curmr = mr; addr < end; idx++, curmr++) { >+ BUG_ON(idx == NR_RANGE_MR); >+ mr_setup(curmr, addr, end); > >+ /* Try map sizes top down. PAGE_SIZE will always succeed. */ >+ for (mi = mapinfos; !mr_try_map(curmr, mi); mi++); > >+ /* Get the start address for the next range */ >+ addr = curmr->end; > }
I re-arrange the code to make split_mem_range() here easy to read. My question is to the for loop. For example, we have a range +--+---------+-----------------------+ ^ 128M 1G 2G 128M - 4K If my understanding is correct, the original behavior will split this into three ranges: 4K size: [128M - 4K, 128M] 2M size: [128M, 1G] 1G size: [1G, 2G] While after your change, it will split this into two ranges: ?? size: [128M - 4K, 1G] 2M size: [1G, 2G] The question mark here is because you leave the page_size_mask unchanged in this case. Is my understanding correct? Or I missed something? -- Wei Yang Help you, Help me