From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.0 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7EB76C4360F for ; Wed, 3 Apr 2019 02:55:04 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 04AF620830 for ; Wed, 3 Apr 2019 02:55:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="cZ8ko2IH" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 04AF620830 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=rpcEYC4f1wr/YLHcrCxvchdUeGdQA/n0/aZZ2kFMGEk=; b=cZ8ko2IH8tx5tT hpMQKDbrVBZ1RUf2U0Brh/1kgRCoWr5Auvh2+N1ikqhq7XsHml5F9GzmwNUlGbkoEcPF8xjbVKwub imDfT8Pif3g1R1yhIjbyaZQv9Rqw4jY/SgTwQBNcHj3sFBQYaVM+HB0UiofAUvJDtc8ShO3Ecm98n dF6gVBtQcCoBVO2IFhQqwIA/4XVS2KtrGnRksDgU36XypQ0GCWxtLdVH5k8RV9TecMl7z7Yck1WrN Ql3A4fjZmA3xBIDv3moXOvsz0rG4CGWZuMSBcH4lE2DWrPH34GSvQYdd8sGS1AOZ8XnmWTeg28nem jvJotS/5uL3axDAWXH4A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBW3G-00023B-Cg; Wed, 03 Apr 2019 02:54:58 +0000 Received: from szxga05-in.huawei.com ([45.249.212.191] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hBW32-0001iQ-UJ; Wed, 03 Apr 2019 02:54:49 +0000 Received: from DGGEMS408-HUB.china.huawei.com (unknown [10.3.19.208]) by Forcepoint Email with ESMTP id 3DFD7EFA4B81E6ED553E; Wed, 3 Apr 2019 10:54:42 +0800 (CST) Received: from localhost.localdomain.localdomain (10.175.113.25) by DGGEMS408-HUB.china.huawei.com (10.3.19.208) with Microsoft SMTP Server id 14.3.408.0; Wed, 3 Apr 2019 10:54:34 +0800 From: Chen Zhou To: , , , , , Subject: [PATCH 2/3] arm64: kdump: support more than one crash kernel regions Date: Wed, 3 Apr 2019 11:05:45 +0800 Message-ID: <20190403030546.23718-3-chenzhou10@huawei.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190403030546.23718-1-chenzhou10@huawei.com> References: <20190403030546.23718-1-chenzhou10@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.113.25] X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190402_195445_373902_B728F221 X-CRM114-Status: GOOD ( 14.24 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: wangkefeng.wang@huawei.com, Chen Zhou , kexec@lists.infradead.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-arm-kernel@lists.infradead.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+infradead-linux-arm-kernel=archiver.kernel.org@lists.infradead.org After commit (arm64: kdump: support reserving crashkernel above 4G), there may be two crash kernel regions, one is below 4G, the other is above 4G. Crash dump kernel reads more than one crash kernel regions via a dtb property under node /chosen, linux,usable-memory-range = Signed-off-by: Chen Zhou --- arch/arm64/mm/init.c | 37 +++++++++++++++++++++++++------------ include/linux/memblock.h | 1 + mm/memblock.c | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index ceb2a25..769c77a 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -64,6 +64,8 @@ EXPORT_SYMBOL(memstart_addr); phys_addr_t arm64_dma_phys_limit __ro_after_init; #ifdef CONFIG_KEXEC_CORE +# define CRASH_MAX_USABLE_RANGES 2 + static int __init reserve_crashkernel_low(void) { unsigned long long base, low_base = 0, low_size = 0; @@ -346,8 +348,8 @@ static int __init early_init_dt_scan_usablemem(unsigned long node, const char *uname, int depth, void *data) { struct memblock_region *usablemem = data; - const __be32 *reg; - int len; + const __be32 *reg, *endp; + int len, nr = 0; if (depth != 1 || strcmp(uname, "chosen") != 0) return 0; @@ -356,22 +358,33 @@ static int __init early_init_dt_scan_usablemem(unsigned long node, if (!reg || (len < (dt_root_addr_cells + dt_root_size_cells))) return 1; - usablemem->base = dt_mem_next_cell(dt_root_addr_cells, ®); - usablemem->size = dt_mem_next_cell(dt_root_size_cells, ®); + endp = reg + (len / sizeof(__be32)); + while ((endp - reg) >= (dt_root_addr_cells + dt_root_size_cells)) { + usablemem[nr].base = dt_mem_next_cell(dt_root_addr_cells, ®); + usablemem[nr].size = dt_mem_next_cell(dt_root_size_cells, ®); + + if (++nr >= CRASH_MAX_USABLE_RANGES) + break; + } return 1; } static void __init fdt_enforce_memory_region(void) { - struct memblock_region reg = { - .size = 0, - }; - - of_scan_flat_dt(early_init_dt_scan_usablemem, ®); - - if (reg.size) - memblock_cap_memory_range(reg.base, reg.size); + int i, cnt = 0; + struct memblock_region regs[CRASH_MAX_USABLE_RANGES]; + + memset(regs, 0, sizeof(regs)); + of_scan_flat_dt(early_init_dt_scan_usablemem, regs); + + for (i = 0; i < CRASH_MAX_USABLE_RANGES; i++) + if (regs[i].size) + cnt++; + else + break; + if (cnt) + memblock_cap_memory_ranges(regs, cnt); } void __init arm64_memblock_init(void) diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 47e3c06..aeade34 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -446,6 +446,7 @@ phys_addr_t memblock_start_of_DRAM(void); phys_addr_t memblock_end_of_DRAM(void); void memblock_enforce_memory_limit(phys_addr_t memory_limit); void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size); +void memblock_cap_memory_ranges(struct memblock_region *regs, int cnt); void memblock_mem_limit_remove_map(phys_addr_t limit); bool memblock_is_memory(phys_addr_t addr); bool memblock_is_map_memory(phys_addr_t addr); diff --git a/mm/memblock.c b/mm/memblock.c index 28fa8926..1a7f4ee7c 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -1697,6 +1697,46 @@ void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size) base + size, PHYS_ADDR_MAX); } +void __init memblock_cap_memory_ranges(struct memblock_region *regs, int cnt) +{ + int start_rgn[INIT_MEMBLOCK_REGIONS], end_rgn[INIT_MEMBLOCK_REGIONS]; + int i, j, ret, nr = 0; + + for (i = 0; i < cnt; i++) { + ret = memblock_isolate_range(&memblock.memory, regs[i].base, + regs[i].size, &start_rgn[i], &end_rgn[i]); + if (ret) + break; + nr++; + } + if (!nr) + return; + + /* remove all the MAP regions */ + for (i = memblock.memory.cnt - 1; i >= end_rgn[nr - 1]; i--) + if (!memblock_is_nomap(&memblock.memory.regions[i])) + memblock_remove_region(&memblock.memory, i); + + for (i = nr - 1; i > 0; i--) + for (j = start_rgn[i] - 1; j >= end_rgn[i - 1]; j--) + if (!memblock_is_nomap(&memblock.memory.regions[j])) + memblock_remove_region(&memblock.memory, j); + + for (i = start_rgn[0] - 1; i >= 0; i--) + if (!memblock_is_nomap(&memblock.memory.regions[i])) + memblock_remove_region(&memblock.memory, i); + + /* truncate the reserved regions */ + memblock_remove_range(&memblock.reserved, 0, regs[0].base); + + for (i = nr - 1; i > 0; i--) + memblock_remove_range(&memblock.reserved, + regs[i].base, regs[i - 1].base + regs[i - 1].size); + + memblock_remove_range(&memblock.reserved, + regs[nr - 1].base + regs[nr - 1].size, PHYS_ADDR_MAX); +} + void __init memblock_mem_limit_remove_map(phys_addr_t limit) { phys_addr_t max_addr; -- 2.7.4 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel