mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] mm/memory: fix hugetlb_zap_begin() call in zap_vma_range_batched()
@ 2026-09-04  0:00 SJ Park
  2026-09-04  0:06 ` SJ Park
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: SJ Park @ 2026-09-04  0:00 UTC (permalink / raw)
  To: Andrew Morton
  Cc: SJ Park, Liam R. Howlett, David Hildenbrand, Lorenzo Stoakes,
	Michal Hocko, Mike Rapoport, Suren Baghdasaryan, Vlastimil Babka,
	linux-kernel, linux-mm

Commit f1fc44daf618 ("mm/hugetlb: don't lock private resv_map during
final unmap") added zap_details parameter to hugetlb_zap_begin().  But
the hugetlb_zap_begin() call in zap_vma_range_batched() is not updated.
As a result, build fails as below.  Fix it.

  CC      mm/memory.o
.../mm/memory.c: In function ‘zap_vma_range_batched’:
.../mm/memory.c:2308:9: error: too few arguments to function ‘hugetlb_zap_begin’
 2308 |         hugetlb_zap_begin(vma, &range.start, &range.end);
      |         ^~~~~~~~~~~~~~~~~
In file included from .../mm/memory.c:48:
.../include/linux/hugetlb.h:253:20: note: declared here
  253 | static inline void hugetlb_zap_begin(struct vm_area_struct *vma,
      |                    ^~~~~~~~~~~~~~~~~

/* TODO: move below to commentary */

I didn't read the broken commit in depth.  This fix is only
build-tested.  I wanted to report the issue with this as a temporal fix,
but the broken commit doesn't have Link: tag.  So directly posting this
temporal and not very well verified fix first.

Fixes: Fixes: f1fc44daf618 ("mm/hugetlb: don't lock private resv_map during final unmap")
Signed-off-by: SJ Park <sj@kernel.org>
---
 mm/memory.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/memory.c b/mm/memory.c
index fcf893f4b55e2..151a1bf512e00 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2305,7 +2305,7 @@ void zap_vma_range_batched(struct mmu_gather *tlb,
 
 	mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma->vm_mm,
 				address, end);
-	hugetlb_zap_begin(vma, &range.start, &range.end);
+	hugetlb_zap_begin(vma, &range.start, &range.end, details);
 	update_hiwater_rss(vma->vm_mm);
 	mmu_notifier_invalidate_range_start(&range);
 	/*

base-commit: 2d1388907095f676b59fe6dd22f244abc08408cf
-- 
2.47.3

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] mm/memory: fix hugetlb_zap_begin() call in zap_vma_range_batched()
  2026-09-04  0:00 [PATCH] mm/memory: fix hugetlb_zap_begin() call in zap_vma_range_batched() SJ Park
@ 2026-09-04  0:06 ` SJ Park
  2026-09-04  0:22 ` SJ Park
  2026-09-04  0:35 ` Andrew Morton
  2 siblings, 0 replies; 8+ messages in thread
From: SJ Park @ 2026-09-04  0:06 UTC (permalink / raw)
  To: SJ Park
  Cc: Andrew Morton, Liam R. Howlett, David Hildenbrand,
	Lorenzo Stoakes, Michal Hocko, Mike Rapoport, Suren Baghdasaryan,
	Vlastimil Babka, linux-kernel, linux-mm

On Thu,  3 Sep 2026 17:00:26 -0700 SJ Park <sj@kernel.org> wrote:

