From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793672128; b=fD0gaXOPKXv3ZVYgDN08tvott6xG4f4xMrThYYr/JIJP6Ci3QJ4WMhYv7hYa7stSoofB S3QxsJGqPDit4SFi8qC67uAZ4v36Q+JCWJf2dE47mUxxPCsnjxMKLzUhfdIgfqN28q1hC Amk5HX9YGTa3yFzkHDKH8BYBSGCtfFT5XbB20E9Rbt2fxaSkufJ1glXRs2Ep/5GrvBnHl wCNslnEdr0IduUrq8M8CXhBGlwhrUm2hWECnEW+fD+Vklk6BTV65k7tqQo0mIFvPm3bTw CQEKdYsHX3hhX0U2KFerLfIBkRfc1a+8ef/TqtvQevnXrc6+2RA/mg4WJ2lmpDXDduQ== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793672128; h=Received:DKIM-Signature:Date:To:From:Subject:Message-Id; bh=/dizXlwya//rUrZvDlBatSPZVLOm9hZ2fu04Ti5DfbE=; b=n37YqhM4FIaGt+U+9Lq4ZpypUcAk8lArl1T+mkb7CUOzL3pBAgpyfLyMdk8wo5t7jXoE 5PaX+bnp1g5+ZtnuTR1fur1VnG1b+ysVcWbzoqHx02uB9qKGxpDJwqjShYtA+61NQqgxe 0kV0wVr+fKehDmVb/n5cpptRlEFEW2nzDl+QjZovAmY5iD+lI9FWB1ppwFZxJwsrb3R5L Hp8UB+FiGDCNh8lcxM96wuE3RUDpO4GkJ1yVzxhImb2vNNEuaKfMEjT7SRUJS7DmSnJlb laahggMRELKrf+9kIGB5zge/f53arlAK9dO6wafdTpLxBmhlU8UVYp1f7ZU2fJxQgUA== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linux-foundation.org header.i=@linux-foundation.org header.a=rsa-sha256 header.s=korg header.b=jgCRy55g; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 23B12606A32F; Tue, 3 Nov 2026 02:15:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key, unprotected) header.d=linux-foundation.org header.i=@linux-foundation.org header.a=rsa-sha256 header.s=korg header.b=jgCRy55g Received: by smtp.kernel.org (Postfix) with ESMTPSA id B79B31F00919; Tue, 3 Nov 2026 02:15:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux-foundation.org; s=korg; t=1793672127; bh=/dizXlwya//rUrZvDlBatSPZVLOm9hZ2fu04Ti5DfbE=; h=Date:To:From:Subject; b=jgCRy55gtF96t5YTOIf1AazUhjiUq0OHMZSmnEwjd8/SBn8rRkqkCn2sHtrfmKWw5 RjPj1oVni6okBWXNkXHqMaVg3/xonvJzKIIuNmo1J3PLH2TJEp2Ty/NhZpTTfS3PUy D2K7VkmDmp8LpKk4sVPdJBs9BFbG+2ipqxkuPzTc= Date: Mon, 02 Nov 2026 18:15:27 -0800 To: mm-commits@vger.kernel.org,stable@vger.kernel.org,rppt@kernel.org, peterx@redhat.com,osalvador@suse.de,muchun.song@linux.dev,david@kernel.org, azpijr@gmail.com,lizhe.67@bytedance.com,akpm@linux-foundation.org From: Andrew Morton Subject: [merged mm-hotfixes-stable] mm-hugetlb-fix-mremap-deadlock-when-pmd-sharing-is-possible.patch removed from -mm tree Message-Id: <20261103021527.B79B31F00919@smtp.kernel.org> X-Mailing-List: stable@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list The quilt patch titled Subject: mm/hugetlb: fix mremap deadlock when PMD sharing is possible has been removed from the -mm tree. Its filename was mm-hugetlb-fix-mremap-deadlock-when-pmd-sharing-is-possible.patch This patch was dropped because it was merged into the mm-hotfixes-stable branch of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm ------------------------------------------------------ From: Li Zhe Subject: mm/hugetlb: fix mremap deadlock when PMD sharing is possible Date: Thu, 22 Oct 2026 11:45:43 +0800 move_hugetlb_page_tables() holds the mapping's i_mmap_rwsem for write while moving hugetlb PTEs. This prevents races with truncation and protects huge_pmd_unshare(), but the move loop must not call helpers that can acquire the same rwsem for read. huge_pte_alloc() can do that when the destination can use PMD sharing: it may call huge_pmd_share(), which takes i_mmap_rwsem for read while searching for a shareable PMD table. Calling it while the move path already holds i_mmap_rwsem for write can deadlock. Avoid that path for PMD-sized hugetlb mappings that can use PMD sharing. Instead of allocating or sharing the destination page table while moving, zap the source range and let the destination fault path populate or share the PMD lazily. Reuse the hugetlb unmap logic for the source-side zap by splitting the core loop out of __unmap_hugepage_range(). The wrapper keeps the existing tlb_start_vma(), tlb_end_vma() and huge_pmd_unshare_flush() behavior, while move_hugetlb_page_tables() can reuse the unmap loop with its existing mmu_gather. Link: https://lore.kernel.org/20261022034543.51226-4-lizhe.67@bytedance.com Fixes: 550a7d60bd5e ("mm, hugepages: add mremap() support for hugepage backed vma") Signed-off-by: Li Zhe Co-developed-by: David Hildenbrand (Arm) Signed-off-by: David Hildenbrand (Arm) Signed-off-by: Andrew Morton Cc: Muchun Song Cc: Oscar Salvador Cc: Peter Xu Cc: Mike Rapoport Cc: Jose A. Perez de Azpillaga Cc: --- mm/hugetlb.c | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) --- a/mm/hugetlb.c~mm-hugetlb-fix-mremap-deadlock-when-pmd-sharing-is-possible +++ a/mm/hugetlb.c @@ -137,6 +137,10 @@ static int __huge_pmd_unshare(struct mmu bool check_locks); static void hugetlb_unshare_pmds(struct vm_area_struct *vma, unsigned long start, unsigned long end, bool take_locks); +static void hugetlb_unmap_range(struct mmu_gather *tlb, + struct vm_area_struct *vma, unsigned long start, + unsigned long end, struct folio *folio, + zap_flags_t zap_flags); static struct resv_map *vma_resv_map(struct vm_area_struct *vma); static inline bool subpool_is_free(struct hugepage_subpool *spool) @@ -5227,6 +5231,8 @@ unsigned long move_hugetlb_page_tables(s for (; old_addr < old_end; old_addr += sz, new_addr += sz) { const unsigned long offset_to_last_entry = (old_addr | last_addr_mask) - old_addr; + const unsigned long offset_to_last_dst_entry = + (new_addr | last_addr_mask) - new_addr; src_pte = hugetlb_walk(vma, old_addr, sz); if (!src_pte) { @@ -5243,6 +5249,24 @@ unsigned long move_hugetlb_page_tables(s continue; } + /* + * Avoid entering the destination PMD sharing path while holding + * i_mmap_rwsem for write. Leave destination page table + * population to the fault path, which can share the PMD lazily. + */ + if (sz == PMD_SIZE && want_pmd_share(new_vma, new_addr)) { + const unsigned long unmap_size = + min(old_end - old_addr, + offset_to_last_dst_entry + sz); + + hugetlb_unmap_range(&tlb, vma, old_addr, + old_addr + unmap_size, NULL, + ZAP_FLAG_DROP_MARKER); + old_addr += unmap_size - sz; + new_addr += unmap_size - sz; + continue; + } + dst_pte = huge_pte_alloc(mm, new_vma, new_addr, sz); if (!dst_pte) break; @@ -5262,9 +5286,10 @@ unsigned long move_hugetlb_page_tables(s return len + old_addr - old_end; } -void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma, - unsigned long start, unsigned long end, - struct folio *folio, zap_flags_t zap_flags) +static void hugetlb_unmap_range(struct mmu_gather *tlb, + struct vm_area_struct *vma, unsigned long start, + unsigned long end, struct folio *folio, + zap_flags_t zap_flags) { struct mm_struct *mm = vma->vm_mm; const bool folio_provided = !!folio; @@ -5282,13 +5307,6 @@ void __unmap_hugepage_range(struct mmu_g BUG_ON(start & ~huge_page_mask(h)); BUG_ON(end & ~huge_page_mask(h)); - /* - * This is a hugetlb vma, all the pte entries should point - * to huge page. - */ - tlb_change_page_size(tlb, sz); - tlb_start_vma(tlb, vma); - last_addr_mask = hugetlb_mask_last_page(h); address = start; for (; address < end; address += sz) { @@ -5417,6 +5435,15 @@ void __unmap_hugepage_range(struct mmu_g if (folio_provided) break; } +} + +void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma, + unsigned long start, unsigned long end, + struct folio *folio, zap_flags_t zap_flags) +{ + tlb_change_page_size(tlb, huge_page_size(hstate_vma(vma))); + tlb_start_vma(tlb, vma); + hugetlb_unmap_range(tlb, vma, start, end, folio, zap_flags); tlb_end_vma(tlb, vma); huge_pmd_unshare_flush(tlb, vma); _ Patches currently in -mm which might be from lizhe.67@bytedance.com are