Re: [PATCH 4/6] x86, mm: make split_mem_range() more easy to read

From: Wei Yang
Date: Thu Mar 28 2019 - 03:20:52 EST


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