From patchwork Fri Jul 13 03:26:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naoya Horiguchi X-Patchwork-Id: 10522543 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DEF6C6028E for ; Fri, 13 Jul 2018 03:26:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CD96C28CB5 for ; Fri, 13 Jul 2018 03:26:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C21A429B99; Fri, 13 Jul 2018 03:26:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1778028CB5 for ; Fri, 13 Jul 2018 03:26:29 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 4A2826B000A; Thu, 12 Jul 2018 23:26:27 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 452836B000C; Thu, 12 Jul 2018 23:26:27 -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 2FD406B000D; Thu, 12 Jul 2018 23:26:27 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from mail-pl0-f71.google.com (mail-pl0-f71.google.com [209.85.160.71]) by kanga.kvack.org (Postfix) with ESMTP id CFAFE6B000A for ; Thu, 12 Jul 2018 23:26:26 -0400 (EDT) Received: by mail-pl0-f71.google.com with SMTP id f31-v6so10825044plb.10 for ; Thu, 12 Jul 2018 20:26:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:dkim-signature:sender:from:to:cc:subject:date :message-id:in-reply-to:references; bh=gc/9xeTOIbw53F6nYP89sY5reU1DoIfxCKRmupl9mxU=; b=LZnRNVC3W96i2lH0AO4U97VNFDXRKqEzqUJ6Rna9/YG7elB+0S1w5pdiBoYXY83qmF BN6WikEI1tKWPh38ngurUitBVOTo8oaQ3VMoEG1yq/R48vYD+h9MrLLGz/apVh+1PaF+ M88tmVkKlY92EA9WZe9AtEimCIcsfLW1IkQV0i+uwUL3sxGBmmjC+vIYSDggPiMj84A5 8aTkUcykQuW3pImZiwK/hK3CT3jtcbSTXjvKS+S0bGPxIEyBur5BT7CRHbv36ekd6srs uzS2Q/YRyqHxhNWbT14kNB1E+piGo9TgJLc5mzQ9cQC41LuwN6n60dYUYC5ETwIjj4lf 1wXg== X-Gm-Message-State: AOUpUlHHcHaF3c97LrNX7dIg+2pa2Ldq7NuyBrAHdyazwO6LNsOku6to w1Csgh+PXwnoNO+m+R1qQl6zPsDHXWryAQ+MBEXwERP9TmenLp26mfkV2Fvnt0sE6b3u7C4bqah ivW8NAsOfMhM1YPeJm6Pv56fVMDNHQAPThsxb47yEgnATwpS7FRqAgWeFVcZ10jCnkLeXbtTKjo Z+t0foBH82k7UrM/Eyiwm8YycrqflXYoseL0+hXatC3+QHgDV3YQStGvkgo7t7Wia7Wy5ODv2wz NKyvNR2hx2eaahsUtam7gxQaIhOpqS0q/sYfPdYjBTJ4wNOWVI/s3F5bewKfL87Pj1j65a1UwAl 59MEZXAXYEiNhyvP1DsgRvF7JsaBazh0GYPZe2XJMTGKaGZzJlbzrvFT13htyMIJ2ivgu2e8gw= = X-Received: by 2002:a63:1350:: with SMTP id 16-v6mr4450963pgt.214.1531452386517; Thu, 12 Jul 2018 20:26:26 -0700 (PDT) X-Received: by 2002:a63:1350:: with SMTP id 16-v6mr4450919pgt.214.1531452385476; Thu, 12 Jul 2018 20:26:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531452385; cv=none; d=google.com; s=arc-20160816; b=Ht77RxfPhzIa6BpjOwyzbIIhA0ntjHd+FdABo16vZsbi7RnaJFCGpQPDT08LzotxP9 0C7Ssler+UXjbS2aZrIbDjbl1uOrffHGYaQ1p7KVV6nA7SZCC1a2XofyWGlaWTeEAFzq qow+O6MrEeVIUx2Byhh615vAG2vpGjWeHpCtOjbucLibn/0TczaWsBMHyqQjHxUTjO1O VHKuv4VloDX5vmWGHJkOZH4hq+Rfztws+hCZwEfHX8sLUdnBGU7WM1Wz8oaA6rwzrGwp ZmuNCQw4BIRiTD2OcCAa6VExSmT9g3JRiVyOEZZXGtWL3T+5aa6Jo+NgDVABG2IH9o+8 TSiA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from:sender :dkim-signature:arc-authentication-results; bh=gc/9xeTOIbw53F6nYP89sY5reU1DoIfxCKRmupl9mxU=; b=FSQeRCKWUP6afkwzKiii6sHNRlc/jY/cGUlM7/6eo3SUtb/iD3VMN0GzCkgVxpnFtC nxVINUBXF5wVUvVPwgzZYgjVo2loDwzC3LRZFysWOOMsNYpMuHzP/YZwChNkfDHDp0cY t0wQjzMs0vL7go91sNcJRfdWUcKBMOOO71vFepSD9NGZcZ0HK97fQwjEDeHEKL3AXLQO IWaby5o7+4Hp+Al4jF26XVaYsgw2NsWYNQiXNZArlJsJgcQgLE2s3sYsxi/Q4iiLzp0q orlTkt7omM1c9DBEDyjzG+9p42MPt9kiVwZ7WLrlJPglJmn51cW7vcNe9kT653ImYVEl +fxQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=YjHJVLKq; spf=pass (google.com: domain of nao.horiguchi@gmail.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=nao.horiguchi@gmail.com Received: from mail-sor-f65.google.com (mail-sor-f65.google.com. [209.85.220.65]) by mx.google.com with SMTPS id e2-v6sor7152459pfb.34.2018.07.12.20.26.25 for (Google Transport Security); Thu, 12 Jul 2018 20:26:25 -0700 (PDT) Received-SPF: pass (google.com: domain of nao.horiguchi@gmail.com designates 209.85.220.65 as permitted sender) client-ip=209.85.220.65; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=YjHJVLKq; spf=pass (google.com: domain of nao.horiguchi@gmail.com designates 209.85.220.65 as permitted sender) smtp.mailfrom=nao.horiguchi@gmail.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=gc/9xeTOIbw53F6nYP89sY5reU1DoIfxCKRmupl9mxU=; b=YjHJVLKqS55fOsiVgjemOD4Wrk4FwWz0KMIChBKWZ9vlx5jQSijHM6b6M6a3K30vmv pIXstIdYq1ci85VO0Dvxtp6De1Tqimn+qxHz2UF9tBrDm6K968azdwwZMz76/RoLITYa dCmoRQtyHgekyWidk5u2xfXZxoiKCCLl2IpqzenwKjpuz69Va/UpwKWovp6l5DLoWaoR 0hduLLnIJbTwdsirWjGWQlqVTTSF10IQrtTes3Vt6eerDd9SpbULdV62QQ771o2Pkt7E OQW47TUIPjzz2TjRrdzJptGiVCMvNpXzgy7ymyfB7mdVFApS1ArEQqAoj7FcsN0d26kc CdzQ== X-Google-Smtp-Source: AAOMgpd69noVRezXFSpuNk8AuGo4WPydicOwcnjAoqVpyGifKrRw8VQrUQiUGfdKsLLbpqUvT/95Xg== X-Received: by 2002:a62:5290:: with SMTP id g138-v6mr5218677pfb.46.1531452384669; Thu, 12 Jul 2018 20:26:24 -0700 (PDT) Received: from www9186uo.sakura.ne.jp (www9186uo.sakura.ne.jp. [153.121.56.200]) by smtp.gmail.com with ESMTPSA id b66-v6sm8867241pgc.15.2018.07.12.20.26.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 12 Jul 2018 20:26:23 -0700 (PDT) From: Naoya Horiguchi To: linux-mm@kvack.org Cc: Michal Hocko , Andrew Morton , xishi.qiuxishi@alibaba-inc.com, zy.zhengyi@alibaba-inc.com, linux-kernel@vger.kernel.org Subject: [PATCH v1 2/2] mm: soft-offline: close the race against page allocation Date: Fri, 13 Jul 2018 12:26:06 +0900 Message-Id: <1531452366-11661-3-git-send-email-n-horiguchi@ah.jp.nec.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1531452366-11661-1-git-send-email-n-horiguchi@ah.jp.nec.com> References: <1531452366-11661-1-git-send-email-n-horiguchi@ah.jp.nec.com> 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: X-Virus-Scanned: ClamAV using ClamSMTP A process can be killed with SIGBUS(BUS_MCEERR_AR) when it tries to allocate a page that was just freed on the way of soft-offline. This is undesirable because soft-offline (which is about corrected error) is less aggressive than hard-offline (which is about uncorrected error), and we can make soft-offline fail and keep using the page for good reason like "system is busy." Two main changes of this patch are: - setting migrate type of the target page to MIGRATE_ISOLATE. As done in free_unref_page_commit(), this makes kernel bypass pcplist when freeing the page. So we can assume that the page is in freelist just after put_page() returns, - setting PG_hwpoison on free page under zone->lock which protects freelists, so this allows us to avoid setting PG_hwpoison on a page that is decided to be allocated soon. Reported-by: Xishi Qiu Signed-off-by: Naoya Horiguchi --- include/linux/page-flags.h | 5 +++++ include/linux/swapops.h | 10 ---------- mm/memory-failure.c | 26 +++++++++++++++++++++----- mm/migrate.c | 2 +- mm/page_alloc.c | 29 +++++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 16 deletions(-) diff --git v4.18-rc4-mmotm-2018-07-10-16-50/include/linux/page-flags.h v4.18-rc4-mmotm-2018-07-10-16-50_patched/include/linux/page-flags.h index 901943e..74bee8c 100644 --- v4.18-rc4-mmotm-2018-07-10-16-50/include/linux/page-flags.h +++ v4.18-rc4-mmotm-2018-07-10-16-50_patched/include/linux/page-flags.h @@ -369,8 +369,13 @@ PAGEFLAG_FALSE(Uncached) PAGEFLAG(HWPoison, hwpoison, PF_ANY) TESTSCFLAG(HWPoison, hwpoison, PF_ANY) #define __PG_HWPOISON (1UL << PG_hwpoison) +extern bool set_hwpoison_free_buddy_page(struct page *page); #else PAGEFLAG_FALSE(HWPoison) +static inline bool set_hwpoison_free_buddy_page(struct page *page) +{ + return 0; +} #define __PG_HWPOISON 0 #endif diff --git v4.18-rc4-mmotm-2018-07-10-16-50/include/linux/swapops.h v4.18-rc4-mmotm-2018-07-10-16-50_patched/include/linux/swapops.h index 9c0eb4d..fe8e08b 100644 --- v4.18-rc4-mmotm-2018-07-10-16-50/include/linux/swapops.h +++ v4.18-rc4-mmotm-2018-07-10-16-50_patched/include/linux/swapops.h @@ -335,11 +335,6 @@ static inline int is_hwpoison_entry(swp_entry_t entry) return swp_type(entry) == SWP_HWPOISON; } -static inline bool test_set_page_hwpoison(struct page *page) -{ - return TestSetPageHWPoison(page); -} - static inline void num_poisoned_pages_inc(void) { atomic_long_inc(&num_poisoned_pages); @@ -362,11 +357,6 @@ static inline int is_hwpoison_entry(swp_entry_t swp) return 0; } -static inline bool test_set_page_hwpoison(struct page *page) -{ - return false; -} - static inline void num_poisoned_pages_inc(void) { } diff --git v4.18-rc4-mmotm-2018-07-10-16-50/mm/memory-failure.c v4.18-rc4-mmotm-2018-07-10-16-50_patched/mm/memory-failure.c index c63d982..794687a 100644 --- v4.18-rc4-mmotm-2018-07-10-16-50/mm/memory-failure.c +++ v4.18-rc4-mmotm-2018-07-10-16-50_patched/mm/memory-failure.c @@ -57,6 +57,7 @@ #include #include #include +#include #include "internal.h" #include "ras/ras_event.h" @@ -1697,6 +1698,7 @@ static int __soft_offline_page(struct page *page, int flags) static int soft_offline_in_use_page(struct page *page, int flags) { int ret; + int mt; struct page *hpage = compound_head(page); if (!PageHuge(page) && PageTransHuge(hpage)) { @@ -1715,23 +1717,37 @@ static int soft_offline_in_use_page(struct page *page, int flags) put_hwpoison_page(hpage); } + /* + * Setting MIGRATE_ISOLATE here ensures that the page will be linked + * to free list immediately (not via pcplist) when released after + * successful page migration. Otherwise we can't guarantee that the + * page is really free after put_page() returns, so + * set_hwpoison_free_buddy_page() highly likely fails. + */ + mt = get_pageblock_migratetype(page); + set_pageblock_migratetype(page, MIGRATE_ISOLATE); if (PageHuge(page)) ret = soft_offline_huge_page(page, flags); else ret = __soft_offline_page(page, flags); - + set_pageblock_migratetype(page, mt); return ret; } -static void soft_offline_free_page(struct page *page) +static int soft_offline_free_page(struct page *page) { int rc = 0; struct page *head = compound_head(page); if (PageHuge(head)) rc = dissolve_free_huge_page(page); - if (!rc && !TestSetPageHWPoison(page)) - num_poisoned_pages_inc(); + if (!rc) { + if (set_hwpoison_free_buddy_page(page)) + num_poisoned_pages_inc(); + else + rc = -EBUSY; + } + return rc; } /** @@ -1775,7 +1791,7 @@ int soft_offline_page(struct page *page, int flags) if (ret > 0) ret = soft_offline_in_use_page(page, flags); else if (ret == 0) - soft_offline_free_page(page); + ret = soft_offline_free_page(page); return ret; } diff --git v4.18-rc4-mmotm-2018-07-10-16-50/mm/migrate.c v4.18-rc4-mmotm-2018-07-10-16-50_patched/mm/migrate.c index 3ae213b..e772323 100644 --- v4.18-rc4-mmotm-2018-07-10-16-50/mm/migrate.c +++ v4.18-rc4-mmotm-2018-07-10-16-50_patched/mm/migrate.c @@ -1199,7 +1199,7 @@ static ICE_noinline int unmap_and_move(new_page_t get_new_page, * intentionally. Although it's rather weird, * it's how HWPoison flag works at the moment. */ - if (!test_set_page_hwpoison(page)) + if (set_hwpoison_free_buddy_page(page)) num_poisoned_pages_inc(); } } else { diff --git v4.18-rc4-mmotm-2018-07-10-16-50/mm/page_alloc.c v4.18-rc4-mmotm-2018-07-10-16-50_patched/mm/page_alloc.c index 607deff..3c76d40 100644 --- v4.18-rc4-mmotm-2018-07-10-16-50/mm/page_alloc.c +++ v4.18-rc4-mmotm-2018-07-10-16-50_patched/mm/page_alloc.c @@ -8027,3 +8027,32 @@ bool is_free_buddy_page(struct page *page) return order < MAX_ORDER; } + +#ifdef CONFIG_MEMORY_FAILURE +/* + * Set PG_hwpoison flag if a given page is confirmed to be a free page + * within zone lock, which prevents the race against page allocation. + */ +bool set_hwpoison_free_buddy_page(struct page *page) +{ + struct zone *zone = page_zone(page); + unsigned long pfn = page_to_pfn(page); + unsigned long flags; + unsigned int order; + bool hwpoisoned = false; + + spin_lock_irqsave(&zone->lock, flags); + for (order = 0; order < MAX_ORDER; order++) { + struct page *page_head = page - (pfn & ((1 << order) - 1)); + + if (PageBuddy(page_head) && page_order(page_head) >= order) { + if (!TestSetPageHWPoison(page)) + hwpoisoned = true; + break; + } + } + spin_unlock_irqrestore(&zone->lock, flags); + + return hwpoisoned; +} +#endif