From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from MW6PR02CU001.outbound.protection.outlook.com (mail-westus2azon11012001.outbound.protection.outlook.com [52.101.48.1]) (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 381C82561A7 for ; Sun, 12 Jul 2026 07:41:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=52.101.48.1 ARC-Seal:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783842100; cv=fail; b=W3LG8xq6ae6P73zhh08N9mXpa2sl0mVVbYPS41VtZYranIUYdXsBac10seafQ5Ff1pp6RquCyBsBj9Oin0+QA17AgaDf+z2TK31hkyT79DgHIIiouqOPQg15Nc1GPTpCUSoRoL1Ay3PUVet098RdPpQqLNkQHT25SFtBCTQJXOQ= ARC-Message-Signature:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783842100; c=relaxed/simple; bh=kA4wEi7ppwGHQEuijqPdO/498Z6da5jU8Oyz0X6nkYA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-ID:References: In-Reply-To:To:CC; b=tNyWq1ePajfe7q5bdblh+ltIPRONzKxi2xokiK6gsNE3LTPjRFG4vd6/yOPkUxxeldip9IPZwDSfUTK9akznzh1/lUZElABaxMbX1YpvGrTQfrEtYEjQqh/Ziau+cMUh4h3cWWmhbdzB1t15NqDiKJRqAKtDcw8Cy/JZmr1PdKE= ARC-Authentication-Results:i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=QC3cKXF/; arc=fail smtp.client-ip=52.101.48.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="QC3cKXF/" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=DG5+NymSfOAZqOIhijvwMu0eBN1WZAvciLgZda/R//sxwml/oKBHlC8Azle9dVRdAzkGOPRVZy8mrjkZ8Krk1G4F+HDdhxiQwpatl2T7bHz/Wc/MjibnthetFwMDvywFKF48/V4lFNnZRMGK/FwMENhKIRagmH0RmpyHbNKty3wZqHYGy1heNQvJu9UiBjBWsCrKLwOkWJmESeKdc6uLNH3u+OI+Ct9lLJkbey6jBvIsP7XSU4MFddotpEdLzLoBTYfSw3pqMXUAWElkzjdSQfSX0Ra/lNdLEZy/4CR8iipZtiZr+JJjnQ2TmTAIKqUchohQLnjrcl9njoLKggTdlg== 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=cDRb3q89wfKwwC3j/8iU8EEJ2BM5C0f3qSFbGzDevzI=; b=Phu/lXdfaT78VG9MpwAnXopPZaZpBhFr+6n7Etmxj6iMVEuNFLGm/mybn7NFmzf7gf3Wc/ERik5DMp8L7YAYZrdS+JtOzUjXFmDsWw6z8lc28zb1c6+RKa1AhpJD6aIrxCGpQe4YnnPlPg5/89pAHsd5ZulkRkI9f4DaPh2jjyFhY7L4plCrJsC1Xhb+TU/Ox6jNiQngVLGQGxKQp6/W+bj07QHzWdcioejLJ3+LPEqdnLe3oCdDfoD7UtlArm9h/WBBR4UNgE043g+Niql2tRImHFNlk3Trh56NLlshDOGtTzh/UwzCAJeFgKT7ecnePPpVueOp8q2DMciFZZJiTQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=google.com smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=cDRb3q89wfKwwC3j/8iU8EEJ2BM5C0f3qSFbGzDevzI=; b=QC3cKXF/NIfrN8g2Mf+V0CYMwuDFN6PW/UO+9LK3Od12p64xwJOUGAT9M3YNP0v/7tq2iFSqA+HhVMQi3XE6kkM6t6a/Pu7JAzecP0JM/klbZeb6iE+Odu8MrWnw3WkCZ5K9hWIG4pDfq7aN+A1Cp5cZszD7SBPabFgGkYehxos= Received: from MN2PR05CA0057.namprd05.prod.outlook.com (2603:10b6:208:236::26) by CH8PR12MB9742.namprd12.prod.outlook.com (2603:10b6:610:27a::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.181.19; Sun, 12 Jul 2026 07:41:30 +0000 Received: from BL02EPF0001A105.namprd05.prod.outlook.com (2603:10b6:208:236:cafe::98) by MN2PR05CA0057.outlook.office365.com (2603:10b6:208:236::26) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.223.9 via Frontend Transport; Sun, 12 Jul 2026 07:41:30 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb07.amd.com; pr=C Received: from satlexmb07.amd.com (165.204.84.17) by BL02EPF0001A105.mail.protection.outlook.com (10.167.241.137) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.202.18 via Frontend Transport; Sun, 12 Jul 2026 07:41:30 +0000 Received: from [127.0.1.1] (10.180.168.240) by satlexmb07.amd.com (10.181.42.216) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.41; Sun, 12 Jul 2026 02:41:20 -0500 From: Shivank Garg Date: Sun, 12 Jul 2026 07:38:51 +0000 Subject: [PATCH 5/6] mm/rmap: split try_to_migrate_hugetlb_one() out of try_to_migrate_one() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-ID: <20260712-migrate-rmap-batch-v1-5-872a734431d1@amd.com> References: <20260712-migrate-rmap-batch-v1-0-872a734431d1@amd.com> In-Reply-To: <20260712-migrate-rmap-batch-v1-0-872a734431d1@amd.com> To: Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Rik van Riel , "Liam R. Howlett" , Vlastimil Babka , Harry Yoo , Jann Horn , Lance Yang , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , Zi Yan , Matthew Brost , Joshua Hahn , Rakie Kim , Byungchul Park , Gregory Price , Ying Huang , "Alistair Popple" CC: Karim Manaouil , Frank van der Linden , Kinsey Ho , Wei Xu , Bharata B Rao , David Rientjes , Dev Jain , , , Shivank Garg X-Mailer: b4 0.15-dev-47d62 X-Developer-Signature: v=1; a=ed25519-sha256; t=1783842044; l=15491; i=shivankg@amd.com; s=20260518; h=from:subject:message-id; bh=kA4wEi7ppwGHQEuijqPdO/498Z6da5jU8Oyz0X6nkYA=; b=wRbrjbzqlIzHpuSnUEX/BHkdBXd/1TmBTOLV+WXvAfZ4v2sAJMMSDeDmqZXWa+e86rAx6FTaH ZD+wh8TX4aDCKLKdNxD+ZpNskRh8q2QAgydafmhrfjVI/Rg+isnacUS X-Developer-Key: i=shivankg@amd.com; a=ed25519; pk=2l2QGTeXuGkZTtfmx0nPQU8iFZfjYmX/ymMojitevx4= X-ClientProxiedBy: satlexmb07.amd.com (10.181.42.216) To satlexmb07.amd.com (10.181.42.216) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BL02EPF0001A105:EE_|CH8PR12MB9742:EE_ X-MS-Office365-Filtering-Correlation-Id: 23912fd4-225b-4b49-3674-08dedfe8fcef X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|36860700016|376014|7416014|23010399003|1800799024|82310400026|921020|56012099006|11063799006|18002099003|22082099003; X-Microsoft-Antispam-Message-Info: ykaes4BDVlA2bRg/Ouxss2zWlINkBI/y1+8tPp+AddwNiogQNi0uZXhy3V2aPOwUNlxBZXj2NZu73eWxIY/sfhCQL/KhGS1pAMq/8NN0EswiVcCysofm5R+cuOaTxS5lLYVUfrBxecwwsZS1sHA9FgvONk6pdirqaGU6AM00+5VRoAkP9sFbFgEatJ530XZKFKxCx3QxISNSNn4k00IqWxMcAcQpX22II0RM3pWaXACP42H7UR2a5ejdNvITpXTmYjKDTWPYIn5wt7Q1PZ8TjJwfWyPbRcBVxJHI6unRFUZt+nS1EcBun+nwgYo5mlvYuL9FnSN4BrhjnmvVTfUxt0G+fgK5WHZ1cKdjoN+xtEZoyG8fSINuyjMVaiI3lJcUrIWjZvYbD2t6k8LHK9kCFpiiwYKuhR92VRvXl8srJQXiS5+bJ+G1UduoPnZyJ+stnKblgFQOJDEV4hltNO2NdEW42hN4Y0htINlapiJPafv3MyPCrTxPFyUl88IiDwXNEiPjwF1+hVbQiqMRRBBde7f6KpjlH21VEUKAF8VIV5ttyRYcvTnA79fnswu1gKQFF9195nR/IMcEXKid2cYohmmfYZ+GS8GyWjrZxIcN7DcU5tr+Jh6gYpT2zGtdxiNNcqu/EFGL8I+Q+zsTFOYeFOd3Mr1oJ+u5YyjKOOrbvz4y9Gm4gBZFo7/+rmISi/GZPdar75RRmaZ2IRmYz44YP0upWVocz58lzhAOaGpdZ23gCmI0Bojn0HvrU13CnCjK X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb07.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(36860700016)(376014)(7416014)(23010399003)(1800799024)(82310400026)(921020)(56012099006)(11063799006)(18002099003)(22082099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: DR+BKDQbUnmNlQuJ9S9NqwLPpYdimRT+BQcnfKopY71oLxWfxYsC0YkCyqWlfcTDP6E9iLxIsL2rIUBSN7J48cEx//3k8KrRThbPzICOoBPT6bg7detC+ou0J2uwQ9EWCQQxIwC+CiDIZ1FBP1miFokR0xBkW9euNTOHRxwjig8FcnGaOUOPmBpMKuvoSc0/dgeKROrn+GMIqwofbdQiLarxrplI7ynz1F3mtQMtHeHv4IiB30exUnCxTchGak2MIXdfTv7FrqvP7FKEUot2ycfdhTG87qc+gxQeLamjIr1FafqEofMtNiSRAtSgaLmIxWQxMc+jWe6tKXUtLIrdPcnS1B8cw+atHuw/gTAOqj4sjPbdmJXKBXCmXyUMgzO8EQJjW+Rzf5Q9dj24Cp2TmdKhpytVQnDjcTjtHZVvf6OFoYwdCK3MKnEdvoDSJy8E X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Jul 2026 07:41:30.1765 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 23912fd4-225b-4b49-3674-08dedfe8fcef X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb07.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BL02EPF0001A105.namprd05.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH8PR12MB9742 try_to_migrate_one() interleaves hugetlb special handling through the regular PTE/PMD migration path with folio_test_hugetlb() checks scattered across the walk. Simplify this by moving hugetlb handling into its own rmap_one callback, try_to_migrate_hugetlb_one(). Factor the migration swap-pte construction shared by both hugetlb and regular folios path into make_migration_swp_pte(). Few minor changes: - Since hugetlb uses separate counters, update_hiwater_rss() is not needed for hugetlb path. Also, use huge_pte_dirty instead of pte_dirty - No PVMW_SYNC flag is needed for hugetlb - hugetlb folio has single mapping per VMA, so no loop is needed. - Convert VM_BUG_ON to VM_WARN_ON_ONCE and not use irrelevant WARN check. Signed-off-by: Shivank Garg --- mm/rmap.c | 329 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 195 insertions(+), 134 deletions(-) diff --git a/mm/rmap.c b/mm/rmap.c index e854679553b9..ef68adba89c4 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -2405,6 +2405,187 @@ void try_to_unmap(struct folio *folio, enum ttu_flags flags) rmap_walk(folio, &rwc); } +/* Build the migration swap PTE that replaces pteval for a page. */ +static pte_t make_migration_swp_pte(struct page *page, pte_t pteval, + bool writable, bool anon_exclusive) +{ + swp_entry_t entry; + pte_t swp_pte; + + if (writable) + entry = make_writable_migration_entry(page_to_pfn(page)); + else if (anon_exclusive) + entry = make_readable_exclusive_migration_entry( + page_to_pfn(page)); + else + entry = make_readable_migration_entry(page_to_pfn(page)); + + if (likely(pte_present(pteval))) { + if (pte_young(pteval)) + entry = make_migration_entry_young(entry); + if (pte_dirty(pteval)) + entry = make_migration_entry_dirty(entry); + swp_pte = swp_entry_to_pte(entry); + if (pte_soft_dirty(pteval)) + swp_pte = pte_swp_mksoft_dirty(swp_pte); + if (pte_uffd(pteval)) + swp_pte = pte_swp_mkuffd(swp_pte); + } else { + swp_pte = swp_entry_to_pte(entry); + if (pte_swp_soft_dirty(pteval)) + swp_pte = pte_swp_mksoft_dirty(swp_pte); + if (pte_swp_uffd(pteval)) + swp_pte = pte_swp_mkuffd(swp_pte); + } + + return swp_pte; +} + +/* + * Replace the hugetlb page table mapping for folio with migration entries. + * + * @arg: enum ttu_flags will be passed to this argument. + */ +static bool try_to_migrate_hugetlb_one(struct folio *folio, + struct vm_area_struct *vma, unsigned long address, void *arg) +{ + const unsigned long hsz = huge_page_size(hstate_vma(vma)); + DEFINE_FOLIO_VMA_WALK(pvmw, folio, vma, address, 0); + enum ttu_flags flags = (enum ttu_flags)(long)arg; + bool anon_exclusive, writable, ret = true; + bool anon = folio_test_anon(folio); + struct mm_struct *mm = vma->vm_mm; + struct mmu_notifier_range range; + unsigned long pfn; + struct page *page; + pte_t pteval; + + range.end = vma_address_end(&pvmw); + mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma->vm_mm, + address, range.end); + /* If sharing is possible, start and end will be adjusted accordingly. */ + adjust_range_if_pmd_sharing_possible(vma, &range.start, &range.end); + mmu_notifier_invalidate_range_start(&range); + + if (page_vma_mapped_walk(&pvmw)) { + address = pvmw.address; + pteval = huge_ptep_get(mm, address, pvmw.pte); + if (likely(pte_present(pteval))) + pfn = pte_pfn(pteval); + else + pfn = softleaf_to_pfn(softleaf_from_pte(pteval)); + + page = folio_page(folio, pfn - folio_pfn(folio)); + anon_exclusive = anon && PageAnonExclusive(page); + + /* + * huge_pmd_unshare may unmap an entire PMD page. There is no + * way of knowing exactly which PMDs may be cached for this mm, + * so we must flush them all. start/end were already adjusted + * above to cover this range. + */ + flush_cache_range(vma, range.start, range.end); + + /* + * To call huge_pmd_unshare, i_mmap_rwsem must be held in write + * mode. Caller needs to explicitly do this outside rmap + * routines. We also must hold hugetlb vma_lock in write mode. + * Lock order dictates acquiring vma_lock BEFORE i_mmap_rwsem. + * We can only try lock here and fail if unsuccessful. + */ + if (!anon) { + struct mmu_gather tlb; + + VM_WARN_ON_ONCE(!(flags & TTU_RMAP_LOCKED)); + if (!hugetlb_vma_trylock_write(vma)) { + ret = false; + goto walk_done; + } + + tlb_gather_mmu_vma(&tlb, vma); + if (huge_pmd_unshare(&tlb, vma, address, pvmw.pte)) { + hugetlb_vma_unlock_write(vma); + huge_pmd_unshare_flush(&tlb, vma); + tlb_finish_mmu(&tlb); + /* + * The PMD table was unmapped, + * consequently unmapping the folio. + */ + goto walk_done; + } + hugetlb_vma_unlock_write(vma); + tlb_finish_mmu(&tlb); + } + + /* Nuke the hugetlb page table entry */ + pteval = huge_ptep_clear_flush(vma, address, pvmw.pte); + if (huge_pte_dirty(pteval)) + folio_mark_dirty(folio); + writable = pte_write(pteval); + + VM_WARN_ON_FOLIO(writable && anon && !anon_exclusive, folio); + + if (PageHWPoison(page)) { + pteval = swp_entry_to_pte(make_hwpoison_entry(page)); + hugetlb_count_sub(folio_nr_pages(folio), mm); + set_huge_pte_at(mm, address, pvmw.pte, pteval, hsz); + } else if (likely(pte_present(pteval)) && pte_unused(pteval) && + !userfaultfd_armed(vma)) { + /* + * The guest indicated that the page content is of no + * interest anymore. Simply discard the pte, vmscan + * will take care of the rest. + */ + dec_mm_counter(mm, mm_counter(folio)); + } else { + pte_t swp_pte; + + /* + * arch_unmap_one() is expected to be a NOP on + * architectures where we could have PFN swap PTEs, + * so we'll not check/care. + */ + if (arch_unmap_one(mm, vma, address, pteval) < 0) { + set_huge_pte_at(mm, address, pvmw.pte, + pteval, hsz); + ret = false; + goto walk_done; + } + + /* See folio_try_share_anon_rmap_pte(): clear PTE first. */ + if (anon_exclusive && + hugetlb_try_share_anon_rmap(folio)) { + set_huge_pte_at(mm, address, pvmw.pte, + pteval, hsz); + ret = false; + goto walk_done; + } + + /* + * Store the pfn of the page in a special migration + * pte. do_swap_page() will wait until the migration + * pte is removed and then restart fault handling. + */ + swp_pte = make_migration_swp_pte(page, pteval, + writable, anon_exclusive); + set_huge_pte_at(mm, address, pvmw.pte, swp_pte, hsz); + trace_set_migration_pte(address, pte_val(swp_pte), + folio_order(folio)); + } + + hugetlb_remove_rmap(folio); + if (vma->vm_flags & VM_LOCKED) + mlock_drain_local(); + folio_put(folio); +walk_done: + page_vma_mapped_walk_done(&pvmw); + } + + mmu_notifier_invalidate_range_end(&range); + + return ret; +} + /* * @arg: enum ttu_flags will be passed to this argument. * @@ -2422,7 +2603,6 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, struct mmu_notifier_range range; enum ttu_flags flags = (enum ttu_flags)(long)arg; unsigned long pfn; - unsigned long hsz = 0; /* * When racing against e.g. zap_pte_range() on another cpu, @@ -2435,26 +2615,13 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, /* * For THP, we have to assume the worse case ie pmd for invalidation. - * For hugetlb, it could be much worse if we need to do pud - * invalidation in the case of pmd sharing. * * Note that the page can not be free in this function as call of - * try_to_unmap() must hold a reference on the page. + * try_to_migrate() must hold a reference on the page. */ range.end = vma_address_end(&pvmw); mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma->vm_mm, address, range.end); - if (folio_test_hugetlb(folio)) { - /* - * If sharing is possible, start and end will be adjusted - * accordingly. - */ - adjust_range_if_pmd_sharing_possible(vma, &range.start, - &range.end); - - /* We need the huge page size for set_huge_pte_at() */ - hsz = huge_page_size(hstate_vma(vma)); - } mmu_notifier_invalidate_range_start(&range); while (page_vma_mapped_walk(&pvmw)) { @@ -2501,10 +2668,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, VM_BUG_ON_FOLIO(!pvmw.pte, folio); address = pvmw.address; - if (folio_test_hugetlb(folio)) - pteval = huge_ptep_get(mm, address, pvmw.pte); - else - pteval = ptep_get(pvmw.pte); + pteval = ptep_get(pvmw.pte); if (likely(pte_present(pteval))) { pfn = pte_pfn(pteval); } else { @@ -2515,66 +2679,13 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, const softleaf_t entry = softleaf_from_pte(pteval); pfn = softleaf_to_pfn(entry); - VM_WARN_ON_FOLIO(folio_test_hugetlb(folio), folio); } subpage = folio_page(folio, pfn - folio_pfn(folio)); anon_exclusive = folio_test_anon(folio) && PageAnonExclusive(subpage); - if (folio_test_hugetlb(folio)) { - bool anon = folio_test_anon(folio); - - /* - * huge_pmd_unshare may unmap an entire PMD page. - * There is no way of knowing exactly which PMDs may - * be cached for this mm, so we must flush them all. - * start/end were already adjusted above to cover this - * range. - */ - flush_cache_range(vma, range.start, range.end); - - /* - * To call huge_pmd_unshare, i_mmap_rwsem must be - * held in write mode. Caller needs to explicitly - * do this outside rmap routines. - * - * We also must hold hugetlb vma_lock in write mode. - * Lock order dictates acquiring vma_lock BEFORE - * i_mmap_rwsem. We can only try lock here and - * fail if unsuccessful. - */ - if (!anon) { - struct mmu_gather tlb; - - VM_BUG_ON(!(flags & TTU_RMAP_LOCKED)); - if (!hugetlb_vma_trylock_write(vma)) { - page_vma_mapped_walk_done(&pvmw); - ret = false; - break; - } - - tlb_gather_mmu_vma(&tlb, vma); - if (huge_pmd_unshare(&tlb, vma, address, pvmw.pte)) { - hugetlb_vma_unlock_write(vma); - huge_pmd_unshare_flush(&tlb, vma); - tlb_finish_mmu(&tlb); - /* - * The PMD table was unmapped, - * consequently unmapping the folio. - */ - page_vma_mapped_walk_done(&pvmw); - break; - } - hugetlb_vma_unlock_write(vma); - tlb_finish_mmu(&tlb); - } - /* Nuke the hugetlb page table entry */ - pteval = huge_ptep_clear_flush(vma, address, pvmw.pte); - if (pte_dirty(pteval)) - folio_mark_dirty(folio); - writable = pte_write(pteval); - } else if (likely(pte_present(pteval))) { + if (likely(pte_present(pteval))) { flush_cache_page(vma, address, pfn); /* Nuke the page table entry. */ if (should_defer_flush(mm, flags)) { @@ -2613,14 +2724,8 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, VM_WARN_ON_FOLIO(folio_is_device_private(folio), folio); pteval = swp_entry_to_pte(make_hwpoison_entry(subpage)); - if (folio_test_hugetlb(folio)) { - hugetlb_count_sub(folio_nr_pages(folio), mm); - set_huge_pte_at(mm, address, pvmw.pte, pteval, - hsz); - } else { - dec_mm_counter(mm, mm_counter(folio)); - set_pte_at(mm, address, pvmw.pte, pteval); - } + dec_mm_counter(mm, mm_counter(folio)); + set_pte_at(mm, address, pvmw.pte, pteval); } else if (likely(pte_present(pteval)) && pte_unused(pteval) && !userfaultfd_armed(vma)) { /* @@ -2635,7 +2740,6 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, */ dec_mm_counter(mm, mm_counter(folio)); } else { - swp_entry_t entry; pte_t swp_pte; /* @@ -2644,28 +2748,15 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, * so we'll not check/care. */ if (arch_unmap_one(mm, vma, address, pteval) < 0) { - if (folio_test_hugetlb(folio)) - set_huge_pte_at(mm, address, pvmw.pte, - pteval, hsz); - else - set_pte_at(mm, address, pvmw.pte, pteval); + set_pte_at(mm, address, pvmw.pte, pteval); ret = false; page_vma_mapped_walk_done(&pvmw); break; } /* See folio_try_share_anon_rmap_pte(): clear PTE first. */ - if (folio_test_hugetlb(folio)) { - if (anon_exclusive && - hugetlb_try_share_anon_rmap(folio)) { - set_huge_pte_at(mm, address, pvmw.pte, - pteval, hsz); - ret = false; - page_vma_mapped_walk_done(&pvmw); - break; - } - } else if (anon_exclusive && - folio_try_share_anon_rmap_pte(folio, subpage)) { + if (anon_exclusive && + folio_try_share_anon_rmap_pte(folio, subpage)) { set_pte_at(mm, address, pvmw.pte, pteval); ret = false; page_vma_mapped_walk_done(&pvmw); @@ -2677,37 +2768,9 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, * pte. do_swap_page() will wait until the migration * pte is removed and then restart fault handling. */ - if (writable) - entry = make_writable_migration_entry( - page_to_pfn(subpage)); - else if (anon_exclusive) - entry = make_readable_exclusive_migration_entry( - page_to_pfn(subpage)); - else - entry = make_readable_migration_entry( - page_to_pfn(subpage)); - if (likely(pte_present(pteval))) { - if (pte_young(pteval)) - entry = make_migration_entry_young(entry); - if (pte_dirty(pteval)) - entry = make_migration_entry_dirty(entry); - swp_pte = swp_entry_to_pte(entry); - if (pte_soft_dirty(pteval)) - swp_pte = pte_swp_mksoft_dirty(swp_pte); - if (pte_uffd(pteval)) - swp_pte = pte_swp_mkuffd(swp_pte); - } else { - swp_pte = swp_entry_to_pte(entry); - if (pte_swp_soft_dirty(pteval)) - swp_pte = pte_swp_mksoft_dirty(swp_pte); - if (pte_swp_uffd(pteval)) - swp_pte = pte_swp_mkuffd(swp_pte); - } - if (folio_test_hugetlb(folio)) - set_huge_pte_at(mm, address, pvmw.pte, swp_pte, - hsz); - else - set_pte_at(mm, address, pvmw.pte, swp_pte); + swp_pte = make_migration_swp_pte(subpage, pteval, + writable, anon_exclusive); + set_pte_at(mm, address, pvmw.pte, swp_pte); trace_set_migration_pte(address, pte_val(swp_pte), folio_order(folio)); /* @@ -2716,10 +2779,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, */ } - if (unlikely(folio_test_hugetlb(folio))) - hugetlb_remove_rmap(folio); - else - folio_remove_rmap_pte(folio, subpage, vma); + folio_remove_rmap_pte(folio, subpage, vma); if (vma->vm_flags & VM_LOCKED) mlock_drain_local(); folio_put(folio); @@ -2741,7 +2801,8 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, void try_to_migrate(struct folio *folio, enum ttu_flags flags) { struct rmap_walk_control rwc = { - .rmap_one = try_to_migrate_one, + .rmap_one = folio_test_hugetlb(folio) ? + try_to_migrate_hugetlb_one : try_to_migrate_one, .arg = (void *)flags, .done = folio_not_mapped, .anon_lock = folio_lock_anon_vma_read, -- 2.43.0