From patchwork Tue Oct 21 17:01:21 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grygorii Strashko X-Patchwork-Id: 5126481 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 243919F30B for ; Tue, 21 Oct 2014 17:04:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1AC1E201ED for ; Tue, 21 Oct 2014 17:04:09 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 19FF320176 for ; Tue, 21 Oct 2014 17:04:08 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Xgcoy-0002JY-5b; Tue, 21 Oct 2014 17:02:08 +0000 Received: from comal.ext.ti.com ([198.47.26.152]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Xgcov-0002Cx-8J for linux-arm-kernel@lists.infradead.org; Tue, 21 Oct 2014 17:02:06 +0000 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by comal.ext.ti.com (8.13.7/8.13.7) with ESMTP id s9LH1O7n013942; Tue, 21 Oct 2014 12:01:24 -0500 Received: from DFLE72.ent.ti.com (dfle72.ent.ti.com [128.247.5.109]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id s9LH1OI6008950; Tue, 21 Oct 2014 12:01:24 -0500 Received: from dlep33.itg.ti.com (157.170.170.75) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.3.174.1; Tue, 21 Oct 2014 12:01:23 -0500 Received: from [192.168.192.190] (ileax41-snat.itg.ti.com [10.172.224.153]) by dlep33.itg.ti.com (8.14.3/8.13.8) with ESMTP id s9LH1MLm005654; Tue, 21 Oct 2014 12:01:22 -0500 Message-ID: <54469161.50709@ti.com> Date: Tue, 21 Oct 2014 20:01:21 +0300 From: Grygorii Strashko User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: Laura Abbott , Russell King - ARM Linux Subject: Re: ARM: issue with memory reservation from DT References: <543EAC5A.6050209@ti.com> <20141015175025.GJ27405@n2100.arm.linux.org.uk> <54400123.7040806@ti.com> <5440DD02.9020103@codeaurora.org> <5440EDC6.70300@ti.com> <544149CF.5080809@codeaurora.org> <54457534.5050607@codeaurora.org> In-Reply-To: <54457534.5050607@codeaurora.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141021_100205_386556_29881F65 X-CRM114-Status: GOOD ( 24.51 ) X-Spam-Score: -6.5 (------) Cc: Grant Likely , Rob Herring , linux-arm , ssantosh@kernel.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-3.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hi Laura, On 10/20/2014 11:48 PM, Laura Abbott wrote: > On 10/17/2014 9:54 AM, Laura Abbott wrote: >> On 10/17/2014 3:21 AM, Grygorii Strashko wrote: >>> Hi Laura, >>> >>> As I mentioned in first e-mail I've 1G Mem node initially: >>> reg = <0x8 0x00000000 0x0 0x40000000>; >>> >>> and have memory reservation of 512M in the upper part of memory: >>> reserved-memory { >>> reg = <0x8 0x20000000 0x0 0x20000000>; >>> >>> then in sanity_check_meminfo() initial mem configuration calculated as >>> following: >>> >>> [ 0.000000] ======= memblock_limit=0x000000082f800000 >>> arm_lowmem_limit=0x000000082f800000 vmalloc_limit=ef800000 >>> high_memory=0x000000082f800000 >>> and memblock.current_limit == arm_lowmem_limit=0x000000082f800000 >>> >>> then in arm_memblock_init()->early_init_fdt_scan_reserved_mem() 512M >>> of memory removed >>> (not reserved!, because "no-map;" is defined). >>> >>> After that Kernel will have only 512M of accessible memory >>> memory[0x0] [0x00000800000000-0x0000081fffffff] >>> >>> I've checked of_reserved_mem.c and saw no issues there :( >>> >> >> Yes, I suspect the issue is not with of_reserved_mem.c and instead with >> sanity_check_meminfo in mmu.c . I'm still traveling so I'll probably >> take a look on Monday unless I find some time sooner. >> > > I was able to reproduce a crash on my device by removing all highmem > as well. It looks like the logic assumes that lowmem limit will only > ever increase and not need to decrease. This seems like a limitation > of running with CONFIG_HIGHMEM on a system which doesn't actually > need highmem. This seems to have been the case even before the meminfo > removal as well. The following worked for me: > > diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c > index 9f98cec..6696016 100644 > --- a/arch/arm/mm/mmu.c > +++ b/arch/arm/mm/mmu.c > @@ -1140,6 +1140,9 @@ void __init sanity_check_meminfo(void) > } > } > > + if (arm_lowmem_limit > memblock_end_of_DRAM()) > + arm_lowmem_limit = memblock_end_of_DRAM(); > + > high_memory = __va(arm_lowmem_limit - 1) + 1; > > /* > > > I'll turn this into an official patch for review if it fixes your > problem as well. thanks you for your comments. No. It doesn't help :( because you've fixed sanity_check_meminfo() while I've the case when memory is removed (stolen) from arm_memblock_init() which, in turn, called after sanity_check_meminfo() - see setup_arch(). Below is last things I've found - It seems related to memZones configuration and in my case CONFIG_ZONE_DMA=y: == bad case: [ 0.000000] ======= memblock_limit=0x000000082f800000 arm_lowmem_limit=0x000000082f800000 vmalloc_limit=ef800000 high_memory=0x000000082f800000 [ 0.000000] ======= min_low_pfn=800000 max_low_pfn=82F800 max_pfn=820000 [ 0.000000] ======= zone0 size2F800 holeF800 [ 0.000000] ======= zone1 size0 hole0 [ 0.000000] ======= zone2 sizeFFFF0800 holeFFFF0800 [ 0.000000] ======= zone3 size0 hole0 == good case - can boot (with below fix applied): [ 0.000000] ======= memblock_limit=0x000000082f800000 arm_lowmem_limit=0x000000082f800000 vmalloc_limit=ef800000 high_memory=0x000000082f800000 [ 0.000000] ======= min_low_pfn=800000 max_low_pfn=820000 max_pfn=820000 [ 0.000000] ======= zone0 size20000 hole0 [ 0.000000] ======= zone1 size0 hole0 [ 0.000000] ======= zone2 size0 hole0 [ 0.000000] ======= zone3 size0 hole0 Also I've found, that before commit "ARM: 8025/1: Get rid of meminfo" the 'max_low_pfn' was calculated as below: - struct meminfo *mi = &meminfo; - int i; - - /* This assumes the meminfo array is properly sorted */ - *min = bank_pfn_start(&mi->bank[0]); - for_each_bank (i, mi) - if (mi->bank[i].highmem) - break; - *max_low = bank_pfn_end(&mi->bank[i - 1]); So, I've tried to roll back above functionality and I was able to boot with below change: In the above code I've tried to take into account, that at the moment when find_limits() is called memory structure can have following configurations (may be I've listed not all of them): 1) mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm ^ 2) mmmmmmmmmmmmmmmmmmmmmmmmmmmmhhhh ^ 3) mmmmmmmmmmmmmmmmhhhhhhhhhhhhhhhh (my case) ^ 4) mmmmhhhhmmmmmmmmmmmmmmmmmmmmmmmm ^ 5) mmmmhhhhmmmmmmmmmmmmmmmmmhhhhmmm ^ 6) mmmmmmmmmmmmmmmmhhhhhhhhmmmmmmmm ^ m - available memory h - hole ^ - position of arm_lowmem_limit/memblock.current_limit & high_memory Also, Might be we can get rid of arm_lowmem_limit and replace it with memblock_get_current_limit? Could we? Unfortunately, this issue has low priority for me and I'm not sure that I'll be able to continue working on :( Best regards, -grygorii --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -137,7 +137,19 @@ void show_mem(unsigned int filter) static void __init find_limits(unsigned long *min, unsigned long *max_low, unsigned long *max_high) { - *max_low = PFN_DOWN(memblock_get_current_limit()); + struct memblock_region *reg; + + for_each_memblock(memory, reg) { + if (reg->base >= memblock_get_current_limit()) + break; + + if ((reg->base + reg->size) > memblock_get_current_limit()) { + *max_low = PFN_DOWN(memblock_get_current_limit()); + break; + } + + *max_low = PFN_DOWN(reg->base + reg->size); + } *min = PFN_UP(memblock_start_of_DRAM()); *max_high = PFN_DOWN(memblock_end_of_DRAM()); }