From patchwork Mon Feb 10 21:21:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 13968629 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1B2F7C02198 for ; Mon, 10 Feb 2025 21:21:58 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 9AA6F280033; Mon, 10 Feb 2025 16:21:57 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 93284280007; Mon, 10 Feb 2025 16:21:57 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 7FAC1280033; Mon, 10 Feb 2025 16:21:57 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 5FE30280007 for ; Mon, 10 Feb 2025 16:21:57 -0500 (EST) Received: from smtpin13.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id 273821A0641 for ; Mon, 10 Feb 2025 21:21:57 +0000 (UTC) X-FDA: 83105307474.13.7003FD8 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) by imf04.hostedemail.com (Postfix) with ESMTP id 7FFD840007 for ; Mon, 10 Feb 2025 21:21:55 +0000 (UTC) Authentication-Results: imf04.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b="j06wopU/"; spf=none (imf04.hostedemail.com: domain of willy@infradead.org has no SPF policy when checking 90.155.50.34) smtp.mailfrom=willy@infradead.org; dmarc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1739222515; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=YQMQMCs6w1+E+581hiZ1NQ3PA5CTu8OYOh82Sp1fR+E=; b=ERH9GWq58IAL2zUR89lL5X4Fe1BT1kuy9UIsUU+Te7ZR2wWQX4PWZjlvXZVvOdd9lqnH9Z jLxMGQbdaR/Be1p4JNn94Yw/uvn3kZlVchRxVafFdQXELGpvlAuKDd5oFjIUbaJ14ZdICG AeBUXNQfcvKxkkf+uOEAdyxPHzkG3pY= ARC-Authentication-Results: i=1; imf04.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b="j06wopU/"; spf=none (imf04.hostedemail.com: domain of willy@infradead.org has no SPF policy when checking 90.155.50.34) smtp.mailfrom=willy@infradead.org; dmarc=none ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1739222515; a=rsa-sha256; cv=none; b=KXwiRM5yF7BYkIntBAMU49X4hQu4yF5ZtsaafLzm3abWRs6ubFU3meFd0ap1FrOgikVU3L 4J5daJxPsplg5X6oYJRRSp+ZnqzpiC9iwZnr3YoYqagee7sgy4Hl1OHWTi5xTFsSSxPis9 5nZj+lx7sbZ7SL9ouCd9bWYgTC3Z5yo= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=YQMQMCs6w1+E+581hiZ1NQ3PA5CTu8OYOh82Sp1fR+E=; b=j06wopU/tkUZM2XzZ8b1cIXdCp HUM26aOZLwQWRlhJuptTqqjvBqOhyFl2U3tt/nwzJxPL/50GByKwPqWVmKgYYO8udVpfJeBs4LaQF qgFg2yC68jWdXAjzJNvTikLWAOHmiXFCoZkRR5CnLpxU5O0N9tZ0xoUVvqT9FsbK5lVvTyz8bjBmK gwMcWW/uqRgXzithiNIwjnR8ST6hs2ON6RyNmR5OorI7PkBmQbgPpXQrZVMuEnwMnTOU6afK3v0oQ uYPheZcF6TCKvfPPP1mqndqHBtCETkwYD1/646xR78fXv3pNMatIlemCznmp64lAqqbmReXo2vCJe Q74gahIQ==; Received: from willy by casper.infradead.org with local (Exim 4.98 #2 (Red Hat Linux)) id 1thbDt-0000000GnC8-16zI; Mon, 10 Feb 2025 21:21:45 +0000 From: "Matthew Wilcox (Oracle)" To: linux-mm@kvack.org Cc: "Matthew Wilcox (Oracle)" , David Hildenbrand Subject: [RFC PATCH 3/3] proc: Use snapshot_page() in kpageflags Date: Mon, 10 Feb 2025 21:21:41 +0000 Message-ID: <20250210212142.4002210-4-willy@infradead.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250210212142.4002210-1-willy@infradead.org> References: <20250210212142.4002210-1-willy@infradead.org> MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Server: rspam09 X-Rspamd-Queue-Id: 7FFD840007 X-Stat-Signature: bg86m793ts6jsk5nksg1cgtmgm34dh5y X-HE-Tag: 1739222515-770675 X-HE-Meta: U2FsdGVkX1+r8A2NHa4WpB3CMqUTV0oLYxctwVEKWVRSj6axLQq90B1w1Bv/AagJg7hJuCMtm8isjGeWynQzAbXKs+kzCWnWuRhA/q4Rh4DpNd75yml2PCnTQzcT3OgcnONR+B5F8joOHWrw54/z79MLaYFZalOYliXxhIgpKDdqVBtUGJvcEXDB97NeIQzIXg7bzJkU27brI37PPWd5Sbk+9Tkno105bMXRb3jTyN79lKndRnp3pcMAo9XUXqGUFt9DOXXih4PkKkqae7/APVRoiYFD5ATQe78uzS2f7/prRZjv5zYil6+S8XlT6PNrTPFL4G74YOXIqFaWEzawfVlr6d6Y0TYahJUH25ZYMaZe6lf2d4XFX6FsdLOopjWP3cBaYehEEL6dP0qTwVIwAVmCHz02GYZbTB+EcYkFPHbxdrLoBTEpcoL8l/RnNN72EeWI/usnrTbNUNrfED/H7PtkyZFSngveelT5CxLqS/lWjvyp9iEdRsbezLBZqaJeiCqECirNyiOkgaC5jnXwbBVmHqGB5HF6ZTmacLblgufwT2ERUdCUtcxbQJyuqdOgUUtZezzODaDKLBOT+fPFAgI4Uq4t/lUzT75AIYby3I82zfHqLeQr2MPx4RAYU3+j6HLvHqwp3CUvoz3jz9zYt2vGpw/VNzAohA3V2V0SHif+2znE6uyOeMIgE4lcV3kOlvWzoyEHLij0p2TkccfyreK1nORjuk1TO40zOf+pkvwewbr6YmetgZn50CmTk8nsKrb2DOPNavfWLWrau9t2V9PPuAjPqzfsxb4P72T9NfBs0Bzx3aBascDvtGz7Jpy0Y4snHIIFOCSUp8YTVDIwUm0OgWVx+8oQMs6HjNGNEap7mG3X6p+EUHq+3Qh3HUx5rvvHYdPqWjG8A+mrYRGLFKCFK+MIS7zLmD+j3fM8wHPUVBIMNBBeWtd7FgSBx/MK/FqnCdjWb5K0KYfSYVk SEYmQsfV I3uqSskl248PKSsMQTK4o01pGd3btXgMhR1RyKyr8PYSnbD7J/6e17Ufc8Vj8ImpI4q6u7f3kwqwAQdq9uWpQxQsKpdv0tH4HwQjaxYsaDm9lpuMOeZ+jQH0L7Su1q3bQHSQJkoi1ykRfgJXKnm6aqIJPIBU0U3bAWJu0cWUUCxN8HKk1KL3jvHgpjaTXCvE19CqTocw9wDqlkFGW/CJD7aG5I/p8lTZhf3rmbQSl+22uI0TjcbHvjTAjnQdX9Rv+eRuzQeSXBB1LBzNUegTAf4bWJ6RDdH+40Feo 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: List-Subscribe: List-Unsubscribe: syzbot has reported a number of oopses caused by reading /proc/kpageflags racing with a folio being split / freed / allocated and thus a page which starts out as a hed page becomes a tail page during the read, which our assertions catch as an error. To solve this problem, snapshot the page like dump_page() does. Link: the syzbot reports Signed-off-by: Matthew Wilcox (Oracle) Reviewed-by: Shivank Garg --- fs/proc/page.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/fs/proc/page.c b/fs/proc/page.c index a55f5acefa97..9ebbb1e963b4 100644 --- a/fs/proc/page.c +++ b/fs/proc/page.c @@ -17,6 +17,7 @@ #include #include #include "internal.h" +#include "../mm/internal.h" /* snapshot_page() */ #define KPMSIZE sizeof(u64) #define KPMMASK (KPMSIZE - 1) @@ -106,9 +107,12 @@ static inline u64 kpf_copy_bit(u64 kflags, int ubit, int kbit) return ((kflags >> kbit) & 1) << ubit; } -u64 stable_page_flags(const struct page *page) +u64 stable_page_flags(const struct page *unstable) { + struct folio stack_folio; + struct page stack_page; const struct folio *folio; + unsigned long idx; unsigned long k; unsigned long mapping; bool is_anon; @@ -118,9 +122,9 @@ u64 stable_page_flags(const struct page *page) * pseudo flag: KPF_NOPAGE * it differentiates a memory hole from a page with no flags */ - if (!page) + if (!unstable) return 1 << KPF_NOPAGE; - folio = page_folio(page); + folio = snapshot_page(&stack_folio, &stack_page, &idx, unstable); k = folio->flags; mapping = (unsigned long)folio->mapping; @@ -129,7 +133,7 @@ u64 stable_page_flags(const struct page *page) /* * pseudo flags for the well known (anonymous) memory mapped pages */ - if (page_mapped(page)) + if (page_mapped(&stack_page)) u |= 1 << KPF_MMAP; if (is_anon) { u |= 1 << KPF_ANON; @@ -141,7 +145,7 @@ u64 stable_page_flags(const struct page *page) * compound pages: export both head/tail info * they together define a compound page's start/end pos and order */ - if (page == &folio->page) + if (idx == 0) u |= kpf_copy_bit(k, KPF_COMPOUND_HEAD, PG_head); else u |= 1 << KPF_COMPOUND_TAIL; @@ -162,14 +166,14 @@ u64 stable_page_flags(const struct page *page) * Caveats on high order pages: PG_buddy and PG_slab will only be set * on the head page. */ - if (PageBuddy(page)) + if (PageBuddy(unstable)) u |= 1 << KPF_BUDDY; - else if (page_count(page) == 0 && is_free_buddy_page(page)) + else if (folio_ref_count(folio) == 0 && is_free_buddy_page(unstable)) u |= 1 << KPF_BUDDY; - if (PageOffline(page)) + if (folio_test_offline(folio)) u |= 1 << KPF_OFFLINE; - if (PageTable(page)) + if (folio_test_pgtable(folio)) u |= 1 << KPF_PGTABLE; if (folio_test_slab(folio)) u |= 1 << KPF_SLAB; @@ -203,7 +207,7 @@ u64 stable_page_flags(const struct page *page) if (u & (1 << KPF_HUGE)) u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison); else - u |= kpf_copy_bit(page->flags, KPF_HWPOISON, PG_hwpoison); + u |= kpf_copy_bit(stack_page.flags, KPF_HWPOISON, PG_hwpoison); #endif u |= kpf_copy_bit(k, KPF_RESERVED, PG_reserved);