From: "Kiryl Shutsemau (Meta)" <[email protected]>

madvise_collapse() holds an mmgrab() reference across its work, which
nothing needs.  mmgrab() pins the mm_struct alone; every caller already
holds mm_users, which keeps the address space itself alive and so implies
it:

 - madvise(2) works on current->mm, which lives as long as the task is in
   the syscall;
 - process_madvise(2) reaches a remote mm through mm_access(), which takes
   an mm_users reference and holds it until the syscall returns;
 - io_uring passes current->mm;
 - DAMON takes one with get_task_mm() and drops it after the call.

Drop the mmgrab()/mmdrop() pair.  It has been there since
commit 7d8faaf15545 ("mm/madvise: introduce MADV_COLLAPSE sync hugepage 
collapse").

Assisted-by: Claude-Code:claude-opus-5
Signed-off-by: Kiryl Shutsemau (Meta) <[email protected]>
---
 mm/madvise.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/mm/madvise.c b/mm/madvise.c
index 76ddf61f043f..c1bb425be3f4 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -979,8 +979,6 @@ static int madvise_collapse(struct madvise_behavior 
*madv_behavior)
                return err;
        }
 
-       mmgrab(mm);
-
        /*
         * Nothing below wants the lock the VMA walk left held, and
         * lru_add_drain_all() waits on every CPU, so give it up first.  The
@@ -1071,7 +1069,6 @@ static int madvise_collapse(struct madvise_behavior 
*madv_behavior)
        /* The VMA walk this returns to expects the lock it was holding */
        if (!vma)
                mmap_read_lock(mm);
-       mmdrop(mm);
        collapse_control_release(cc);
        kfree(cc);
 
-- 
2.54.0


Reply via email to