From patchwork Mon Mar 30 06:51:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anshuman Khandual X-Patchwork-Id: 11464713 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C683692C for ; Mon, 30 Mar 2020 06:52:02 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 86B5B2073B for ; Mon, 30 Mar 2020 06:52:02 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 86B5B2073B Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id B64276B000C; Mon, 30 Mar 2020 02:52:01 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id B15256B0032; Mon, 30 Mar 2020 02:52:01 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id A51CE6B0037; Mon, 30 Mar 2020 02:52:01 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0178.hostedemail.com [216.40.44.178]) by kanga.kvack.org (Postfix) with ESMTP id 8A42F6B000C for ; Mon, 30 Mar 2020 02:52:01 -0400 (EDT) Received: from smtpin28.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay02.hostedemail.com (Postfix) with ESMTP id 594B940F4 for ; Mon, 30 Mar 2020 06:52:01 +0000 (UTC) X-FDA: 76651108842.28.rod03_1196880747a1f X-Spam-Summary: 2,0,0,5b656cb48dc84ccb,d41d8cd98f00b204,anshuman.khandual@arm.com,,RULES_HIT:2:41:69:334:355:368:369:379:541:800:960:966:968:973:988:989:1260:1261:1345:1431:1437:1535:1605:1730:1747:1777:1792:1963:1981:2194:2196:2198:2199:2200:2201:2393:2553:2559:2562:2731:3138:3139:3140:3141:3142:3865:3866:3867:3868:3870:3871:3874:4049:4119:4321:4385:4605:5007:6261:8634:8957:10004:11026:11232:11473:11658:11914:12043:12291:12296:12297:12438:12555:12683:12691:12737:12895:12986:13221:13229:13846:14096:21080:21451:21627:21990:30012:30045:30054:30056:30064:30089:30090,0,RBL:217.140.110.172:@arm.com:.lbl8.mailshell.net-62.14.0.100 64.201.201.201,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:26,LUA_SUMMARY:none X-HE-Tag: rod03_1196880747a1f X-Filterd-Recvd-Size: 8094 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by imf47.hostedemail.com (Postfix) with ESMTP for ; Mon, 30 Mar 2020 06:52:00 +0000 (UTC) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C581A1FB; Sun, 29 Mar 2020 23:51:59 -0700 (PDT) Received: from p8cg001049571a15.arm.com (unknown [10.163.1.70]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 8FA673F71E; Sun, 29 Mar 2020 23:56:00 -0700 (PDT) From: Anshuman Khandual To: linux-mm@kvack.org Cc: Anshuman Khandual , Andrew Morton , David Hildenbrand , Michal Hocko , Dan Williams , Pavel Tatashin , linux-kernel@vger.kernel.org Subject: [RFC] mm/page_alloc: Enumerate bad page reasons Date: Mon, 30 Mar 2020 12:21:37 +0530 Message-Id: <1585551097-27283-1-git-send-email-anshuman.khandual@arm.com> X-Mailer: git-send-email 2.7.4 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Enumerate all existing bad page reasons which can be used in bad_page() for reporting via __dump_page(). Unfortunately __dump_page() cannot be changed. __dump_page() is called from dump_page() that accepts a raw string and is also an exported symbol that is currently being used from various generic memory functions and other drivers. This reduces code duplication while reporting bad pages. Cc: Andrew Morton Cc: David Hildenbrand Cc: Michal Hocko Cc: Dan Williams Cc: Pavel Tatashin Cc: linux-mm@kvack.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Anshuman Khandual --- Boot tested on arm64 and x86 platforms (next-20200327) but has been built tested on many other platforms. include/linux/memory.h | 36 ++++++++++++++++++++++++++++++++++++ mm/page_alloc.c | 40 ++++++++++++++++++++-------------------- 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/include/linux/memory.h b/include/linux/memory.h index 7914b0dbd4bb..b2fb90fda537 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -82,6 +82,42 @@ struct memory_notify { struct notifier_block; struct mem_section; +/* + * Bad page reasons + */ +enum page_bad_reason { + PAGE_BAD_NONZERO_MAPCOUNT, + PAGE_BAD_NONZERO_REFCOUNT, + PAGE_BAD_NONNULL_MAPPING, + PAGE_BAD_FREE_FLAGS, + PAGE_BAD_PREP_FLAGS, + PAGE_BAD_CGROUP_CHARGED, + PAGE_BAD_HWPOISON, + PAGE_BAD_TAIL_CORRUPTED, + PAGE_BAD_TAIL_NOT_SET, + PAGE_BAD_COMPOUND_HEAD, + PAGE_BAD_COMPOUND_MAPCOUNT, +}; + +static const char *const page_bad_names[] = { + [PAGE_BAD_NONZERO_MAPCOUNT] = "non-zero mapcout", + [PAGE_BAD_NONZERO_REFCOUNT] = "non-zero _refcount", + [PAGE_BAD_NONNULL_MAPPING] = "non-NULL mapping", + [PAGE_BAD_FREE_FLAGS] = "PAGE_FLAGS_CHECK_AT_FREE flag(s) set", + [PAGE_BAD_PREP_FLAGS] = "PAGE_FLAGS_CHECK_AT_PREP flag(s) set", + [PAGE_BAD_CGROUP_CHARGED] = "page still charged to cgroup", + [PAGE_BAD_HWPOISON] = "HWPoisoned (hardware-corrupted)", + [PAGE_BAD_TAIL_CORRUPTED] = "corrupted mapping in tail page", + [PAGE_BAD_TAIL_NOT_SET] = "PageTail not set", + [PAGE_BAD_COMPOUND_HEAD] = "compound_head not consistent", + [PAGE_BAD_COMPOUND_MAPCOUNT] = "non-zero compound_mapcount", +}; + +static inline const char *get_page_bad(int reason) +{ + return page_bad_names[reason]; +} + /* * Priorities for the hotplug memory callback routines (stored in decreasing * order in the callback chain) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ca1453204e66..0f05da0fdc9a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -68,6 +68,7 @@ #include #include #include +#include #include #include @@ -609,7 +610,7 @@ static inline int __maybe_unused bad_range(struct zone *zone, struct page *page) } #endif -static void bad_page(struct page *page, const char *reason, +static void bad_page(struct page *page, int reason, unsigned long bad_flags) { static unsigned long resume; @@ -638,7 +639,7 @@ static void bad_page(struct page *page, const char *reason, pr_alert("BUG: Bad page state in process %s pfn:%05lx\n", current->comm, page_to_pfn(page)); - __dump_page(page, reason); + __dump_page(page, get_page_bad(reason)); bad_flags &= page->flags; if (bad_flags) pr_alert("bad because of flags: %#lx(%pGp)\n", @@ -1079,25 +1080,24 @@ static inline bool page_expected_state(struct page *page, static void free_pages_check_bad(struct page *page) { - const char *bad_reason; + int bad_reason; unsigned long bad_flags; - bad_reason = NULL; bad_flags = 0; if (unlikely(atomic_read(&page->_mapcount) != -1)) - bad_reason = "nonzero mapcount"; + bad_reason = PAGE_BAD_NONZERO_MAPCOUNT; if (unlikely(page->mapping != NULL)) - bad_reason = "non-NULL mapping"; + bad_reason = PAGE_BAD_NONNULL_MAPPING; if (unlikely(page_ref_count(page) != 0)) - bad_reason = "nonzero _refcount"; + bad_reason = PAGE_BAD_NONZERO_REFCOUNT; if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_FREE)) { - bad_reason = "PAGE_FLAGS_CHECK_AT_FREE flag(s) set"; + bad_reason = PAGE_BAD_FREE_FLAGS; bad_flags = PAGE_FLAGS_CHECK_AT_FREE; } #ifdef CONFIG_MEMCG if (unlikely(page->mem_cgroup)) - bad_reason = "page still charged to cgroup"; + bad_reason = PAGE_BAD_CGROUP_CHARGED; #endif bad_page(page, bad_reason, bad_flags); } @@ -1130,7 +1130,7 @@ static int free_tail_pages_check(struct page *head_page, struct page *page) case 1: /* the first tail page: ->mapping may be compound_mapcount() */ if (unlikely(compound_mapcount(page))) { - bad_page(page, "nonzero compound_mapcount", 0); + bad_page(page, PAGE_BAD_COMPOUND_MAPCOUNT, 0); goto out; } break; @@ -1142,17 +1142,17 @@ static int free_tail_pages_check(struct page *head_page, struct page *page) break; default: if (page->mapping != TAIL_MAPPING) { - bad_page(page, "corrupted mapping in tail page", 0); + bad_page(page, PAGE_BAD_TAIL_CORRUPTED, 0); goto out; } break; } if (unlikely(!PageTail(page))) { - bad_page(page, "PageTail not set", 0); + bad_page(page, PAGE_BAD_TAIL_NOT_SET, 0); goto out; } if (unlikely(compound_head(page) != head_page)) { - bad_page(page, "compound_head not consistent", 0); + bad_page(page, PAGE_BAD_COMPOUND_HEAD, 0); goto out; } ret = 0; @@ -2110,29 +2110,29 @@ static inline void expand(struct zone *zone, struct page *page, static void check_new_page_bad(struct page *page) { - const char *bad_reason = NULL; + int bad_reason; unsigned long bad_flags = 0; if (unlikely(atomic_read(&page->_mapcount) != -1)) - bad_reason = "nonzero mapcount"; + bad_reason = PAGE_BAD_NONZERO_MAPCOUNT; if (unlikely(page->mapping != NULL)) - bad_reason = "non-NULL mapping"; + bad_reason = PAGE_BAD_NONNULL_MAPPING; if (unlikely(page_ref_count(page) != 0)) - bad_reason = "nonzero _refcount"; + bad_reason = PAGE_BAD_NONZERO_REFCOUNT; if (unlikely(page->flags & __PG_HWPOISON)) { - bad_reason = "HWPoisoned (hardware-corrupted)"; + bad_reason = PAGE_BAD_HWPOISON; bad_flags = __PG_HWPOISON; /* Don't complain about hwpoisoned pages */ page_mapcount_reset(page); /* remove PageBuddy */ return; } if (unlikely(page->flags & PAGE_FLAGS_CHECK_AT_PREP)) { - bad_reason = "PAGE_FLAGS_CHECK_AT_PREP flag set"; + bad_reason = PAGE_BAD_PREP_FLAGS; bad_flags = PAGE_FLAGS_CHECK_AT_PREP; } #ifdef CONFIG_MEMCG if (unlikely(page->mem_cgroup)) - bad_reason = "page still charged to cgroup"; + bad_reason = PAGE_BAD_CGROUP_CHARGED; #endif bad_page(page, bad_reason, bad_flags); }