From nobody Mon Feb 9 02:12:42 2026 Received: from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4]) (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 48A26350D7C for ; Tue, 13 Jan 2026 18:47:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.85.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768330067; cv=none; b=eKDP90J3piBc6meBQ5fOLj/m1nc0r1LTYE3fELCHswrjHtIk73A8r5L6nNx+Egcuw+EO6+qWwh+aB8xtgUAJ/+Yz6fLx3+9IU7PE5XF9RfIfni19JXyDyPr0PZ5GAeMgIColiwdYWOcukrtnNeoZF7SoZ2x4r1V3nS8cFcro0Z8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768330067; c=relaxed/simple; bh=T6vjkCTJHKrrfCfENt22C+/WuMCOS6UvN5jMtJ/7I30=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ly0zHAgVTNfurj1QtEWP8TUa4Y6hYf6pj6ykgGZ5+GPGWOumSNzaD5rBiSS2E1UqHJriEZID6/j4/pD4GDmuDMdA02/BqV1S797vYk+qjSg8gmD2sMh1Wm99NEcmBike6TYLXAh+1epsRiphnEu8NR7rketzE6/kuq3uVx4HL4A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=zxn3en61; arc=none smtp.client-ip=185.246.85.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="zxn3en61" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-03.galae.net (Postfix) with ESMTPS id DD14F4E420B4; Tue, 13 Jan 2026 18:47:37 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id B20E260701; Tue, 13 Jan 2026 18:47:37 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id 107E1103C871A; Tue, 13 Jan 2026 19:47:34 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1768330056; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=dzUppabWL92ubQUZhFXAzHoT9lyZRb6BD9mDAHq16fA=; b=zxn3en61kmIXe5o7kG+ogBYNR2D5f5ro+DjUuhOwDxpPo3DOgAosWK/FgKPfA4ZHXWs0re voQAP48dEbd5eGLs5X7IC+0a9pXu3Ourep5bMMIpVkJrTzGUr6LuVCsCUTYOubpv85tWHl 0NIMoSYny9DtRF6NZVr3L/6twQKa+zPgMFaI0rc5f4n06YopOwqG8SLl/r2hYBuNOYQG9f h9QrT5aezVUaqFo/NFpt6pvbhbkH/eg7pdQvcfLJ8W84P//v3YWz/9ZJwnKnoUMlmGaP/y iECmH9glhdK4I64pQFrzKU/IE6ZSetdq+u7jS3aZn5KmGzfBaTLw3Fs7DF+5jQ== From: Luca Ceresoli Date: Tue, 13 Jan 2026 19:47:17 +0100 Subject: [PATCH RESEND v4 6/7] drm/bridge: prevent encoder chain changes while iterating with list_for_each_entry_reverse() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260113-drm-bridge-alloc-encoder-chain-mutex-v4-6-60f3135adc45@bootlin.com> References: <20260113-drm-bridge-alloc-encoder-chain-mutex-v4-0-60f3135adc45@bootlin.com> In-Reply-To: <20260113-drm-bridge-alloc-encoder-chain-mutex-v4-0-60f3135adc45@bootlin.com> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec Cc: Hui Pu , Thomas Petazzoni , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Luca Ceresoli , Ian Ray X-Mailer: b4 0.14.3 X-Last-TLS-Session-Version: TLSv1.3 These loops in drm_bridge.c iterate over the encoder chain using list_for_each_entry_reverse(), which does not prevent changes to the bridge chain while iterating over it. Take the encoder chain mutex while iterating to avoid chain changes while iterating. All the "simple" loops are converted. drm_atomic_bridge_chain_pre_enable() and drm_atomic_bridge_chain_post_disable() are handled by a separate commit. Signed-off-by: Luca Ceresoli --- Changes in v3: - Lock encoder->bridge_chain_mutex directly, no wrappers Changes in v2: none --- drivers/gpu/drm/drm_bridge.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 9b4a075b5361..eca138eadbc5 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -710,6 +710,7 @@ void drm_atomic_bridge_chain_disable(struct drm_bridge = *bridge, return; =20 encoder =3D bridge->encoder; + mutex_lock(&encoder->bridge_chain_mutex); list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { if (iter->funcs->atomic_disable) { iter->funcs->atomic_disable(iter, state); @@ -720,6 +721,7 @@ void drm_atomic_bridge_chain_disable(struct drm_bridge = *bridge, if (iter =3D=3D bridge) break; } + mutex_unlock(&encoder->bridge_chain_mutex); } EXPORT_SYMBOL(drm_atomic_bridge_chain_disable); =20 @@ -1224,25 +1226,27 @@ int drm_atomic_bridge_chain_check(struct drm_bridge= *bridge, return ret; =20 encoder =3D bridge->encoder; - list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { - int ret; - - /* - * Bus flags are propagated by default. If a bridge needs to - * tweak the input bus flags for any reason, it should happen - * in its &drm_bridge_funcs.atomic_check() implementation such - * that preceding bridges in the chain can propagate the new - * bus flags. - */ - drm_atomic_bridge_propagate_bus_flags(iter, conn, - crtc_state->state); - - ret =3D drm_atomic_bridge_check(iter, crtc_state, conn_state); - if (ret) - return ret; + scoped_guard(mutex, &encoder->bridge_chain_mutex) { + list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { + int ret; + + /* + * Bus flags are propagated by default. If a bridge needs to + * tweak the input bus flags for any reason, it should happen + * in its &drm_bridge_funcs.atomic_check() implementation such + * that preceding bridges in the chain can propagate the new + * bus flags. + */ + drm_atomic_bridge_propagate_bus_flags(iter, conn, + crtc_state->state); + + ret =3D drm_atomic_bridge_check(iter, crtc_state, conn_state); + if (ret) + return ret; =20 - if (iter =3D=3D bridge) - break; + if (iter =3D=3D bridge) + break; + } } =20 return 0; --=20 2.52.0