From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AF89563A2 for ; Mon, 28 Aug 2023 10:50:10 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0ABAAC433C7; Mon, 28 Aug 2023 10:50:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1693219810; bh=DOcxuvoljP6PyT/x6MHkKSR/s7DVmaLwDLe/ziQSc+I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RNmJn17UNPRZI1kxLRFCE98lJxcG3h09U5KPq3ydNF7o6qw1h1eXymri00E7Sveq1 JA6PTYPdGC9jueB157Z5YIYFMiA2GTcg2s8qABT0/aouZxIehTBjo3PQNmNUALmiKJ QnlnucapJFT88h1iypwPl12UYCfi4aDOfhNykJVQ= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Dan Williams , David Hildenbrand , Oscar Salvador , Naoya Horiguchi , Michal Hocko , Qian Cai , Andrew Morton , Linus Torvalds , Sasha Levin Subject: [PATCH 5.10 80/84] mm: fix page reference leak in soft_offline_page() Date: Mon, 28 Aug 2023 12:14:37 +0200 Message-ID: <20230828101151.996955753@linuxfoundation.org> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230828101149.146126827@linuxfoundation.org> References: <20230828101149.146126827@linuxfoundation.org> User-Agent: quilt/0.67 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 5.10-stable review patch. If anyone has any objections, please let me know. ------------------ From: Dan Williams [ Upstream commit dad4e5b390866ca902653df0daa864ae4b8d4147 ] The conversion to move pfn_to_online_page() internal to soft_offline_page() missed that the get_user_pages() reference taken by the madvise() path needs to be dropped when pfn_to_online_page() fails. Note the direct sysfs-path to soft_offline_page() does not perform a get_user_pages() lookup. When soft_offline_page() is handed a pfn_valid() && !pfn_to_online_page() pfn the kernel hangs at dax-device shutdown due to a leaked reference. Link: https://lkml.kernel.org/r/161058501210.1840162.8108917599181157327.stgit@dwillia2-desk3.amr.corp.intel.com Fixes: feec24a6139d ("mm, soft-offline: convert parameter to pfn") Signed-off-by: Dan Williams Reviewed-by: David Hildenbrand Reviewed-by: Oscar Salvador Reviewed-by: Naoya Horiguchi Cc: Michal Hocko Cc: Qian Cai Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Stable-dep-of: e2c1ab070fdc ("mm: memory-failure: fix unexpected return value in soft_offline_page()") Signed-off-by: Sasha Levin --- mm/memory-failure.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 71fd546dbdc37..e3c0fa2464ff8 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -1867,6 +1867,12 @@ static int soft_offline_free_page(struct page *page) return rc; } +static void put_ref_page(struct page *page) +{ + if (page) + put_page(page); +} + /** * soft_offline_page - Soft offline a page. * @pfn: pfn to soft-offline @@ -1892,20 +1898,26 @@ static int soft_offline_free_page(struct page *page) int soft_offline_page(unsigned long pfn, int flags) { int ret; - struct page *page; bool try_again = true; + struct page *page, *ref_page = NULL; + + WARN_ON_ONCE(!pfn_valid(pfn) && (flags & MF_COUNT_INCREASED)); if (!pfn_valid(pfn)) return -ENXIO; + if (flags & MF_COUNT_INCREASED) + ref_page = pfn_to_page(pfn); + /* Only online pages can be soft-offlined (esp., not ZONE_DEVICE). */ page = pfn_to_online_page(pfn); - if (!page) + if (!page) { + put_ref_page(ref_page); return -EIO; + } if (PageHWPoison(page)) { pr_info("%s: %#lx page already poisoned\n", __func__, pfn); - if (flags & MF_COUNT_INCREASED) - put_page(page); + put_ref_page(ref_page); return 0; } -- 2.40.1