> Commit f1fc44daf618 ("mm/hugetlb: don't lock private resv_map during
> final unmap")

FYI, this commit is in only mm-new.

> added zap_details parameter to hugetlb_zap_begin().  But
> the hugetlb_zap_begin() call in zap_vma_range_batched() is not updated.
> As a result, build fails as below.  Fix it.
> 
>   CC      mm/memory.o
> .../mm/memory.c: In function ‘zap_vma_range_batched’:
> .../mm/memory.c:2308:9: error: too few arguments to function ‘hugetlb_zap_begin’
>  2308 |         hugetlb_zap_begin(vma, &range.start, &range.end);
>       |         ^~~~~~~~~~~~~~~~~
> In file included from .../mm/memory.c:48:
> .../include/linux/hugetlb.h:253:20: note: declared here
>   253 | static inline void hugetlb_zap_begin(struct vm_area_struct *vma,
>       |                    ^~~~~~~~~~~~~~~~~
> 
> /* TODO: move below to commentary */

Oops, somehow my tool didn't process this...  Sorry for noise.


Thanks,
SJ

[...]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] mm/memory: fix hugetlb_zap_begin() call in zap_vma_range_batched()
  2026-09-04  0:00 [PATCH] mm/memory: fix hugetlb_zap_begin() call in zap_vma_range_batched() SJ Park
  2026-09-04  0:06 ` SJ Park
@ 2026-09-04  0:22 ` SJ Park
  2026-09-04  0:35 ` Andrew Morton
  2 siblings, 0 replies; 8+ messages in thread
From: SJ Park @ 2026-09-04  0:22 UTC (permalink / raw)
  To: SJ Park
  Cc: Andrew Morton, Liam R. Howlett, David Hildenbrand,
	Lorenzo Stoakes, Michal Hocko, Mike Rapoport, Suren Baghdasaryan,
	Vlastimil Babka, linux-kernel, linux-mm, Muchun Song,
	Oscar Salvador

On Thu,  3 Sep 2026 17:00:26 -0700 SJ Park <sj@kernel.org> wrote:

> Commit f1fc44daf618 ("mm/hugetlb: don't lock private resv_map during
> final unmap") added zap_details parameter to hugetlb_zap_begin().  But
> the hugetlb_zap_begin() call in zap_vma_range_batched() is not updated.
> As a result, build fails as below.  Fix it.
> 
>   CC      mm/memory.o
> .../mm/memory.c: In function ‘zap_vma_range_batched’:
> .../mm/memory.c:2308:9: error: too few arguments to function ‘hugetlb_zap_begin’
>  2308 |         hugetlb_zap_begin(vma, &range.start, &range.end);
>       |         ^~~~~~~~~~~~~~~~~
> In file included from .../mm/memory.c:48:
> .../include/linux/hugetlb.h:253:20: note: declared here
>   253 | static inline void hugetlb_zap_begin(struct vm_area_struct *vma,
>       |                    ^~~~~~~~~~~~~~~~~
> 
> /* TODO: move below to commentary */
> 
> I didn't read the broken commit in depth.  This fix is only
> build-tested.  I wanted to report the issue with this as a temporal fix,
> but the broken commit doesn't have Link: tag.  So directly posting this
> temporal and not very well verified fix first.
> 
> Fixes: Fixes: f1fc44daf618 ("mm/hugetlb: don't lock private resv_map during final unmap")
> Signed-off-by: SJ Park <sj@kernel.org>
> ---
>  mm/memory.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/mm/memory.c b/mm/memory.c
> index fcf893f4b55e2..151a1bf512e00 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -2305,7 +2305,7 @@ void zap_vma_range_batched(struct mmu_gather *tlb,
>  
>  	mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma->vm_mm,
>  				address, end);
> -	hugetlb_zap_begin(vma, &range.start, &range.end);
> +	hugetlb_zap_begin(vma, &range.start, &range.end, details);
>  	update_hiwater_rss(vma->vm_mm);
>  	mmu_notifier_invalidate_range_start(&range);
>  	/*

And this is not enough for some configs.

# /home/lkhack/linux/mm/memory.c: In function 'unmap_vmas':
# /home/lkhack/linux/mm/memory.c:2272:3: error: too many arguments to function 'hugetlb_zap_begin'
#  2272 |   hugetlb_zap_begin(vma, &start, &end, &details);
#       |   ^~~~~~~~~~~~~~~~~
# In file included from /home/lkhack/linux/mm/memory.c:48:
# /home/lkhack/linux/include/linux/hugetlb.h:322:20: note: declared here
#   322 | static inline void hugetlb_zap_begin(

Below change fixes the build on the config, too.

'''
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 63c85f2540c9f..0cdccafb83983 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -321,7 +321,8 @@ static inline void adjust_range_if_pmd_sharing_possible(

 static inline void hugetlb_zap_begin(
                                struct vm_area_struct *vma,
-                               unsigned long *start, unsigned long *end)
+                               unsigned long *start, unsigned long *end,
+                               struct zap_details *details)
 {
 }

'''

So more complete version of the patch would look like below.  Forgive me
posting v2 as a reply for this case.  I think this doesn't deserve a new
thread.


Thanks,
SJ

=== >8 ===
From hackermail Thu Jan  1 00:00:00 1970
From: SJ Park <sj@kernel.org>
Date: Thu, 3 Sep 2026 16:52:06 -0700
Subject: [PATCH v2] mm/memory: fix hugetlb_zap_begin() call in zap_vma_range_batched()
To: Andrew Morton <akpm@linux-foundation.org>
Cc: "Liam R. Howlett" <liam@infradead.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-mm@kvack.org

Commit f1fc44daf618 ("mm/hugetlb: don't lock private resv_map during
final unmap") added zap_details parameter to hugetlb_zap_begin().  But
the hugetlb_zap_begin() call in zap_vma_range_batched() is not updated.
As a result, build fails as below.

  CC      mm/memory.o
.../mm/memory.c: In function ‘zap_vma_range_batched’:
.../mm/memory.c:2308:9: error: too few arguments to function ‘hugetlb_zap_begin’
 2308 |         hugetlb_zap_begin(vma, &range.start, &range.end);
      |         ^~~~~~~~~~~~~~~~~
In file included from .../mm/memory.c:48:
.../include/linux/hugetlb.h:253:20: note: declared here
  253 | static inline void hugetlb_zap_begin(struct vm_area_struct *vma,
      |                    ^~~~~~~~~~~~~~~~~

It also fails on !CONFIG_HUGETLB_PAGE config.

    .../mm/memory.c: In function 'unmap_vmas':
    .../mm/memory.c:2272:3: error: too many arguments to function 'hugetlb_zap_begin'
     2272 |   hugetlb_zap_begin(vma, &start, &end, &details);
          |   ^~~~~~~~~~~~~~~~~
    In file included from .../mm/memory.c:48:
    .../include/linux/hugetlb.h:322:20: note: declared here
     322 | static inline void hugetlb_zap_begin(

Fixes: Fixes: f1fc44daf618 ("mm/hugetlb: don't lock private resv_map during final unmap")
Signed-off-by: SJ Park <sj@kernel.org>
---
I didn't read the broken commit in depth.  This fix is only
build-tested.  I wanted to report the issue with this as a temporal fix,
but the broken commit doesn't have Link: tag.  So directly posting this
temporal and not very well verified fix first.

Changes from v1
- v1: https://lore.kernel.org/20260904000028.149656-1-sj@kernel.org
- Fix !CONFIG_HUGETLB_PAGE build.

 include/linux/hugetlb.h | 3 ++-
 mm/memory.c             | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 63c85f2540c9f..0cdccafb83983 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -321,7 +321,8 @@ static inline void adjust_range_if_pmd_sharing_possible(
 
 static inline void hugetlb_zap_begin(
 				struct vm_area_struct *vma,
-				unsigned long *start, unsigned long *end)
+				unsigned long *start, unsigned long *end,
+				struct zap_details *details)
 {
 }
 
diff --git a/mm/memory.c b/mm/memory.c
index fcf893f4b55e2..151a1bf512e00 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2305,7 +2305,7 @@ void zap_vma_range_batched(struct mmu_gather *tlb,
 
 	mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma->vm_mm,
 				address, end);
-	hugetlb_zap_begin(vma, &range.start, &range.end);
+	hugetlb_zap_begin(vma, &range.start, &range.end, details);
 	update_hiwater_rss(vma->vm_mm);
 	mmu_notifier_invalidate_range_start(&range);
 	/*

base-commit: 2d1388907095f676b59fe6dd22f244abc08408cf
-- 
2.47.3

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] mm/memory: fix hugetlb_zap_begin() call in zap_vma_range_batched()
  2026-09-04  0:00 [PATCH] mm/memory: fix hugetlb_zap_begin() call in zap_vma_range_batched() SJ Park
  2026-09-04  0:06 ` SJ Park
  2026-09-04  0:22 ` SJ Park
@ 2026-09-04  0:35 ` Andrew Morton
  2026-09-04  1:15   ` SJ Park
                     ` (2 more replies)
  2 siblings, 3 replies; 8+ messages in thread
From: Andrew Morton @ 2026-09-04  0:35 UTC (permalink / raw)
  To: SJ Park
  Cc: Liam R. Howlett, David Hildenbrand, Lorenzo Stoakes,
	Michal Hocko, Mike Rapoport, Suren Baghdasaryan, Vlastimil Babka,
	linux-kernel, linux-mm

On Thu,  3 Sep 2026 17:00:26 -0700 SJ Park <sj@kernel.org> wrote:

> Commit f1fc44daf618 ("mm/hugetlb: don't lock private resv_map during
> final unmap") added zap_details parameter to hugetlb_zap_begin().  But
> the hugetlb_zap_begin() call in zap_vma_range_batched() is not updated.
> As a result, build fails as below.  Fix it.
> 
>   CC      mm/memory.o
> .../mm/memory.c: In function ‘zap_vma_range_batched’:
> .../mm/memory.c:2308:9: error: too few arguments to function ‘hugetlb_zap_begin’
>  2308 |         hugetlb_zap_begin(vma, &range.start, &range.end);
>       |         ^~~~~~~~~~~~~~~~~
> In file included from .../mm/memory.c:48:
> .../include/linux/hugetlb.h:253:20: note: declared here
>   253 | static inline void hugetlb_zap_begin(struct vm_area_struct *vma,
>       |                    ^~~~~~~~~~~~~~~~~

You cleverly pulled during the ten-minute-window after I'd pushed this
out in order to pull it onto my build-test-machine.

There's probably a smarter way of doing this, not sure what though.

It doesn't happen often - I usually only need to push/pull the quilt
patches (25-new).

> /* TODO: move below to commentary */
> 
> I didn't read the broken commit in depth.  This fix is only
> build-tested.  I wanted to report the issue with this as a temporal fix,
> but the broken commit doesn't have Link: tag.  So directly posting this
> temporal and not very well verified fix first.

Yeah, this is possible fix for
https://syzkaller.appspot.com/bug?extid=bd6aaf99e8443d8a9034 which I
had chatgpt create for me.  It's in limbo at present until I figure out
what to do with it.  Actually I'll hide it from others while figuring-out
happens.



For the morbidly curious.  It's really only a 2-line change, plus a bunch
of changes to pass the zap_details down to  __hugetlb_zap_begin().



From: Andrew Morton <akpm@linux-foundation.org>
Subject: mm/hugetlb: don't lock private resv_map during final unmap

Replacing a private hugetlb mapping can trigger a lockdep circular
locking warning and, if the corresponding reclaim, NBD and socket paths
run concurrently, can deadlock userspace tasks.

The mmap path holds mmap_lock for write while removing an overlapping
mapping and then reaches:

  unmap_vmas()
    hugetlb_zap_begin()
      hugetlb_vma_lock_write()
        resv_map->rw_sema

This establishes the lock ordering:

  mmap_lock -> resv_map->rw_sema

Lockdep already knows about a transitive dependency in the other
direction.  In full, the relevant part of the dependency graph is:

  resv_map->rw_sema
    -> fs_reclaim
    -> q->q_usage_counter
    -> q->elevator_lock
    -> set->srcu
    -> cmd->lock
    -> nsock->tx_lock
    -> sk_lock-AF_INET6
    -> mmap_lock

The resv_map->rw_sema -> fs_reclaim edge can be established by a
private hugetlb fault.  The fault holds the private VMA lock for read
and huge_pte_alloc() can allocate page-table memory with reclaim
enabled.  The middle of the chain comes from the block and NBD paths,
while sk_lock-AF_INET6 -> mmap_lock can be established when an IPv6
send copies from userspace while holding the socket lock and faults on
the user buffer.

Consequently, lockdep summarizes the relevant reverse path as:

  resv_map->rw_sema -> sk_lock-AF_INET6 -> mmap_lock

This is a transitive lockdep dependency, not a single call stack
holding all three locks.

Commit bf4916922c60 ("hugetlbfs: extend hugetlb_vma_lock to private
VMAs") made hugetlb_vma_lock_write() acquire resv_map->rw_sema for
private hugetlb mappings.  That lock is needed for partial zaps such as
MADV_DONTNEED.  It keeps a concurrent fault from running after the PTE
has been cleared but before the hugepage has actually been returned to
the pool, which could otherwise result in an unexpected SIGBUS when the
hugepage pool is fully allocated.

That serialization is unnecessary when the VMA is being finally
unmapped.  mmap_lock prevents a concurrent fault from entering a VMA
which is being removed, and private VMAs do not participate in hugetlb
PMD sharing.

Pass the zap details to hugetlb_zap_begin() so that it can distinguish
a final unmap.  For final unmaps, continue taking the hugetlb VMA lock
for shareable mappings, where it protects PMD sharing and the lifetime
of the VMA lock, but do not take resv_map->rw_sema for a private
mapping.  Likewise, do not attempt to release the private reservation
map lock from hugetlb_zap_end().

Non-final zaps continue taking resv_map->rw_sema, preserving the
MADV_DONTNEED versus page-fault serialization for which private hugetlb
VMA locking was introduced.

Fixes: bf4916922c60 ("hugetlbfs: extend hugetlb_vma_lock to private VMAs")
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: syzbot+bd6aaf99e8443d8a9034@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=bd6aaf99e8443d8a9034
Cc: Rik van Riel <riel@surriel.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: David Hildenbrand <david@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Jane Chu <jane.chu@oracle.com>
Assisted-by: ChatGPT <chatgpt@openai.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 include/linux/hugetlb.h |    8 +++++---
 mm/hugetlb.c            |   16 ++++++++++++++--
 mm/memory.c             |    4 ++--
 3 files changed, 21 insertions(+), 7 deletions(-)

--- a/include/linux/hugetlb.h~mm-hugetlb-dont-lock-private-resv_map-during-final-unmap
+++ a/include/linux/hugetlb.h
@@ -245,15 +245,17 @@ void adjust_range_if_pmd_sharing_possibl
 				unsigned long *start, unsigned long *end);
 
 extern void __hugetlb_zap_begin(struct vm_area_struct *vma,
-				unsigned long *begin, unsigned long *end);
+				unsigned long *begin, unsigned long *end,
+				struct zap_details *details);
 extern void __hugetlb_zap_end(struct vm_area_struct *vma,
 			      struct zap_details *details);
 
 static inline void hugetlb_zap_begin(struct vm_area_struct *vma,
-				     unsigned long *start, unsigned long *end)
+				     unsigned long *start, unsigned long *end,
+				     struct zap_details *details)
 {
 	if (is_vm_hugetlb_page(vma))
-		__hugetlb_zap_begin(vma, start, end);
+		__hugetlb_zap_begin(vma, start, end, details);
 }
 
 static inline void hugetlb_zap_end(struct vm_area_struct *vma,
--- a/mm/hugetlb.c~mm-hugetlb-dont-lock-private-resv_map-during-final-unmap
+++ a/mm/hugetlb.c
@@ -5403,13 +5403,25 @@ void __unmap_hugepage_range(struct mmu_g
 }
 
 void __hugetlb_zap_begin(struct vm_area_struct *vma,
-			 unsigned long *start, unsigned long *end)
+			 unsigned long *start, unsigned long *end,
+			 struct zap_details *details)
 {
+	zap_flags_t zap_flags = details ? details->zap_flags : 0;
+
 	if (!vma->vm_file)	/* hugetlbfs_file_mmap error */
 		return;
 
 	adjust_range_if_pmd_sharing_possible(vma, start, end);
-	hugetlb_vma_lock_write(vma);
+
+	/*
+	 * A final unmap cannot race with a fault in this VMA because
+	 * mmap_lock prevents the fault from entering a VMA which is being
+	 * removed.  Skip the private resv_map lock in that case to avoid
+	 * inverting its lock order with mmap_lock.  Shareable mappings
+	 * still need the VMA lock to protect PMD sharing.
+	 */
+	if (!(zap_flags & ZAP_FLAG_UNMAP) || __vma_shareable_lock(vma))
+		hugetlb_vma_lock_write(vma);
 	if (vma->vm_file)
 		i_mmap_lock_write(vma->vm_file->f_mapping);
 }
--- a/mm/memory.c~mm-hugetlb-dont-lock-private-resv_map-during-final-unmap
+++ a/mm/memory.c
@@ -2268,7 +2268,7 @@ void unmap_vmas(struct mmu_gather *tlb,
 		unsigned long start = max(vma->vm_start, unmap->vma_start);
 		unsigned long end = min(vma->vm_end, unmap->vma_end);
 
-		hugetlb_zap_begin(vma, &start, &end);
+		hugetlb_zap_begin(vma, &start, &end, &details);
 		__zap_vma_range(tlb, vma, start, end, &details);
 		hugetlb_zap_end(vma, &details);
 		vma = mas_find(unmap->mas, unmap->tree_end - 1);
@@ -2304,7 +2304,7 @@ void zap_vma_range_batched(struct mmu_ga
 
 	mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, vma->vm_mm,
 				address, end);
-	hugetlb_zap_begin(vma, &range.start, &range.end);
+	hugetlb_zap_begin(vma, &range.start, &range.end, details);
 	update_hiwater_rss(vma->vm_mm);
 	mmu_notifier_invalidate_range_start(&range);
 	/*
_


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] mm/memory: fix hugetlb_zap_begin() call in zap_vma_range_batched()
  2026-09-04  0:35 ` Andrew Morton
@ 2026-09-04  1:15   ` SJ Park
  2026-09-07 17:05   ` Zenghui Yu
  2026-09-08  0:14   ` Zi Yan
  2 siblings, 0 replies; 8+ messages in thread
From: SJ Park @ 2026-09-04  1:15 UTC (permalink / raw)
  To: Andrew Morton
  Cc: SJ Park, Liam R. Howlett, David Hildenbrand, Lorenzo Stoakes,
	Michal Hocko, Mike Rapoport, Suren Baghdasaryan, Vlastimil Babka,
	linux-kernel, linux-mm

On Thu, 3 Sep 2026 17:35:40 -0700 Andrew Morton <akpm@linux-foundation.org> wrote:

> On Thu,  3 Sep 2026 17:00:26 -0700 SJ Park <sj@kernel.org> wrote:
> 
> > Commit f1fc44daf618 ("mm/hugetlb: don't lock private resv_map during
> > final unmap") added zap_details parameter to hugetlb_zap_begin().  But
> > the hugetlb_zap_begin() call in zap_vma_range_batched() is not updated.
> > As a result, build fails as below.  Fix it.
> > 
> >   CC      mm/memory.o
> > .../mm/memory.c: In function ‘zap_vma_range_batched’:
> > .../mm/memory.c:2308:9: error: too few arguments to function ‘hugetlb_zap_begin’
> >  2308 |         hugetlb_zap_begin(vma, &range.start, &range.end);
> >       |         ^~~~~~~~~~~~~~~~~
> > In file included from .../mm/memory.c:48:
> > .../include/linux/hugetlb.h:253:20: note: declared here
> >   253 | static inline void hugetlb_zap_begin(struct vm_area_struct *vma,
> >       |                    ^~~~~~~~~~~~~~~~~
> 
> You cleverly pulled during the ten-minute-window after I'd pushed this
> out in order to pull it onto my build-test-machine.

What a timing :)

I just found you pushed the tree again, after dropping the commit.  I confirmed
my build setup has no problem with it.  Sorry for making this noise.

> 
> There's probably a smarter way of doing this, not sure what though.
> 
> It doesn't happen often - I usually only need to push/pull the quilt
> patches (25-new).

No worry, indeed I never had this situation before.  And this was never a real
issue for me.


Thanks,
SJ

[...]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] mm/memory: fix hugetlb_zap_begin() call in zap_vma_range_batched()
  2026-09-04  0:35 ` Andrew Morton
  2026-09-04  1:15   ` SJ Park
@ 2026-09-07 17:05   ` Zenghui Yu
  2026-09-08  0:14   ` Zi Yan
  2 siblings, 0 replies; 8+ messages in thread
From: Zenghui Yu @ 2026-09-07 17:05 UTC (permalink / raw)
  To: Andrew Morton
  Cc: SJ Park, Liam R. Howlett, David Hildenbrand, Lorenzo Stoakes,
	Michal Hocko, Mike Rapoport, Suren Baghdasaryan, Vlastimil Babka,
	linux-kernel, linux-mm

On 9/4/26 8:35 AM, Andrew Morton wrote:
> On Thu,  3 Sep 2026 17:00:26 -0700 SJ Park <sj@kernel.org> wrote:
> 
> > I didn't read the broken commit in depth.  This fix is only
> > build-tested.  I wanted to report the issue with this as a temporal fix,
> > but the broken commit doesn't have Link: tag.  So directly posting this
> > temporal and not very well verified fix first.
> 
> Yeah, this is possible fix for
> https://syzkaller.appspot.com/bug?extid=bd6aaf99e8443d8a9034 which I
> had chatgpt create for me.  It's in limbo at present until I figure out
> what to do with it.  Actually I'll hide it from others while figuring-out
> happens.
> 
> 
> 
> For the morbidly curious.  It's really only a 2-line change, plus a bunch
> of changes to pass the zap_details down to  __hugetlb_zap_begin().
> 
> 
> 
> From: Andrew Morton <akpm@linux-foundation.org>
> Subject: mm/hugetlb: don't lock private resv_map during final unmap

FYI this causes the following warn when running selftests:

 ------------[ cut here ]------------
 DEBUG_RWSEMS_WARN_ON((rwsem_owner(sem) != current) && !rwsem_test_oflags(sem, RWSEM_NONSPINNABLE)): count = 0x0, magic = 0xffff8000059ff478, owner = 0x0, curr 0xffff800104a29000, list not empty
 WARNING: kernel/locking/rwsem.c:1412 at up_write+0x1f4/0x25c, CPU#6: pagemap_ioctl/1352
 Modules linked in: rfkill fuse virtio_gpu drm_client_lib virtio_dma_buf drm_shmem_helper drm_kms_helper drm
 CPU: 6 UID: 0 PID: 1352 Comm: pagemap_ioctl Kdump: loaded Tainted: G                 N  7.3.0-rc1+ #70 PREEMPT 
 Tainted: [N]=TEST
 Hardware name: QEMU QEMU Virtual Machine, BIOS edk2-stable202408-prebuilt.qemu.org 08/13/2024
 pstate: 61400005 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
 pc : up_write+0x1f4/0x25c
 lr : up_write+0x1f4/0x25c
 sp : ffffc0008903bab0
 x29: ffffc0008903bab0 x28: ffff800104a29000 x27: 0000000000000000
 x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000
 x23: ffff800104a29000 x22: ffffc000826254d0 x21: ffffc0008903bc68
 x20: ffffc00081eb6000 x19: ffff8000059ff478 x18: 0000000000000020
 x17: ffffc000800da3a8 x16: ffffc000800d971c x15: 00000000ffffffff
 x14: 0000000000000aab x13: ffffc00081edca98 x12: 0000000000002001
 x11: ffffffffffe26460 x10: ffffc00081edca98 x9 : 0000000000000006
 x8 : 0000000000000003 x7 : ffffc0008903b800 x6 : ffffc0008018bf04
 x5 : ffff8001eeb7d208 x4 : ffff8001eeb7d280 x3 : 0000000000000001
 x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff800104a29000
 Call trace:
  up_write+0x1f4/0x25c (P)
  __hugetlb_zap_end+0x58/0xfc
  unmap_vmas+0xbc/0x178
  exit_mmap+0xbc/0x4d0
  __mmput+0x58/0x154
  mmput+0x50/0x5c
  do_exit+0x2bc/0xd00
  do_group_exit+0x34/0x90
  pid_child_should_wake+0x0/0x5c
  invoke_syscall+0x54/0x110
  el0_svc_common.constprop.0+0x40/0xe0
  do_el0_svc+0x1c/0x28
  el0_svc+0x54/0x424
  el0t_64_sync_handler+0xa0/0xe4
  el0t_64_sync+0x1b0/0x1b4
 irq event stamp: 0
 hardirqs last  enabled at (0): [<0000000000000000>] 0x0
 hardirqs last disabled at (0): [<ffffc000800ce3a8>] copy_process+0x8f8/0x2078
 softirqs last  enabled at (0): [<ffffc000800ce3b0>] copy_process+0x900/0x2078
 softirqs last disabled at (0): [<0000000000000000>] 0x0
 ---[ end trace 0000000000000000 ]---

Thanks,
Zenghui

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] mm/memory: fix hugetlb_zap_begin() call in zap_vma_range_batched()
  2026-09-04  0:35 ` Andrew Morton
  2026-09-04  1:15   ` SJ Park
  2026-09-07 17:05   ` Zenghui Yu
@ 2026-09-08  0:14   ` Zi Yan
  2026-09-09  3:01     ` Andrew Morton
  2 siblings, 1 reply; 8+ messages in thread
From: Zi Yan @ 2026-09-08  0:14 UTC (permalink / raw)
  To: Andrew Morton, SJ Park
  Cc: Liam R. Howlett, David Hildenbrand, Lorenzo Stoakes,
	Michal Hocko, Mike Rapoport, Suren Baghdasaryan, Vlastimil Babka,
	linux-kernel, linux-mm

On Thu Sep 3, 2026 at 8:35 PM EDT, Andrew Morton wrote:
> On Thu,  3 Sep 2026 17:00:26 -0700 SJ Park <sj@kernel.org> wrote:
>
>> Commit f1fc44daf618 ("mm/hugetlb: don't lock private resv_map during
>> final unmap") added zap_details parameter to hugetlb_zap_begin().  But
>> the hugetlb_zap_begin() call in zap_vma_range_batched() is not updated.
>> As a result, build fails as below.  Fix it.
>> 
>>   CC      mm/memory.o
>> .../mm/memory.c: In function ‘zap_vma_range_batched’:
>> .../mm/memory.c:2308:9: error: too few arguments to function ‘hugetlb_zap_begin’
>>  2308 |         hugetlb_zap_begin(vma, &range.start, &range.end);
>>       |         ^~~~~~~~~~~~~~~~~
>> In file included from .../mm/memory.c:48:
>> .../include/linux/hugetlb.h:253:20: note: declared here
>>   253 | static inline void hugetlb_zap_begin(struct vm_area_struct *vma,
>>       |                    ^~~~~~~~~~~~~~~~~
>
> You cleverly pulled during the ten-minute-window after I'd pushed this
> out in order to pull it onto my build-test-machine.
>
> There's probably a smarter way of doing this, not sure what though.
>
> It doesn't happen often - I usually only need to push/pull the quilt
> patches (25-new).
>
>> /* TODO: move below to commentary */
>> 
>> I didn't read the broken commit in depth.  This fix is only
>> build-tested.  I wanted to report the issue with this as a temporal fix,
>> but the broken commit doesn't have Link: tag.  So directly posting this
>> temporal and not very well verified fix first.
>
> Yeah, this is possible fix for
> https://syzkaller.appspot.com/bug?extid=bd6aaf99e8443d8a9034 which I
> had chatgpt create for me.  It's in limbo at present until I figure out
> what to do with it.  Actually I'll hide it from others while figuring-out
> happens.
>
>
>
> For the morbidly curious.  It's really only a 2-line change, plus a bunch
> of changes to pass the zap_details down to  __hugetlb_zap_begin().
>
>
>
> From: Andrew Morton <akpm@linux-foundation.org>
> Subject: mm/hugetlb: don't lock private resv_map during final unmap
>
> Replacing a private hugetlb mapping can trigger a lockdep circular
> locking warning and, if the corresponding reclaim, NBD and socket paths
> run concurrently, can deadlock userspace tasks.
>
> The mmap path holds mmap_lock for write while removing an overlapping
> mapping and then reaches:
>
>   unmap_vmas()
>     hugetlb_zap_begin()
>       hugetlb_vma_lock_write()
>         resv_map->rw_sema
>
> This establishes the lock ordering:
>
>   mmap_lock -> resv_map->rw_sema
>
> Lockdep already knows about a transitive dependency in the other
> direction.  In full, the relevant part of the dependency graph is:
>
>   resv_map->rw_sema
>     -> fs_reclaim
>     -> q->q_usage_counter
>     -> q->elevator_lock
>     -> set->srcu
>     -> cmd->lock
>     -> nsock->tx_lock
>     -> sk_lock-AF_INET6
>     -> mmap_lock
>
> The resv_map->rw_sema -> fs_reclaim edge can be established by a
> private hugetlb fault.  The fault holds the private VMA lock for read
> and huge_pte_alloc() can allocate page-table memory with reclaim
> enabled.  The middle of the chain comes from the block and NBD paths,
> while sk_lock-AF_INET6 -> mmap_lock can be established when an IPv6
> send copies from userspace while holding the socket lock and faults on
> the user buffer.
>
> Consequently, lockdep summarizes the relevant reverse path as:
>
>   resv_map->rw_sema -> sk_lock-AF_INET6 -> mmap_lock
>
> This is a transitive lockdep dependency, not a single call stack
> holding all three locks.
>
> Commit bf4916922c60 ("hugetlbfs: extend hugetlb_vma_lock to private
> VMAs") made hugetlb_vma_lock_write() acquire resv_map->rw_sema for
> private hugetlb mappings.  That lock is needed for partial zaps such as
> MADV_DONTNEED.  It keeps a concurrent fault from running after the PTE
> has been cleared but before the hugepage has actually been returned to
> the pool, which could otherwise result in an unexpected SIGBUS when the
> hugepage pool is fully allocated.
>
> That serialization is unnecessary when the VMA is being finally
> unmapped.  mmap_lock prevents a concurrent fault from entering a VMA
> which is being removed, and private VMAs do not participate in hugetlb
> PMD sharing.
>
> Pass the zap details to hugetlb_zap_begin() so that it can distinguish
> a final unmap.  For final unmaps, continue taking the hugetlb VMA lock
> for shareable mappings, where it protects PMD sharing and the lifetime
> of the VMA lock, but do not take resv_map->rw_sema for a private
> mapping.  Likewise, do not attempt to release the private reservation
> map lock from hugetlb_zap_end().
>
> Non-final zaps continue taking resv_map->rw_sema, preserving the
> MADV_DONTNEED versus page-fault serialization for which private hugetlb
> VMA locking was introduced.
>
> Fixes: bf4916922c60 ("hugetlbfs: extend hugetlb_vma_lock to private VMAs")
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Reported-by: syzbot+bd6aaf99e8443d8a9034@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=bd6aaf99e8443d8a9034
> Cc: Rik van Riel <riel@surriel.com>
> Cc: Muchun Song <muchun.song@linux.dev>
> Cc: Oscar Salvador <osalvador@suse.de>
> Cc: David Hildenbrand <david@kernel.org>
> Cc: Liam R. Howlett <liam@infradead.org>
> Cc: Lorenzo Stoakes <ljs@kernel.org>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: Mike Rapoport <rppt@kernel.org>
> Cc: Suren Baghdasaryan <surenb@google.com>
> Cc: Vlastimil Babka <vbabka@kernel.org>
> Cc: Jane Chu <jane.chu@oracle.com>
> Assisted-by: ChatGPT <chatgpt@openai.com>
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> ---
>
>  include/linux/hugetlb.h |    8 +++++---
>  mm/hugetlb.c            |   16 ++++++++++++++--
>  mm/memory.c             |    4 ++--
>  3 files changed, 21 insertions(+), 7 deletions(-)
>

hugetlb-madvise got stuck because of this. Reverting the patch fixed the
issue.

From proc stack, it points to __hugetlb_zap_begin+0xf5/0x210, which
corresponds to __hugetlb_zap_begin at mm/hugetlb.c:5436 in mm-new.

-- 
Best Regards,
Yan, Zi


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] mm/memory: fix hugetlb_zap_begin() call in zap_vma_range_batched()
  2026-09-08  0:14   ` Zi Yan
@ 2026-09-09  3:01     ` Andrew Morton
  0 siblings, 0 replies; 8+ messages in thread
From: Andrew Morton @ 2026-09-09  3:01 UTC (permalink / raw)
  To: Zi Yan
  Cc: SJ Park, Liam R. Howlett, David Hildenbrand, Lorenzo Stoakes,
	Michal Hocko, Mike Rapoport, Suren Baghdasaryan, Vlastimil Babka,
	linux-kernel, linux-mm

On Mon, 07 Sep 2026 20:14:45 -0400 "Zi Yan" <ziy@nvidia.com> wrote:

> > ---
> >
> >  include/linux/hugetlb.h |    8 +++++---
> >  mm/hugetlb.c            |   16 ++++++++++++++--
> >  mm/memory.c             |    4 ++--
> >  3 files changed, 21 insertions(+), 7 deletions(-)
> >
> 
> hugetlb-madvise got stuck because of this. Reverting the patch fixed the
> issue.

oops, thanks, that patch isn't supposed to be in mm.git.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-09-09  3:01 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-04  0:00 [PATCH] mm/memory: fix hugetlb_zap_begin() call in zap_vma_range_batched() SJ Park
2026-09-04  0:06 ` SJ Park
2026-09-04  0:22 ` SJ Park
2026-09-04  0:35 ` Andrew Morton
2026-09-04  1:15   ` SJ Park
2026-09-07 17:05   ` Zenghui Yu
2026-09-08  0:14   ` Zi Yan
2026-09-09  3:01     ` Andrew Morton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®