From nobody Mon Sep 28 07:19:28 2026 Received: from out203-205-221-164.mail.qq.com (out203-205-221-164.mail.qq.com [203.205.221.164]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0DFE43E6DDD for ; Tue, 25 Aug 2026 09:20:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.205.221.164 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787649636; cv=none; b=pQpN56i9Ms9o2qhzfA4tTaWra8nhMqYKvgZEzZqyr+Er/RoQPPT/kEMDdi1NdvtuCcgncgxWLtF60IlX339EqwYONEddpiI2ICkwIeTltiRPxVtr0GkiW4nP8SB8gdEMQXICP32jzI1is1KmJ/lUXHXA0j/R7YSKrLmFCrYY/Rc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787649636; c=relaxed/simple; bh=P0oXdvkRH64e6Nkfl3+kSs3KG1vyW+HhZwij1Ex5W1A=; h=Message-ID:Date:MIME-Version:To:Cc:From:Subject:Content-Type; b=WDe1bPcRHagEz5OcNRYOWJaEnUI0NBtDcGB0L5RcUp2yWi1w7ghONi54xhOUjCRBBEEWs7nKYoAeL3eX2RDS6ORZo99/ghE6DH2pS+mEu5hVRA3exvgGH4JtjGi2QeMnPz8TWwIOMJ+qjam3BlY90fLf0oxMveB7ohPRsKRbQ8E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=qq.com; spf=pass smtp.mailfrom=qq.com; dkim=pass (1024-bit key) header.d=qq.com header.i=@qq.com header.b=kB7Ag9it; arc=none smtp.client-ip=203.205.221.164 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=qq.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=qq.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=qq.com header.i=@qq.com header.b="kB7Ag9it" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201512; t=1787649624; bh=P0oXdvkRH64e6Nkfl3+kSs3KG1vyW+HhZwij1Ex5W1A=; h=Date:To:Cc:From:Subject; b=kB7Ag9itPDBSCSECsWk28xWjZWksI7wTNsDKQjfocgVtZLiTSEHNe20iuwFCI4tMg KhgGjBs/I/bDBG+IlYdnBVwsZbxpcZBFi8iwNzjT1Aj/vyx50M0xeQtH+qkcD2qix2 LvpHjzh18o+WdC1ljfC5lhDlwKHIMVIK58AFFgh8= Received: from [192.168.255.10] ([111.206.96.150]) by newxmesmtplogicsvrsza73-0.qq.com (NewEsmtp) with SMTP id 51500010; Tue, 25 Aug 2026 17:20:21 +0800 X-QQ-mid: xmsmtpt1787649621t51dxlkuk Message-ID: X-QQ-XMAILINFO: OATpkVjS499u6LX1l/SusAnGSdIhRJa931Nvo2+dVn2gNcdzL2PQ9zkjy+5l3u 0yDag/P50NlTCtuIzJbYECL2tB55KF/+eX5y4L7B1RIBcdsIJzIXnofw6EB1AI+bvL6fmfcDhGoz Njes3bX7t2ELhSKoCY/ejNKtmf0AdEhrWcKVBCGsNgFhf3bAF6GQIwJginmdtyZemSPWKh7Actdo 6Gk6HGoZDBu7F30jJeiWwfkLmHbhkwRKEeHpmeQSFSItB6J3p7lBw1k5EF1LQvV2ex0CJQYt+6TH EkoS2dJVuWZZ8UKu/xZTdiuRTv4Gxy3cKNrws5jeBi4ky2NoUw6CbroilPShS9YJYtfC03Wb+iir v3ca8XPaLAE4IZengYzaNAclZESAO45fW04yvrozMAf9CHSs/Qhd4IZ6jWHLNKqYMiwWzbYNjCRs WIEkAgkp9cmnkWb3DvqGrz4sNRm0/8QTkSoEqT/Fwn7z46AtIE1AL7APNZBvGIsM9NRnm6UF5Q9p 3w1EdipYqSbFvUmAsgbZO+ntjuL13U/2p+dn0zJlTBgIK+zKuJ6A1EPKzxYvT6IQMhdM/5LK8vvz Qyk1X2BPctfkSpMk3dHYFxsoRuz8MknUVfrTrvaJ4TwTcp27oKmc1UnBjaZ4GD8bW4uY4mWvGD8V 7P6xFABUYPfqxRtxXmR68YOemQeMH01HX5DN8Qwn8Ao0NoSTP+gIiU4I0KpJ23LKae11mzig03Jz IHBuRUjiu+NNjTOEVXgoDv0ZWtWtGGRpKI1TDbGYGEwknu9KL1W0F1hA3PggGVt9OXF7pj/aYmnu ecnhN+U001L38/JDf3ylwbUglLmW6Quy2CJmT10xO4vm2kwdDA8bvlZifepTdpvnj8Qi66CMeceW Ntx+HbnluW3mqufuiNNlyAyMXM/Vpc75MyB6fOGoOh76bRyQ1iqU6Ee8N9ZnQ3GeUPTVTwk5Wdpq ouxUhdRG9OuN1FFEkZE3G1WsK5ojcBY4EuNI6iernTy81D9KtR/TuaUkQKkaQXw/j1aEvJLKMEql ME8i8TW23AG4E8j0OANHxoEqP06Jp9PN5E53Gxh4fBSdt+Zv7P X-QQ-XMRINFO: NI4Ajvh11aEjEMj13RCX7UuhPEoou2bs1g== X-OQ-MSGID: <5e513890-eea6-4194-b441-9ab391691021@qq.com> Date: Tue, 25 Aug 2026 17:20:20 +0800 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird To: peterz@infradead.org, mingo@redhat.com, will@kernel.org, boqun@kernel.org, longman@redhat.com Cc: linux-kernel@vger.kernel.org From: Yang Zi <2959243019@qq.com> Subject: [PATCH] locking/mutex: Restore RCU read-side protection for optimistic spinning Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The optimistic spinning paths in kernel/locking/mutex.c dereference the current lock owner's task_struct (via owner_on_cpu() -> owner->on_cpu and task_cpu(owner)) without any lifetime protection on the owner pointer. __mutex_owner() (kernel/locking/mutex.h) returns a bare task_struct pointer that is read directly from lock->owner. mutex_spin_on_owner() and mutex_can_spin_on_owner() then dereference it inside "while (__mutex_owner(lock) =3D=3D owner)" / immediately after the owner load, whi= le relying only on preempt_disable(). Fix it by taking an explicit rcu_read_lock()/rcu_read_unlock() around the owner dereference in both mutex_spin_on_owner() and mutex_can_spin_on_owner= (), restoring the pre-5.16 protection, and update the now-inaccurate comments. Signed-off-by: Yang Zi <2959243019@qq.com> --- diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index 942a939cee95..cc2d7090bf36 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -389,14 +389,21 @@ bool mutex_spin_on_owner(struct mutex *lock, struct t= ask_struct *owner, =C2=A0 =C2=A0 =C2=A0 =C2=A0lockdep_assert_preemption_disabled(); =C2=A0 +=C2=A0 =C2=A0 /* +=C2=A0 =C2=A0 =C2=A0* Optimistic spinners run with preempt_disable() which= , on classic +=C2=A0 =C2=A0 =C2=A0* PREEMPT_RCU, was enough to act as an RCU read-side c= ritical +=C2=A0 =C2=A0 =C2=A0* section. On PREEMPT_LAZY kernels preempt_disable() n= o longer +=C2=A0 =C2=A0 =C2=A0* prevents RCU callbacks (e.g. the free of an exiting = owner's +=C2=A0 =C2=A0 =C2=A0* task_struct via call_rcu() in rcu_do_batch()) from r= unning, so take +=C2=A0 =C2=A0 =C2=A0* an explicit RCU read-side critical section to keep t= he owner alive. +=C2=A0 =C2=A0 =C2=A0*/ +=C2=A0 =C2=A0 rcu_read_lock(); =C2=A0 =C2=A0 =C2=A0while (__mutex_owner(lock) =3D=3D owner) { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* Ensure we emit the owner->on_cpu, dere= ference _after_ -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* checking lock->owner still matches own= er. And we already -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* disabled preemption which is equal to = the RCU read-side -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* crital section in optimistic spinning = code. Thus the -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* task_strcut structure won't go away du= ring the spinning -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* period +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* Ensure we emit the owner->on_cpu deref= erence _after_ +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* checking lock->owner still matches own= er. If that fails, +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* owner might point to freed memory. If = it still matches, +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0* the rcu_read_lock() ensures the memory= stays valid. =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0barrier(); =C2=A0 @@ -415,6 +422,7 @@ bool mutex_spin_on_owner(struct mutex *lock, struct tas= k_struct *owner, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0cpu_relax(); =C2=A0 =C2=A0 =C2=A0} +=C2=A0 =C2=A0 rcu_read_unlock(); =C2=A0 =C2=A0 =C2=A0 =C2=A0return ret; =C2=A0} @@ -433,13 +441,16 @@ static inline int mutex_can_spin_on_owner(struct mute= x *lock) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0; =C2=A0 =C2=A0 =C2=A0 =C2=A0/* -=C2=A0 =C2=A0 =C2=A0* We already disabled preemption which is equal to the= RCU read-side -=C2=A0 =C2=A0 =C2=A0* crital section in optimistic spinning code. Thus the= task_strcut -=C2=A0 =C2=A0 =C2=A0* structure won't go away during the spinning period. +=C2=A0 =C2=A0 =C2=A0* See the comment in mutex_spin_on_owner(): preempt_di= sable() is no +=C2=A0 =C2=A0 =C2=A0* longer an RCU read-side critical section on PREEMPT_= LAZY kernels, +=C2=A0 =C2=A0 =C2=A0* so protect the owner dereference with an explicit RC= U read-side +=C2=A0 =C2=A0 =C2=A0* critical section. =C2=A0 =C2=A0 =C2=A0 */ +=C2=A0 =C2=A0 rcu_read_lock(); =C2=A0 =C2=A0 =C2=A0owner =3D __mutex_owner(lock); =C2=A0 =C2=A0 =C2=A0if (owner) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0retval =3D owner_on_cpu(owner); +=C2=A0 =C2=A0 rcu_read_unlock(); =C2=A0 =C2=A0 =C2=A0 =C2=A0/* =C2=A0 =C2=A0 =C2=A0 * If lock->owner is not set, the mutex has been releas= ed. Return true