From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from SA9PR02CU001.outbound.protection.outlook.com (mail-southcentralusazon11013070.outbound.protection.outlook.com [40.93.196.70]) (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 EDB4F23C4FA for ; Fri, 12 Jun 2026 18:34:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.93.196.70 ARC-Seal:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781289295; cv=fail; b=ePlZxo5nm4OOrxEReV8pxP2IAd0Vl2KxEInvDCBv6nD4rgWn1h+X2IgyduXmK3WhK2kaSxgqBZPgp+azf+6ZrvGxUXQHbywb1N18XEh8JCdPQsPcIB/5+9MXrm5S4huq87jGEJAXz82SGXg3DtDcM8iB1gv1qS4w1WifpSOuKtI= ARC-Message-Signature:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781289295; c=relaxed/simple; bh=mIequzYfatmNZJ4Hxv9UbRyC3yScqNrhmLYeRlTOMjw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: Content-Type:MIME-Version; b=uyq5jCZ+kLE8cFZx6z8geXLCYYa8wstKl7+W6t64MYzM17wQQ9YUUHMuDwdAXOi94z8+8lm4miqNIgV2YoD9cR1wJ4EgZzfevTckIR3oFKuOxyNfpZdiBJPS8DI8oD2gN0WhZvmUyJu3QiCQMBkvzy/+/nrvo2VNjnI9q0MmLc4= ARC-Authentication-Results:i=2; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com; spf=fail smtp.mailfrom=nvidia.com; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b=mES1WEkQ; arc=fail smtp.client-ip=40.93.196.70 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=nvidia.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=nvidia.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=Nvidia.com header.i=@Nvidia.com header.b="mES1WEkQ" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=dpsIFNeMK0NBsP3hlS5IqoG7Avj6/Cpbobi/scyKF/vw066tOyOkSz05EpEijs4h5nBpXT0fLGEwxJFA3bfyly79pZfvVIybDG7Bicu348PRJPC0juVSvpfx00ngJKq7K6dBEwTDW+VW2tM45NcSOfP8+DGO/bbKfGRfjcNHwfNjPJ86AdTDi3bcInZX6UMqPVQCG8cSkTUSEXNh3yBpzah0IRBTGdK21DYWIoNzf4s+uy1iUHCUCaoU7QNAkTM0ZMN3MzwKWggb5ajNgE7d91C03mXBK4Lj8hR3w27M0PaYcTNEQUEnEsXhjzgonXF/yFfMw9bhUEJEcfnUbsXKIw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=6uEJBGidTuRydWiiU2snpHL8U615cVtMVhxbBaIz9O0=; b=sDZyRkSoU2VDm1vlFkdnjEdxpLWxpUHziY+kdGOk7m8RFIKIg6dF6CGldI5ttMW96BdCCaBQjUoF5WKXrDfleEjssrhEWlI5y7tr2WVaHhoxN9X7JwG6R76oMPcovXyaAR+oCIJ13GOn2AwqBQ8nn8/vc7lsAqarPTbix1hxrFin2e8MVK7tZ3Irq7Bu5Lyr0raJdXf34cTKvndGHuG+meKvbrVHYkAvwc9Yg3XvXgx4CAEXLCR+IL1o3cUh+nUI8hXwilmUtSTGIoimweRCP+gWWzzRXNWGBciBwpR4CqvxHp6m7LFdQRUSg9TeoyY3I9qD6JfPXVXtNyoxuKAfPA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=6uEJBGidTuRydWiiU2snpHL8U615cVtMVhxbBaIz9O0=; b=mES1WEkQyJ4/rtqrZTxP9IENj/1Slt0UQUJCuJGiObLbe2FLhCkiee5pPMMxJ8D72b6AoC1B3gCpZ7jypZi+MmfaIeQ1E4FN+YrjhvrakxYUb+0teB9mb9XQ9JseFCN9P9wBs4Hi+NZ7iLFbcMhrAE1ssRj24V794c2gDZZz7WW5VLXwwpKS7bAzlN0EZf4SaGxXTtHAkihg6YKzTLuHvmiJGtSPGdgu7b5CPbr28Tm7HMFlfVbTvKbVqQigT00ZhvgiWssNCj0Nzvj9dmgGhsmKEE6rywgCPhcPhltc1iIeUoJi6kt1IM+hs+hTsGG1nNB5VaLvjR6vLtMYGLiL3g== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; Received: from DS7PR12MB9473.namprd12.prod.outlook.com (2603:10b6:8:252::5) by MN2PR12MB4302.namprd12.prod.outlook.com (2603:10b6:208:1de::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.113.15; Fri, 12 Jun 2026 18:34:49 +0000 Received: from DS7PR12MB9473.namprd12.prod.outlook.com ([fe80::f01d:73d2:2dda:c7b2]) by DS7PR12MB9473.namprd12.prod.outlook.com ([fe80::f01d:73d2:2dda:c7b2%5]) with mapi id 15.21.0113.013; Fri, 12 Jun 2026 18:34:48 +0000 From: Zi Yan To: Miaohe Lin , Jiaqi Yan Cc: osalvador@suse.de, lorenzo.stoakes@oracle.com, jackmanb@google.com, hannes@cmpxchg.org, nao.horiguchi@gmail.com, david@kernel.org, william.roche@oracle.com, tony.luck@intel.com, wangkefeng.wang@huawei.com, jane.chu@oracle.com, akpm@linux-foundation.org, muchun.song@linux.dev, liam@infradead.org, rientjes@google.com, duenwen@google.com, jthoughton@google.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org, vbabka@suse.cz, rppt@kernel.org, shuah@kernel.org, surenb@google.com, mhocko@suse.com, boudewijn@delta-utec.com, ljs@kernel.org, osalvador@kernel.org, harry.yoo@oracle.com, willy@infradead.org Subject: Re: [PATCH v5 1/4] mm/page_alloc: only free healthy pages in high-order has_hwpoisoned folio Date: Fri, 12 Jun 2026 14:34:44 -0400 X-Mailer: MailMate (2.0r6290) Message-ID: <45290F97-B8BD-4A9B-934E-0A122A5F3A80@nvidia.com> In-Reply-To: <84a0b176-8534-e03a-9e6e-400c74ddab0b@huawei.com> References: <20260531055829.3636554-1-jiaqiyan@google.com> <20260531055829.3636554-2-jiaqiyan@google.com> <84a0b176-8534-e03a-9e6e-400c74ddab0b@huawei.com> Content-Type: text/plain Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: MN2PR06CA0009.namprd06.prod.outlook.com (2603:10b6:208:23d::14) To DS7PR12MB9473.namprd12.prod.outlook.com (2603:10b6:8:252::5) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS7PR12MB9473:EE_|MN2PR12MB4302:EE_ X-MS-Office365-Filtering-Correlation-Id: 1c4d140c-1fc2-4c1e-a5ae-08dec8b14885 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|23010399003|1800799024|366016|376014|7416014|56012099006|5023799004|11063799006|6133799003|4143699003|22082099003|18002099003; X-Microsoft-Antispam-Message-Info: wfkWkCd73RS5u0SPs+hHXoNA8XXmZ7ohVwedtO1iC4P/wwNbqIgHXT4OqDUTpJ+8t8gOJtvyGeT/SrG1Ml6fVrY3F5W6hBM58ofiHHSwTnDAk3Ecdhj5XiL5wMhVwoOTVkt5L+lJgtdlk6rvbk/9BPgzAiG3xqYlE9TFdtvwj9gazG33YHPD+kiDTjApU21Ovxdl511J3DMGfIKkobJfpFGLTaRnrqvqRNaEdmytUm0talnheoF2s+wEYEjKLLTIBTIhbZb3VeZPjoC8dlrPVJH41XVNrbBq+E4pKjOhAUrJHIhOI0BNkbS+D+Y74404FJAPgWEtbYh92Gr+lFppWkzh7OJRJCXkilE+W04GePYxcWIHYgKcDA5sGMeSoRlTJZxAQMzLNWPHjXc6Yv5kAPYUDjiH0MJOjySyN5uQFfwIowZM3HFBrZmJkwfJlFnIIui3JYa8lPCR8lR+jNGZ5au56NoKAulS3xju+ILVHklQ3mccmvXwVGK/TnR64cLADYRDWO9+I/ZJDaZzv/WlPdbf/DRtPBQ67t06UsYFv6V+G1cRPQNQJ7lTw9auqQGjt5qu3Vb4n89iphTmZqFtOY87/g5Yjo+X+RW2dmmolpAJ3yqlR0coWsuaFONBlJsA3IfnhL2Lio3US66j1Pv4dZBtOJ4OAiuIo79Ya5Z8P4G4A+JGoSfbDxOHUp4YYGAp X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DS7PR12MB9473.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(23010399003)(1800799024)(366016)(376014)(7416014)(56012099006)(5023799004)(11063799006)(6133799003)(4143699003)(22082099003)(18002099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?fsuK2dWxO1qV9aT2szXk2zmSSoVhqTJDb3uIHJGUOhYlhd+/kpz+TPQcE/x9?= =?us-ascii?Q?aRv7V3K614aQohl0LWt6IawM28RCFQeihOe6+nU+Wp2w3k+lwhaIogVCeNw/?= =?us-ascii?Q?J95RLkTWJSzUlj7wl1mKoLXoifK2OsMy85qhqIPflcjjJUMVvZioPmNpmr3P?= =?us-ascii?Q?duV6NchsqU9If0YlMTmX58TxXxy9+oRswoFmdN/CtYZkqxeCbhlTpkI9bHnY?= =?us-ascii?Q?OLyadc67InbsTAkoQbi7zMcxPQBHzISqqLu3Q/ot6qVfOmNAiFenF67BPIok?= =?us-ascii?Q?lZTKNTnJOLcM3+cWNNcaRVeguBQ17yfqAoSnbIfyeLhv3Q2S/+MnQfqkQ3xG?= =?us-ascii?Q?p6vppNRne9ssxPR5ak8u6GDv6q81qHyeVronfX9/3fDKnFSfADHjrdQ4XekT?= =?us-ascii?Q?TzTajaXGTtJkIrwpcH9oUhpuhC3mCWiW7K+7MyDgjRmqCn9a1I3mweI2RPY3?= =?us-ascii?Q?c+XrR4iO8ucxHoTRNmj93oyF/QQ3PUSy5c++TlEDJokA7JlZy2wcbx4BSo2k?= =?us-ascii?Q?U+pTtnA5iJlbfPJDrlP4G1wQAVlxybo1zaNWW8uw9b3oUaEY2pXuWKyZgyQl?= =?us-ascii?Q?je1Ih7sHQg0B4XoVvjfQwzTQSAoMRQYL11qAy3Z3+RvYWVZAmHL9t/tXkJQK?= =?us-ascii?Q?ehFuib0DBoxBsSTlOUBYsGpr99wG+oL1/rTsjCk0KTTrx5jvD4impTeprTxb?= =?us-ascii?Q?6kyi+c0/l3mK7l+mHeSyYAV8Z06owJQMiLiMF7GT5DYIdwK2lj7MCYfFlhCv?= =?us-ascii?Q?pM8pcvGeLeMdcLpr8vagBfADrcJIoRo9vCwVTNF2Zp8zrMN4lGrHzvtavy1d?= =?us-ascii?Q?AClljUOSEcx04GjQKGa0fxlsbjQfJh8i2ITv3c4edmHtS4eDR/gHaKbtKI7/?= =?us-ascii?Q?vwaKEYqfsbqCEhG8UXd2FQRhQrHk9sy3L9GSA7aw72RALaFFJ4laGTUu7cG/?= =?us-ascii?Q?hcXaZbpwbtwt/aLcQZXlIbYMF/OkjMma9x9ASZ+MMULTpw+9G7xczK+Ta8yg?= =?us-ascii?Q?k4HgdIlQXgYLRvb8Mr/JRtRV087kLUHh2uCeyi+89GYxtcwfdNowKHFTqvMb?= =?us-ascii?Q?oEiJIZvfYcIPt3WtMje4yLvGwGnuScaPI2UW3u16yftmxDZS7XAoWqyWllal?= =?us-ascii?Q?zdmituito9zBfQ9+XBcVv3p8/mSlqyekdrpnwMIP6jcPthHt9vWfzNvZ2aKb?= =?us-ascii?Q?I5TiZlT7WRa3njDsI6DZ6N+sFwxbkBKYy5Rf8XbfNc4YWZdunN2HkFW0lUgl?= =?us-ascii?Q?EDla84hfnf930Aq+P8ec1i0q9vCotXGF2yP6JtDHAcuVshdSeCz4Qdmk18eb?= =?us-ascii?Q?7k6z3wUSA62fl45gIuN3vf3RQcZy5Vc9Oo3WgBdyluoegAqvilzv/9YQhQKt?= =?us-ascii?Q?/02tkO5nZ9tTt7rpdxNXK7iREEjA/DTC/NbSNOxVSU+S364/ruV5FvmBjjcO?= =?us-ascii?Q?FlfbyUTfVWOqNHtgB6j2vAbW7VZN0gA1Rf4qzw/5Gq5GHL/xEHQVYy0EFrAv?= =?us-ascii?Q?BgzxW/ZRiE0R5WmeBcClTZBS7PgG6H7/zeGJ88kPotS6WRhFpngV4nf997rH?= =?us-ascii?Q?C0fACDbGptbGaOGneRx41hHpZqsZX9FvnHWzMHOSzPM8CTsHBEGWMp4yfz9o?= =?us-ascii?Q?2OrucNqTlnN3lcm/CSo48qyQLpfLPvpBRx5YRNaw/DBeKbeWzegXtfQOE+Ff?= =?us-ascii?Q?BBau45rCweqhPzt5NZYsa3VaiYPNzbkaeG0on8i1MVvKzZHF?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1c4d140c-1fc2-4c1e-a5ae-08dec8b14885 X-MS-Exchange-CrossTenant-AuthSource: DS7PR12MB9473.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jun 2026 18:34:48.6123 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 5iDTNRx7/IXD9MMRPH+cUMRp6DSciZwxBh7iNG4Xgyij18JhUdV++jE2wC543yYV X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4302 On 8 Jun 2026, at 23:44, Miaohe Lin wrote: > On 2026/5/31 13:58, Jiaqi Yan wrote: >> At the end of dissolve_free_hugetlb_folio(), a free HugeTLB folio >> becomes non-HugeTLB, and it is released to buddy allocator >> as a high-order folio, e.g. a folio that contains 262144 pages >> if the folio was a 1G HugeTLB hugepage. >> >> This is problematic if the HugeTLB hugepage contained HWPoison >> subpages. In that case, since buddy allocator does not check >> HWPoison for non-zero-order folio, the raw HWPoison page can >> be given out with its buddy page and be re-used by either >> kernel or userspace. >> >> Memory failure recovery (MFR) in kernel does attempt to take >> raw HWPoison page off buddy allocator after >> dissolve_free_hugetlb_folio(). However, there is always a time >> window between dissolve_free_hugetlb_folio() frees a HWPoison >> high-order folio to buddy allocator and MFR takes HWPoison >> raw page off buddy allocator. >> >> Another similar situation is when a transparent huge page (THP) >> runs into memory failure but splitting failed. Such THP will >> eventually be released to buddy allocator when owning userspace >> processes are gone, but with certain subpages having HWPoison. >> >> One obvious way to avoid both problems is to add page sanity >> checks in page allocate or free path. However, it is against >> the past efforts to reduce sanity check overhead [1,2,3]. >> >> Introduce free_has_hwpoisoned() to only free the healthy pages >> and to exclude the HWPoison ones in the high-order folio. >> The idea is to iterate through the sub-pages of the folio to >> identify contiguous ranges of healthy pages. >> >> free_has_hwpoisoned() is added in free_pages_prepare() as >> a shortcut and is only invoked if PG_has_hwpoisoned indicates >> HWPoison page exists and after checks and preparations in >> free_pages_prepare() all succeeded. free_has_hwpoisoned() then >> can re-use free_prepared_contig_range() [4] to decompose healthy >> ranges into the largest possible chunks of different orders. >> Every chunk meets the requirements to be freed via free_one_page(). >> >> free_has_hwpoisoned() has linear time complexity wrt the number >> of pages in the folio. While the power-of-two decomposition >> ensures that the number of calls to the buddy allocator is >> logarithmic for each contiguous healthy range, the mandatory >> linear scan of pages to identify PageHWPoison() defines the >> overall time complexity. For a 1G hugepage having 8 HWPoison >> pages, free_has_hwpoisoned() takes around 1ms on average on >> a system having 56 Intel Skylake physical cores. This is >> 15x to the case of freeing no HWPoison page. The cost is far >> from triggering soft lockup, and fair for handling exceptional >> hardware memory errors. >> >> [1] https://lore.kernel.org/linux-mm/1460711275-1130-15-git-send-email= -mgorman@techsingularity.net >> [2] https://lore.kernel.org/linux-mm/1460711275-1130-16-git-send-email= -mgorman@techsingularity.net >> [3] https://lore.kernel.org/all/20230216095131.17336-1-vbabka@suse.cz >> [4] https://lore.kernel.org/all/20260401101634.2868165-2-usama.anjum@a= rm.com >> >> Signed-off-by: Jiaqi Yan > > Thanks for your update. This patch looks good to me while some comments= below. > >> --- >> mm/page_alloc.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++= + >> 1 file changed, 85 insertions(+) >> >> diff --git a/mm/page_alloc.c b/mm/page_alloc.c >> index e47679e7a9db..03df929abca6 100644 >> --- a/mm/page_alloc.c >> +++ b/mm/page_alloc.c >> @@ -208,6 +208,7 @@ gfp_t gfp_allowed_mask __read_mostly =3D GFP_BOOT_= MASK; >> unsigned int pageblock_order __read_mostly; >> #endif >> >> +static void free_has_hwpoisoned(struct page *page, unsigned int order= ); >> static void __free_pages_ok(struct page *page, unsigned int order, >> fpi_t fpi_flags); >> static void reserve_highatomic_pageblock(struct page *page, int order= , >> @@ -1309,6 +1310,14 @@ static inline void pgalloc_tag_sub_pages(struct= alloc_tag *tag, unsigned int nr) >> >> #endif /* CONFIG_MEM_ALLOC_PROFILING */ >> >> +/* >> + * Returns >> + * - true: checks and preparations all good, caller can proceed freei= ng. >> + * - false: do not proceed freeing for one of the following reasons: >> + * 1. Some check failed so it is not safe to proceed freeing. >> + * 2. A compound page has some HWPoison pages. The healthy pages >> + * are already safely freed, and the HWPoison ones isolated. >> + */ >> static __always_inline bool __free_pages_prepare(struct page *page, >> unsigned int order, fpi_t fpi_flags) >> { >> @@ -1317,6 +1326,15 @@ static __always_inline bool __free_pages_prepar= e(struct page *page, >> bool init =3D want_init_on_free(); >> bool compound =3D PageCompound(page); >> struct folio *folio =3D page_folio(page); >> + /* >> + * When dealing with compound page, PG_has_hwpoisoned is cleared >> + * with PAGE_FLAGS_SECOND. So the check must be done first. >> + * >> + * Note we can't exclude PG_has_hwpoisoned from PAGE_FLAGS_SECOND. >> + * Because PG_has_hwpoisoned =3D=3D PG_active, free_page_is_bad() wi= ll >> + * confuse and complaint that the first tail page is still active. >> + */ >> + bool should_fhh =3D compound && folio_test_has_hwpoisoned(folio); >> >> if (fpi_flags & FPI_PREPARED) >> return true; >> @@ -1443,6 +1461,16 @@ static __always_inline bool __free_pages_prepar= e(struct page *page, >> >> debug_pagealloc_unmap_pages(page, 1 << order); >> >> + /* >> + * After breaking down compound page and dealing with page metadata >> + * (e.g. page owner and page alloc tags), take a shortcut if this >> + * was a compound page containing certain HWPoison subpages. >> + */ >> + if (should_fhh) { >> + free_has_hwpoisoned(page, order); >> + return false; >> + } > > When the code reaches here, the hwpoisoned pages have passed through ke= rnel_poison_pages, > kasan_poison_pages, kernel_init_pages, arch_free_page... These function= s might write to > the hwpoisoned pages. Is it safe to do so? At least, kernel_poison_pages() writes to the page. It probably should be= moved up, somewhere like above kernel_poison_pages(). I do not like the shortcut method, since the pages are freed in __free_pages_prepare(). This causes confusion. One alternative I can thin= k of is to make __free_pages_prepare() returns a enum { FREE_PAGE_PREPARE_SUCCESS, FREE_PAGE_PREPARE_FAIL, FREE_PAGE_PREPARE_HA= S_HWPOISON} and handle the return value in the caller. Best Regards, Yan, Zi