From patchwork Mon Feb 10 21:21:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wilcox X-Patchwork-Id: 13968630 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 434CDC02198 for ; Mon, 10 Feb 2025 21:23:08 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id C6A09280034; Mon, 10 Feb 2025 16:23:07 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id C1AA8280016; Mon, 10 Feb 2025 16:23:07 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id AB96A280034; Mon, 10 Feb 2025 16:23:07 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 89733280016 for ; Mon, 10 Feb 2025 16:23:07 -0500 (EST) Received: from smtpin18.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 2D400B0BFB for ; Mon, 10 Feb 2025 21:21:54 +0000 (UTC) X-FDA: 83105307348.18.908C58E Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) by imf06.hostedemail.com (Postfix) with ESMTP id 6B2F5180002 for ; Mon, 10 Feb 2025 21:21:52 +0000 (UTC) Authentication-Results: imf06.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b=CKTYo9UW; spf=none (imf06.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=1739222512; 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=pk+3514E1nZek8MCAYQjTVBEsflbSP2sJQOa8nDkjSk=; b=AgYMwWfATCsDAF22Hej3EPPk2MPTugoEQhA6jrs35PWc4Ox2/o4pAyaoyI1+/oMlNOVuYa dxI9v9OyDgB0OaOnHGwp6c4qtIuecluCo43dLyKFyyyNWm7nSQAfPFbmLcYyWOzMk3AIrV aMUEo0nyNQeuMJx6/k6LxJEZIAABXbc= ARC-Authentication-Results: i=1; imf06.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b=CKTYo9UW; spf=none (imf06.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=1739222512; a=rsa-sha256; cv=none; b=xPd5XTZjhNLstRtMn9ss9cd15rAq9LKrRJQBdNnprWXro6uWLlvAQuv8zf2yXVGuQrcKa3 IWe5X47ZmbxJ1nLpOq5Ac4lRIRTIFm8CC0nkJUtIxdmaDOqP6adhQHJmRwi8dlkPzCPawQ Wv24HlIBRxGAM+kIjC02o5AmsfjDE6M= 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=pk+3514E1nZek8MCAYQjTVBEsflbSP2sJQOa8nDkjSk=; b=CKTYo9UWfp0CRIavea0O8f08Ek eA6HxGp9p8CHNPdIEa+XFiEku6ngWEPzYcAziPjFr1G2jpuDykc1I2RDMeU37kvolDPsiFmdW9T2Y SyfwwDLM/6ZX5UvWD4WXYLGhr7XFdKDY575RkEttj3/OZslb+xeXVcF6Wq67fJrC1ijxr+PdGsBo/ lzhcQE/cB+HxMP4twJ3OME5sDyd5veV5GZGLannsLmxHqNTCkPQGyo9pdIY8KulsCMhBvBgwSMZ8v Erit/EIqd44FzYCrD8Z7WP0gioPvnKwKnllTcNEAeCcy3eRxFYT4uojXSuoljqFrgPZjc7NEvl04p lrpcClVQ==; Received: from willy by casper.infradead.org with local (Exim 4.98 #2 (Red Hat Linux)) id 1thbDt-0000000GnC6-0lEo; 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 2/3] mm: Create snapshot_page() Date: Mon, 10 Feb 2025 21:21:40 +0000 Message-ID: <20250210212142.4002210-3-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: rspam08 X-Rspamd-Queue-Id: 6B2F5180002 X-Stat-Signature: ukfox7jxpts57yn8ar55qcipycrxjdjk X-HE-Tag: 1739222512-267076 X-HE-Meta: U2FsdGVkX18k959kAURwyQHNV/KvU8k6Qlr4f3/6AGFjJpmcBfkyRpCDN8dlAI0xvTY4nbqCXEPQGUcOEfH1XNf+Zf1xRi/SEVe8mfjw1YNH7uo+Y5eDkOwldPs7YwCusQC4vclUsiDzzfhlvRABVVRs26axVSTG0Ltg0LJhb4Q2apAMDpwxi1yaz2Cserw49s7PQZYVJO2otl4P8YwsopJ+FWmGeTR/zFONKjoJNxq3jETD/UvppuxA+xN9d5wAsK4+TUuf+ljI7x/vrcyASXym6JY+VlOdvM4ZYZibitklMwbibGa3yT004ljohccEWrPGERZ56itraKrYSDwmOH+P6ooiQXFRJCc+S2+QdGZtAQPGu6ZVuxMeKwUuW17vvmLARg6grokizGOgoZfGE7ig5PMbkSkynKiA01zlQK9JR/u5yTLQXXED5T/NgqQRnOaXfSlynelDTd/WWYKQz9QT773RQFR0sOkcWafHEyGxCdr3mCKLrTzPeLDZ0Qw+X5PGWhY1Qvu2+ObItIVNH0l3dOFEQahE21dXESRGDBhwoYfB9NVeZVVarZlFexwYJgdwXbC9EmyPPnvk3YE+MEtjC4wjWzh9cM+Dh6CIRfqf6D6D1oyJ6JAVpsudIPSFVlhMCdt6BG/aAZBwRXzBjj9NyMZaQwjUFrC7OB3GozQqdjcO4Ki6Uhd+kkJQ3gJHnjvw4hMlZCE/gqExOLWt/f1L5hSqpmlrkAF14lqWD3o2NpDCfdUWgd3mvR00rbnvHOi1wKZ2QtQ92hZuOWG60o/xWeJhdOxMu6LboQOxp9xQlxXeS2KTZkSCOs6+fIwDrKHnVB0nSwS8Zh7B5ykH9Dr2hDKt6KR8VFgQw3K1fucHYPehvKNEhco7Yq/XAfme1y2lh6IqkbcvAF/tHEckiWIBR4QwRnefB6quLX+05kHM2ACMvR9kobK9LAuhLILmkHtDksISLwXIvNuHJ3x wFbDj1PG aQhHPoNTHa/FcaM13eV4kchuKDlkkvFY53MHDfKEnWjZLTIzLCrhWvP/YZqgDcwLeJmciA+x1Ha7glk366frieDZFZfBRy2R5ILie1D9zCrPwbq6Mh77mVK0gEUxKVVZGD0OAT9YnEpEvQRZoMjijAN2m4ouVKBxnpyv4ZKO/SPXhrWk0o3TEu1kagSSCuYdPjsk/1AA0pTlNt9iK1SCUk1nzPhJf8bQPfxUV8j//+ezcVwCAJyPPWme0+IYjnRISOSOphHv74LxvgUXfQNphkOGjp1rP2Gvl3Pds 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: Move the guts of __dump_page() into a new function called snapshot_page(). With that done, __dump_page() becomes trivial so inline it into dump_page(). Signed-off-by: Matthew Wilcox (Oracle) Reviewed-by: Shivank Garg --- mm/debug.c | 53 +++++++++------------------------------------------ mm/internal.h | 2 ++ mm/util.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 44 deletions(-) diff --git a/mm/debug.c b/mm/debug.c index fa3d9686034c..1ea5dacb1524 100644 --- a/mm/debug.c +++ b/mm/debug.c @@ -120,54 +120,19 @@ static void __dump_folio(const struct folio *folio, struct page *page, 2 * sizeof(struct page), false); } -static void __dump_page(const struct page *page) -{ - struct folio *foliop, folio; - struct page precise; - unsigned long head; - unsigned long pfn = page_to_pfn(page); - unsigned long idx, nr_pages = 1; - int loops = 5; - -again: - memcpy(&precise, page, sizeof(*page)); - head = precise.compound_head; - if ((head & 1) == 0) { - foliop = (struct folio *)&precise; - idx = 0; - if (!folio_test_large(foliop)) - goto dump; - foliop = (struct folio *)page; - } else { - foliop = (struct folio *)(head - 1); - idx = folio_page_idx(foliop, page); - } - - if (idx < MAX_FOLIO_NR_PAGES) { - memcpy(&folio, foliop, 2 * sizeof(struct page)); - nr_pages = folio_nr_pages(&folio); - foliop = &folio; - } - - if (idx > nr_pages) { - if (loops-- > 0) - goto again; - pr_warn("page does not match folio\n"); - precise.compound_head &= ~1UL; - foliop = (struct folio *)&precise; - idx = 0; - } - -dump: - __dump_folio(foliop, &precise, pfn, idx); -} - void dump_page(const struct page *page, const char *reason) { + struct folio stack_folio; + struct page stack_page; + const struct folio *folio; + unsigned long idx; + if (PagePoisoned(page)) pr_warn("page:%p is uninitialized and poisoned", page); - else - __dump_page(page); + else { + folio = snapshot_page(&stack_folio, &stack_page, &idx, page); + __dump_folio(folio, &stack_page, page_to_pfn(page), idx); + } if (reason) pr_warn("page dumped because: %s\n", reason); dump_page_owner(page); diff --git a/mm/internal.h b/mm/internal.h index 109ef30fee11..8fdfea104068 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -856,6 +856,8 @@ static inline bool free_area_empty(struct free_area *area, int migratetype) /* mm/util.c */ struct anon_vma *folio_anon_vma(const struct folio *folio); +const struct folio *snapshot_page(struct folio *foliop, struct page *precise, + unsigned long *idxp, const struct page *unstable); #ifdef CONFIG_MMU void unmap_mapping_folio(struct folio *folio); diff --git a/mm/util.c b/mm/util.c index 682ecdb1b1c2..9f9cf3933eb1 100644 --- a/mm/util.c +++ b/mm/util.c @@ -1239,3 +1239,53 @@ void flush_dcache_folio(struct folio *folio) } EXPORT_SYMBOL(flush_dcache_folio); #endif + +/* + * If you have an unstable reference to a page, use this to get a + * somewhat-consistent (potentially outdated) snapshot. The consistency + * is limited to the page being contained in the folio. You need to pass in + * a scratch folio and scratch page, probably allocated on the stack. + * You get back a pointer to the scratch folio you passed in, marked + * as const to remind you not to modify this. + */ +const struct folio *snapshot_page(struct folio *foliop, struct page *precise, + unsigned long *idxp, const struct page *unstable) +{ + struct folio *folio; + unsigned long head; + unsigned long idx, nr_pages = 1; + int loops = 5; + +again: + memcpy(precise, unstable, sizeof(struct page)); + head = precise->compound_head; + /* Open-coded !PageTail because page_is_fake_head() doesn't work here */ + if ((head & 1) == 0) { + folio = (struct folio *)precise; + *idxp = 0; + /* Not a tail, not a head, we have a single page */ + if (!folio_test_large(folio)) + goto out; + folio = (struct folio *)unstable; + } else { + folio = (struct folio *)(head - 1); + *idxp = folio_page_idx(folio, unstable); + } + + if (idx < MAX_FOLIO_NR_PAGES || folio_test_hugetlb(folio)) { + memcpy(foliop, folio, sizeof(struct folio)); + nr_pages = folio_nr_pages(foliop); + folio = foliop; + } + + if (idx > nr_pages) { + if (loops-- > 0) + goto again; + pr_warn("page does not match folio\n"); + precise->compound_head &= ~1UL; + folio = (struct folio *)precise; + *idxp = 0; + } +out: + return folio; +}