From nobody Sun Feb 8 14:10:40 2026 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ECC44314D15 for ; Tue, 23 Dec 2025 16:18:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766506708; cv=none; b=CUqeMb9x6GTA1jFIut5/mTXIo6ZDiZyTvwTN64OphZz4CciZWacbNw8bkIhA9+PNf6HzuRIsTjEQmSpIl0h0kzHxpnS+JxK4LxqswZ8gDpTHlIdgTgVvlzwi8BOHE6r2D2qHCOLuZpWmM7hlz2LK8KFk9mbELTfD6bsJ6IZQurI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766506708; c=relaxed/simple; bh=5MbTezqVniVMWrWPh/jzCyIi8y2s09KemMIahGqctog=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=tKvJ8fmIwzRSmyL4mK8rD+eLRr243bQnzPfQCPbpNYyCoWMUIs52/3Pqi72Y9EympVBnRkulybZOfPVIiyMujpxUl88mAJxpgulzDwzyHcYNTojvpGnDRfpFOF6N3+ppzmX5oAqAL4+dO0iIVYs61KpxIE8xsq5ovakbmZrtq2I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--jackmanb.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=X9xp9T2j; arc=none smtp.client-ip=209.85.221.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--jackmanb.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="X9xp9T2j" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-430fcb6b2ebso2830324f8f.2 for ; Tue, 23 Dec 2025 08:18:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1766506705; x=1767111505; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=R8qAbifDARtNQH6///Cfz2Z6dr98BHzjmVALCF1UKvo=; b=X9xp9T2jhsv063FNnaVSB9Fs/hlioAXGiPXM3LX0I9WTnd6IxmteV8yE7rY0OjbldY 5E3RLjxDprMN73J4+PPGwbx3cXuwFAzwrUQA7hh7FVumoDon0BLHMBksXCtmXbEOzMTO 2+vphi9MxoKUD+Wttk27IzriVTYsHIkYKTSHeIXS4XC5eIofiAkqWac1ygFioj1xF10V IoPmefKfjvnUQoELn9z0Aj1Igx7WBvoqo5CX1Btvu163wvwCDdDBUtqOIC+s2sZKvdxk 8UdctF42MH1lttXqqIJICzOLry//NOM4Tq5emTx0rs52tUiLNh3iGgJXOoGun/pvmHKq qy2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766506705; x=1767111505; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=R8qAbifDARtNQH6///Cfz2Z6dr98BHzjmVALCF1UKvo=; b=u5K0SqKF12NombjCHa03B3quC33kG7GqP7AVtp1PRAuREXPCuXNUbRwwXXdJgHohAq 5zORLPAVOm36XymlIWcG4ixtT+SbRqsrzbv1GCaZ4walmb2VtBBUJBAmoI26Kb6H1hxn NceCYJjCWKO3Ffx3tUV6zx5QZnmSb6LD8VgMpLEZiEH78KyVud3yhjuLCVXnkSoyazjT 1M7L58AtokYj4zqgja6q5no0S8V5M7MwYHdGIuArqP6yw06ffDups21ChSnMDyIDWIkD gNTxZQ/5DZi/w48E5uvfSx39bu/Ksl6Bei3YEvil07bjNBtKCt9oTrsJGcn3NvB6O+QP iECg== X-Forwarded-Encrypted: i=1; AJvYcCVrCkGsZ/KE9B/QUgbDConM2wng5Whk6/VGB0rFNSluGsobt3FoonDan+Be6hNMRsJP8WUwuOcEMbKp1SQ=@vger.kernel.org X-Gm-Message-State: AOJu0YxnpNw6URwAAT10FMmjy/q/FbfF7WgYThk9XqAp9265e93f6t6d a0vpH4+8ad2263tKe+9Tj/O/r/xL8+t+AidDxVz6XRJzSXyiBL39JCtsPss7vUkZoqEUZZGxFYk JDm+0WIKrsLulTg== X-Google-Smtp-Source: AGHT+IE8oDnfqXf51PXB9j7+xWXr487pSfiP2TuENwnOyxXdASQaxwRWlpWlqrTmlw8rYWPUrC2vEA5s/m4GpQ== X-Received: from wrbfu10.prod.google.com ([2002:a05:6000:25ea:b0:42f:b7f1:749e]) (user=jackmanb job=prod-delivery.src-stubby-dispatcher) by 2002:a5d:5f54:0:b0:431:907:f307 with SMTP id ffacd0b85a97d-4324e506ab1mr15076109f8f.48.1766506705229; Tue, 23 Dec 2025 08:18:25 -0800 (PST) Date: Tue, 23 Dec 2025 16:18:11 +0000 In-Reply-To: <20251223-b4-kunit-user-alloc-v1-0-fb910ae0e50c@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251223-b4-kunit-user-alloc-v1-0-fb910ae0e50c@google.com> X-Mailer: b4 0.14.3 Message-ID: <20251223-b4-kunit-user-alloc-v1-2-fb910ae0e50c@google.com> Subject: [PATCH 2/3] kthread: Add kthread_take_mm() From: Brendan Jackman To: Brendan Higgins , David Gow , Rae Moar , Kees Cook , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Valentin Schneider , Andrew Morton , David Hildenbrand , Lorenzo Stoakes , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko Cc: linux-kselftest@vger.kernel.org, kunit-dev@googlegroups.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, Brendan Jackman Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable lib/kunit/user_alloc.c currently uses kthread_use_mm() without a corresponding kthread_unuse_mm(). This is a bug, but fixing it in KUnit makes writing tests that use mms more difficult, because of KUnit's resource/try-catch model. Therefore, introduce a new operation that does what kunit_attach_mm() wants, namely an unbalanced call with cleanup deferred to kthread_exit(). This is actually just the same as kthread_use_mm() but without taking a reference on the mm_struct. While adding this, clarify the reference returned by mm_alloc(), since that is what kthread_take_mm() is gonna be paired with, in practice. Signed-off-by: Brendan Jackman Reviewed-by: David Gow # For KUnit --- include/linux/kthread.h | 1 + kernel/fork.c | 3 ++- kernel/kthread.c | 36 +++++++++++++++++++++++++++--------- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 8d27403888ce9..2e6244d8ff1a3 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -259,6 +259,7 @@ bool kthread_cancel_delayed_work_sync(struct kthread_de= layed_work *work); =20 void kthread_destroy_worker(struct kthread_worker *worker); =20 +void kthread_take_mm(struct mm_struct *mm); void kthread_use_mm(struct mm_struct *mm); void kthread_unuse_mm(struct mm_struct *mm); =20 diff --git a/kernel/fork.c b/kernel/fork.c index b1f3915d5f8ec..761e6232ea75a 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1147,7 +1147,8 @@ static struct mm_struct *mm_init(struct mm_struct *mm= , struct task_struct *p, } =20 /* - * Allocate and initialize an mm_struct. + * Allocate and initialize an mm_struct. The caller gets a single referenc= e to + * the mm's address space, which should be released with a call to mmput(). */ struct mm_struct *mm_alloc(void) { diff --git a/kernel/kthread.c b/kernel/kthread.c index 99a3808d086f0..c660c04a1b627 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -1589,10 +1589,16 @@ void kthread_destroy_worker(struct kthread_worker *= worker) EXPORT_SYMBOL(kthread_destroy_worker); =20 /** - * kthread_use_mm - make the calling kthread operate on an address space + * kthread_take_mm - make the calling kthread own an address space. + * + * Unlike kthread_use_mm(), this doesn't have a cleanup, instead that happ= ens + * automatically on kthread exit. Correspondingly, it does not take any + * references, by calling this function you donate your reference to the a= ddress + * space (from mmget()/mm_users). + * * @mm: address space to operate on */ -void kthread_use_mm(struct mm_struct *mm) +void kthread_take_mm(struct mm_struct *mm) { struct mm_struct *active_mm; struct task_struct *tsk =3D current; @@ -1600,13 +1606,6 @@ void kthread_use_mm(struct mm_struct *mm) WARN_ON_ONCE(!(tsk->flags & PF_KTHREAD)); WARN_ON_ONCE(tsk->mm); =20 - /* - * It is possible for mm to be the same as tsk->active_mm, but - * we must still mmgrab(mm) and mmdrop_lazy_tlb(active_mm), - * because these references are not equivalent. - */ - mmgrab(mm); - task_lock(tsk); /* Hold off tlb flush IPIs while switching mm's */ local_irq_disable(); @@ -1632,6 +1631,25 @@ void kthread_use_mm(struct mm_struct *mm) */ mmdrop_lazy_tlb(active_mm); } +EXPORT_SYMBOL_GPL(kthread_take_mm); + +/** + * kthread_use_mm - make the calling kthread operate on an address space. + * + * This must be paired with a call to kthread_unuse_mm(). + * + * @mm: address space to operate on + */ +void kthread_use_mm(struct mm_struct *mm) +{ + /* + * It is possible for mm to be the same as tsk->active_mm, but we must + * still mmgrab(mm) and mmdrop_lazy_tlb(active_mm) (in + * kthread_take_mm()), because these references are not equivalent. + */ + mmgrab(mm); + kthread_take_mm(mm); +} EXPORT_SYMBOL_GPL(kthread_use_mm); =20 /** --=20 2.51.2