Received: by 10.213.65.68 with SMTP id h4csp1928758imn; Sun, 1 Apr 2018 19:33:57 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/qMFFacs0QgXNCFctpv+ZsEcODiRCkIO3LKA8/hdCl9UEp8nI2OUspPCoebnV1TUBZdpRG X-Received: by 2002:a17:902:7888:: with SMTP id q8-v6mr8101655pll.108.1522636437249; Sun, 01 Apr 2018 19:33:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522636437; cv=none; d=google.com; s=arc-20160816; b=IErieLFdd4dKDc+Ah+kO6+EV5fo6S3GDDgssfedaP4pOBL9jvEMvmtWRoHTbQEjrVx Js25kxxOXUfhBJSQKCJDA4RRIv1ldqc+zoKZAapMVOpZiUMA2TYgECQUaSbx3+yHpNIV VxnEKrCT7zAywZBts11wDzTnq1a3I38LPYyj6FGKd2d62gh/XH7l7IdeOd0kCGUimdYl IkAL79dtJtxIvWqgthd4I6Sl9F74Gp98xEl7muYCFV4sLd5nXF5RPQwqgeR5JhU/uXeg 7fh/nT9Ql3hrzvpVzb2ZIpVGBgwoZfK6SNg7iUq+GzpCt/gF77Wq+QByYwQjIL9flA/Z 2Zaw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=nfnmpH36ya8Gy6VB0XveTx1x0oDqOdqdNrB069YfGZk=; b=cCKHXW5cwjBVatDgH9RF3+qeI50w0N+bKE3ZSMdG9LrpPAgJQDmukUejdH4jRdLTGi qKtmjzXcvQjigad+D5emFiTmMxp/l2FskHWM1qqhM91km+zf1Z0Rnh4teFH0AJkKRnww PuXIuCpeRiQ4kn5OadkjBuniUtY19VCcGngMcQhE3/dki0DK2C5OVQE6xEmc9bS6FtJS IFzap93umJlXZJTbzURQNGzl5oo0CLtxXvytKTrOESmjAuWZPwsXWa3+wk6/MspMhVKH Jx7xHQBffZy7DE+gMf9+hiQD4FTEiOQJRkav9Lr+NctWUOw0o78fyML/kXsbIPP60dC2 /3RQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=pBfEmbl7; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j5si9165442pgn.340.2018.04.01.19.33.43; Sun, 01 Apr 2018 19:33:57 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=pBfEmbl7; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754139AbeDBCc0 (ORCPT + 99 others); Sun, 1 Apr 2018 22:32:26 -0400 Received: from mail-pl0-f66.google.com ([209.85.160.66]:38184 "EHLO mail-pl0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753989AbeDBCcY (ORCPT ); Sun, 1 Apr 2018 22:32:24 -0400 Received: by mail-pl0-f66.google.com with SMTP id m22-v6so3290334pls.5 for ; Sun, 01 Apr 2018 19:32:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nfnmpH36ya8Gy6VB0XveTx1x0oDqOdqdNrB069YfGZk=; b=pBfEmbl7mZJw0fmEunrmC8x2Zxqlhh9eAtzAn9uh4SHqYwQ5dxchSJH02cyesRZYzA saJMKJLvU16W5Kv1qkVERpe4gKAtmlb2JLPZqPkmj6lOTr860DarfnbEdWx2ygbsAQWe ah0un21jehGVtaTyfk1OxYZGm9YCYXBiaTKp2vl0ZLIQYCCH4KUADXiPM6Gv7qOXGwhj nf6RcraiuEgFl1IUVsdRcZQJCs/p+jPRSiXd+HdXvFmamzIzaX7mK/yCnPlkrIiEpaKo UTj77t8H0jub2JSww5r6GjfMT7oSmamlNm4a+FB5cPsmlYbG3qFmyD6yYJ7RsHOGmaYn AaCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nfnmpH36ya8Gy6VB0XveTx1x0oDqOdqdNrB069YfGZk=; b=VitexK3aUQ1ba0Ydi4WSmxiKOrwvsr2rO264Hp9HAXz1QBEgG0XyJsW8SvSiv4Uhb0 9BOR+3AUJV2fp1qShkXN/hRXZjavusNgqCjjxAlax5y84QA+3QAzyeer8THyqwgCNQPE UZBtiR2TUnzmwaTGBvfvDOyI7pZh7k0TE1Z1t4CLrFbmlGS45q6YKlRI/NgXSfYkk9bp Dk7uoB8B692qGKu+paiBMITb+1PSzBToohWYfrJfrYxv+kSz7MDhjqYg5C5970N7hgc4 4Ki+aiRapCxA280poJiJNlF4uDry/62CwzL9MAMJmF9qi1S2sNRZoIoDreTAaKEFs47S ZTIg== X-Gm-Message-State: AElRT7HMXcX4mpovd7Ev17/WbTSL/GRzgDatZKTXyl/epRzKT8otD51F oxI/Vy1eWItnq7xVzQa06mE= X-Received: by 2002:a17:902:102a:: with SMTP id b39-v6mr8161699pla.112.1522636343980; Sun, 01 Apr 2018 19:32:23 -0700 (PDT) Received: from localhost.localdomain ([38.106.11.25]) by smtp.gmail.com with ESMTPSA id t20sm25934371pfh.182.2018.04.01.19.32.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 01 Apr 2018 19:32:23 -0700 (PDT) From: Jia He To: Russell King , Catalin Marinas , Will Deacon , Mark Rutland , Ard Biesheuvel , Andrew Morton , Michal Hocko Cc: Wei Yang , Kees Cook , Laura Abbott , Vladimir Murzin , Philip Derrin , Grygorii Strashko , AKASHI Takahiro , James Morse , Steve Capper , Pavel Tatashin , Gioh Kim , Vlastimil Babka , Mel Gorman , Johannes Weiner , Kemi Wang , Petr Tesarik , YASUAKI ISHIMATSU , Andrey Ryabinin , Nikolay Borisov , Daniel Jordan , Daniel Vacek , Eugeniu Rosca , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Jia He , Jia He Subject: [PATCH v5 1/5] mm: page_alloc: remain memblock_next_valid_pfn() on arm and arm64 Date: Sun, 1 Apr 2018 19:30:32 -0700 Message-Id: <1522636236-12625-2-git-send-email-hejianet@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1522636236-12625-1-git-send-email-hejianet@gmail.com> References: <1522636236-12625-1-git-send-email-hejianet@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit b92df1de5d28 ("mm: page_alloc: skip over regions of invalid pfns where possible") optimized the loop in memmap_init_zone(). But it causes possible panic bug. So Daniel Vacek reverted it later. But as suggested by Daniel Vacek, it is fine to using memblock to skip gaps and finding next valid frame with CONFIG_HAVE_ARCH_PFN_VALID. On arm and arm64, memblock is used by default. But generic version of pfn_valid() is based on mem sections and memblock_next_valid_pfn() does not always return the next valid one but skips more resulting in some valid frames to be skipped (as if they were invalid). And that's why kernel was eventually crashing on some !arm machines. And as verified by Eugeniu Rosca, arm can benifit from commit b92df1de5d28. So remain the memblock_next_valid_pfn on arm{,64} and move the related codes to arm64 arch directory. Suggested-by: Daniel Vacek Signed-off-by: Jia He --- arch/arm/include/asm/page.h | 2 ++ arch/arm/mm/init.c | 31 ++++++++++++++++++++++++++++++- arch/arm64/include/asm/page.h | 2 ++ arch/arm64/mm/init.c | 31 ++++++++++++++++++++++++++++++- include/linux/mmzone.h | 1 + mm/page_alloc.c | 4 +++- 6 files changed, 68 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h index 4355f0e..489875c 100644 --- a/arch/arm/include/asm/page.h +++ b/arch/arm/include/asm/page.h @@ -158,6 +158,8 @@ typedef struct page *pgtable_t; #ifdef CONFIG_HAVE_ARCH_PFN_VALID extern int pfn_valid(unsigned long); +extern unsigned long memblock_next_valid_pfn(unsigned long pfn); +#define skip_to_last_invalid_pfn(pfn) (memblock_next_valid_pfn(pfn) - 1) #endif #include diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index a1f11a7..0fb85ca 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -198,7 +198,36 @@ int pfn_valid(unsigned long pfn) return memblock_is_map_memory(__pfn_to_phys(pfn)); } EXPORT_SYMBOL(pfn_valid); -#endif + +/* HAVE_MEMBLOCK is always enabled on arm */ +unsigned long __init_memblock memblock_next_valid_pfn(unsigned long pfn) +{ + struct memblock_type *type = &memblock.memory; + unsigned int right = type->cnt; + unsigned int mid, left = 0; + phys_addr_t addr = PFN_PHYS(++pfn); + + do { + mid = (right + left) / 2; + + if (addr < type->regions[mid].base) + right = mid; + else if (addr >= (type->regions[mid].base + + type->regions[mid].size)) + left = mid + 1; + else { + /* addr is within the region, so pfn is valid */ + return pfn; + } + } while (left < right); + + if (right == type->cnt) + return -1UL; + else + return PHYS_PFN(type->regions[right].base); +} +EXPORT_SYMBOL(memblock_next_valid_pfn); +#endif /*CONFIG_HAVE_ARCH_PFN_VALID*/ #ifndef CONFIG_SPARSEMEM static void __init arm_memory_present(void) diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h index 60d02c8..e57d3f2 100644 --- a/arch/arm64/include/asm/page.h +++ b/arch/arm64/include/asm/page.h @@ -39,6 +39,8 @@ typedef struct page *pgtable_t; #ifdef CONFIG_HAVE_ARCH_PFN_VALID extern int pfn_valid(unsigned long); +extern unsigned long memblock_next_valid_pfn(unsigned long pfn); +#define skip_to_last_invalid_pfn(pfn) (memblock_next_valid_pfn(pfn) - 1) #endif #include diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 00e7b90..13e43ff 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -290,7 +290,36 @@ int pfn_valid(unsigned long pfn) return memblock_is_map_memory(pfn << PAGE_SHIFT); } EXPORT_SYMBOL(pfn_valid); -#endif + +/* HAVE_MEMBLOCK is always enabled on arm64 */ +unsigned long __init_memblock memblock_next_valid_pfn(unsigned long pfn) +{ + struct memblock_type *type = &memblock.memory; + unsigned int right = type->cnt; + unsigned int mid, left = 0; + phys_addr_t addr = PFN_PHYS(++pfn); + + do { + mid = (right + left) / 2; + + if (addr < type->regions[mid].base) + right = mid; + else if (addr >= (type->regions[mid].base + + type->regions[mid].size)) + left = mid + 1; + else { + /* addr is within the region, so pfn is valid */ + return pfn; + } + } while (left < right); + + if (right == type->cnt) + return -1UL; + else + return PHYS_PFN(type->regions[right].base); +} +EXPORT_SYMBOL(memblock_next_valid_pfn); +#endif /*CONFIG_HAVE_ARCH_PFN_VALID*/ #ifndef CONFIG_SPARSEMEM static void __init arm64_memory_present(void) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index d797716..f9c0c46 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -1245,6 +1245,7 @@ static inline int pfn_valid(unsigned long pfn) return 0; return valid_section(__nr_to_section(pfn_to_section_nr(pfn))); } +#define skip_to_last_invalid_pfn(pfn) (pfn) #endif static inline int pfn_present(unsigned long pfn) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index c19f5ac..30f7d76 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5483,8 +5483,10 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, if (context != MEMMAP_EARLY) goto not_early; - if (!early_pfn_valid(pfn)) + if (!early_pfn_valid(pfn)) { + pfn = skip_to_last_invalid_pfn(pfn); continue; + } if (!early_pfn_in_nid(pfn, nid)) continue; if (!update_defer_init(pgdat, pfn, end_pfn, &nr_initialised)) -- 2.7.4