lkml.org 
[lkml]   [2010]   [Oct]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH 0/4] memblock related fixes for -tip
 On 10/12/2010 10:40 PM, Yinghai Lu wrote:
> On 10/12/2010 04:37 PM, Jeremy Fitzhardinge wrote:
>> On 10/12/2010 02:12 PM, Yinghai Lu wrote:
>>> On 10/12/2010 11:41 AM, Jeremy Fitzhardinge wrote:
>>>> On 10/04/2010 02:57 PM, Yinghai Lu wrote:
>>>>> Please check memblock related patches
>>>>>
>>>>> [PATCH 1/4] memblock: Fix big size with find_region()
>>>>> [PATCH -v5 2/4] x86, memblock: Fix crashkernel allocation
>>>>> [PATCH 3/4] x86, memblock: Remove __memblock_x86_find_in_range_size()
>>>>> [PATCH 4/4] x86, mm, memblock, 32bit: Make add_highpages honor early reserved ranges
>>>>>
>>>>> first one should get into core/memblock branch, and others should be in x86/mm/memeblock branch
>>>> BTW, the memblock changes prevent the kernel from booting under Xen; it
>>>> crashes while setting up the linear maps. I haven't worked out what's
>>>> failing yet, aside from bisecting it down to one of a9ce6bc151000 or
>>>> 72d7c3b33c9808 (they don't compile in isolation so I had to skip them,
>>>> but both are likely looking, but unfortunately large, complex and hard
>>>> to further subdivide).
>>>>
>>>> I'll look further into this, but just a heads-up for the upcoming merge
>>>> window.
>>>>
>>> please use
>>>
>>> git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-2.6-yinghai.git memblock
>>>
>>> to find which commit cause xen broken.
>>>
>>> two xen related patch are folded into first converting commit.
>> Note that ce883cfc65c51e24 doesn't compile:
>>
>> /home/jeremy/git/upstream/arch/x86/kernel/e820.c: In function
>> ‘find_e820_area_size’:
>> /home/jeremy/git/upstream/arch/x86/kernel/e820.c:764: error: expected
>> ‘;’ before ‘return’
>>
>> However, I can fix it with the obvious fix, and the Xen boot failure
>> bisects to this change.
>>
>> The specific crash is when constructing the initial pagetable, when Xen
>> tries to remap a newly allocated pagetable page read-only, and finds the
>> allocated page isn't mapped within the linear map. Since it is in the
>> middle of creating the linear map, I guess its quite possible that the
>> allocation order has changed, and it starts allocating pages which are
>> not yet mapped, whereas before it was allocating already-mapped ones.
> you can limit the allocation of pagetable page further ...
>
> xen doesn't honor max_pfn_mapped?

What do you mean? Xen sets max_pfn_mapped when it does the early
mapping of the kernel space, but I don't see how it relates to this
stage of mapping?

>> I'll see if I can confirm this hypothesis and see if I can work around
>> it (is poses some problems, because it means that when the pages later
>> become mapped, I need to make sure they get mapped RO).
> please check following debug patch, it will try find area bottom up...
>
> Subject: [PATCH] x86, memblock: Add x86 version of memblock_find_in_range()
>
> Generic version is going from high to low, and it seems it can not find
> right area compact enough.
>
> the x86 version will go from goal to limit and just like the way We used
> for early_res
>
> use ARCH_FIND_MEMBLOCK_AREA to select from them.

Thanks, that fixes the problem. I would ideally like to make the the
Xen code independent of the page allocation ordering, but it looks like
it will be very tricky since we effectively make use of the pagetable as
a way of storing one bit of information about each page before there's a
struct page in place.

So this patch looks good to me (but there's no need to make it a
separate config option).

Thanks,
J

> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
> arch/x86/Kconfig | 8 +++++++
> arch/x86/mm/memblock.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++
> mm/memblock.c | 2 -
> 3 files changed, 63 insertions(+), 1 deletion(-)
>
> Index: linux-2.6/arch/x86/mm/memblock.c
> ===================================================================
> --- linux-2.6.orig/arch/x86/mm/memblock.c
> +++ linux-2.6/arch/x86/mm/memblock.c
> @@ -346,3 +346,57 @@ u64 __init memblock_x86_hole_size(u64 st
>
> return end - start - ((u64)ram << PAGE_SHIFT);
> }
> +#ifdef CONFIG_ARCH_MEMBLOCK_FIND_AREA
> +
> +/* Check for already reserved areas */
> +static inline bool __init check_with_memblock_reserved(u64 *addrp, u64 size, u64 align)
> +{
> + u64 addr = *addrp;
> + bool changed = false;
> + struct memblock_region *r;
> +again:
> + for_each_memblock(reserved, r) {
> + if ((addr + size) > r->base && addr < (r->base + r->size)) {
> + addr = round_up(r->base + r->size, align);
> + changed = true;
> + goto again;
> + }
> + }
> +
> + if (changed)
> + *addrp = addr;
> +
> + return changed;
> +}
> +
> +/*
> + * Find a free area with specified alignment in a specific range from bottom up
> + */
> +u64 __init memblock_find_in_range(u64 start, u64 end, u64 size, u64 align)
> +{
> + struct memblock_region *r;
> +
> + for_each_memblock(memory, r) {
> + u64 ei_start = r->base;
> + u64 ei_last = ei_start + r->size;
> + u64 addr, last;
> +
> + addr = round_up(ei_start, align);
> + if (addr < start)
> + addr = round_up(start, align);
> + if (addr >= ei_last)
> + continue;
> + while (check_with_memblock_reserved(&addr, size, align) && addr+size <= ei_last)
> + ;
> + last = addr + size;
> + if (last > ei_last)
> + continue;
> + if (last > end)
> + continue;
> +
> + return addr;
> + }
> +
> + return MEMBLOCK_ERROR;
> +}
> +#endif
> Index: linux-2.6/arch/x86/Kconfig
> ===================================================================
> --- linux-2.6.orig/arch/x86/Kconfig
> +++ linux-2.6/arch/x86/Kconfig
> @@ -542,6 +542,14 @@ config PARAVIRT_DEBUG
> Enable to debug paravirt_ops internals. Specifically, BUG if
> a paravirt_op is missing when it is called.
>
> +config ARCH_MEMBLOCK_FIND_AREA
> + default y
> + bool "Use x86 own memblock_find_in_range()"
> + ---help---
> + Use memblock_find_in_range() version instead of generic version, it get free
> + area up from low.
> + Generic one try to get free area down from limit.
> +
> config NO_BOOTMEM
> def_bool y
>
> Index: linux-2.6/mm/memblock.c
> ===================================================================
> --- linux-2.6.orig/mm/memblock.c
> +++ linux-2.6/mm/memblock.c
> @@ -170,7 +170,7 @@ static phys_addr_t __init_memblock membl
> /*
> * Find a free area with specified alignment in a specific range.
> */
> -u64 __init_memblock memblock_find_in_range(u64 start, u64 end, u64 size, u64 align)
> +u64 __init_memblock __weak memblock_find_in_range(u64 start, u64 end, u64 size, u64 align)
> {
> return memblock_find_base(size, align, start, end);
> }
>

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2010-10-13 18:33    [W:0.095 / U:0.160 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site