* 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