* [PATCH 6.18.y] drm/vkms: Fix ABBA deadlock in vblank disable and timer callback
@ 2026-05-15 13:18 w15303746062
2026-05-15 15:09 ` Greg KH
0 siblings, 1 reply; 18+ messages in thread
From: w15303746062 @ 2026-05-15 13:18 UTC (permalink / raw)
To: louis.chauvet, hamohammed.sa, simona, melissa.srw,
maarten.lankhorst, mripard, tzimmermann, airlied
Cc: dri-devel, linux-kernel, stable, Mingyu Wang
From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
[Note: This patch addresses a legacy VKMS implementation deadlock specific
to older stable trees (e.g., 6.18.y). Mainline has removed this code during
the generic DRM_CRTC_VBLANK_TIMER_FUNCS refactoring.]
During local fuzzing with Syzkaller, an RCU preempt stall (soft lockup)
was observed. This is caused by an ABBA deadlock between the
drm_vblank_disable_and_save() function and the vkms_vblank_simulate()
hrtimer callback.
The race condition occurs as follows:
Thread A (CPU 3 - DRM_IOCTL_MODE_SETCRTC):
- drm_vblank_disable_and_save() acquires `&dev->vblank_time_lock`.
- Calls __disable_vblank() -> vkms_disable_vblank().
- Calls hrtimer_cancel() to synchronously stop the vblank timer.
- BLOCK: hrtimer_cancel() spins indefinitely waiting for the timer
callback to finish executing on CPU 0.
Thread B (CPU 0 - hrtimer interrupt):
- Executes the hrtimer callback vkms_vblank_simulate().
- Calls drm_crtc_handle_vblank() -> drm_handle_vblank().
- BLOCK: drm_handle_vblank() tries to acquire `&dev->vblank_time_lock`
and spins forever because Thread A is holding it.
This patch fixes the deadlock by replacing hrtimer_cancel() with
hrtimer_try_to_cancel(). If the timer callback is running, try_to_cancel()
will safely return -1 and allow Thread A to proceed and release the lock.
Additionally, vkms_vblank_simulate() is modified to conditionally return
HRTIMER_NORESTART if drm_crtc_handle_vblank() fails (which it will,
because Thread A sets `vblank->enabled = false` immediately after
try_to_cancel). This acts as a self-destruct mechanism, preventing the
timer from blindly re-arming itself and causing an infinite loop of
DRM_ERROR messages.
Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
---
drivers/gpu/drm/vkms/vkms_crtc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index e60573e0f3e9..a62153b73548 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -57,7 +57,7 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
dma_fence_end_signalling(fence_cookie);
- return HRTIMER_RESTART;
+ return ret ? HRTIMER_RESTART : HRTIMER_NORESTART;
}
static int vkms_enable_vblank(struct drm_crtc *crtc)
@@ -77,7 +77,7 @@ static void vkms_disable_vblank(struct drm_crtc *crtc)
{
struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
- hrtimer_cancel(&out->vblank_hrtimer);
+ hrtimer_try_to_cancel(&out->vblank_hrtimer);
}
static bool vkms_get_vblank_timestamp(struct drm_crtc *crtc,
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 6.18.y] drm/vkms: Fix ABBA deadlock in vblank disable and timer callback
2026-05-15 13:18 [PATCH 6.18.y] drm/vkms: Fix ABBA deadlock in vblank disable and timer callback w15303746062
@ 2026-05-15 15:09 ` Greg KH
2026-05-16 2:43 ` w15303746062
0 siblings, 1 reply; 18+ messages in thread
From: Greg KH @ 2026-05-15 15:09 UTC (permalink / raw)
To: w15303746062
Cc: louis.chauvet, hamohammed.sa, simona, melissa.srw,
maarten.lankhorst, mripard, tzimmermann, airlied, dri-devel,
linux-kernel, stable, Mingyu Wang
On Fri, May 15, 2026 at 09:18:26PM +0800, w15303746062@163.com wrote:
> From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
>
> [Note: This patch addresses a legacy VKMS implementation deadlock specific
> to older stable trees (e.g., 6.18.y). Mainline has removed this code during
> the generic DRM_CRTC_VBLANK_TIMER_FUNCS refactoring.]
Why not apply those upstream commits here as well? No need to diverge
from Linus's tree, otherwise we will end up having a mess that nothing
can ever be backported to.
How many commits need to be backported? Have you tried?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re:Re: [PATCH 6.18.y] drm/vkms: Fix ABBA deadlock in vblank disable and timer callback
2026-05-15 15:09 ` Greg KH
@ 2026-05-16 2:43 ` w15303746062
2026-05-16 9:51 ` Greg KH
0 siblings, 1 reply; 18+ messages in thread
From: w15303746062 @ 2026-05-16 2:43 UTC (permalink / raw)
To: Greg KH
Cc: louis.chauvet, hamohammed.sa, simona, melissa.srw,
maarten.lankhorst, mripard, tzimmermann, airlied, dri-devel,
linux-kernel, stable, Mingyu Wang
Hi Greg,
Thanks for the quick response and review.
At 2026-05-15 23:09:46, "Greg KH" <greg@kroah.com> wrote:
>On Fri, May 15, 2026 at 09:18:26PM +0800, w15303746062@163.com wrote:
>> From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
>>
>> [Note: This patch addresses a legacy VKMS implementation deadlock specific
>> to older stable trees (e.g., 6.18.y). Mainline has removed this code during
>> the generic DRM_CRTC_VBLANK_TIMER_FUNCS refactoring.]
>
>Why not apply those upstream commits here as well? No need to diverge
>from Linus's tree, otherwise we will end up having a mess that nothing
>can ever be backported to.
>
>How many commits need to be backported? Have you tried?
I have looked into the upstream commits. The commit that removed this
vulnerable legacy code in mainline is:
02e2681ffe1a ("drm/vkms: Convert to DRM's vblank timer")
I tried to apply it to 6.18.y, but it does not apply cleanly. The reason
is that this upstream commit is not a simple bug fix, but a massive
refactoring. It completely rips out the custom VKMS hrtimer and ports
the driver to a newly introduced DRM core infrastructure
(DRM_CRTC_VBLANK_TIMER_FUNCS and drm_vblank_helper.h).
To backport commit 02e2681ffe1a, we would first need to backport the
entire DRM generic vblank timer infrastructure to 6.18.y. This seems
too intrusive and violates the minimal-risk policy for stable trees.
Therefore, since the legacy custom hrtimer still exists in 6.18.y and
is actively causing ABBA deadlocks (RCU stalls), this minimalistic
and localized patch (using hrtimer_try_to_cancel) is proposed as the
safest way to fix the issue specifically for older stable branches
without pulling in major DRM core refactoring.
Would this localized fix be acceptable for the stable tree?
Thanks,
Mingyu
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Re: [PATCH 6.18.y] drm/vkms: Fix ABBA deadlock in vblank disable and timer callback
2026-05-16 2:43 ` w15303746062
@ 2026-05-16 9:51 ` Greg KH
2026-05-18 2:22 ` w15303746062
0 siblings, 1 reply; 18+ messages in thread
From: Greg KH @ 2026-05-16 9:51 UTC (permalink / raw)
To: w15303746062
Cc: louis.chauvet, hamohammed.sa, simona, melissa.srw,
maarten.lankhorst, mripard, tzimmermann, airlied, dri-devel,
linux-kernel, stable, Mingyu Wang
On Sat, May 16, 2026 at 10:43:35AM +0800, w15303746062 wrote:
>
> Hi Greg,
>
> Thanks for the quick response and review.
>
>
> At 2026-05-15 23:09:46, "Greg KH" <greg@kroah.com> wrote:
> >On Fri, May 15, 2026 at 09:18:26PM +0800, w15303746062@163.com wrote:
> >> From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
> >>
> >> [Note: This patch addresses a legacy VKMS implementation deadlock specific
> >> to older stable trees (e.g., 6.18.y). Mainline has removed this code during
> >> the generic DRM_CRTC_VBLANK_TIMER_FUNCS refactoring.]
> >
> >Why not apply those upstream commits here as well? No need to diverge
> >from Linus's tree, otherwise we will end up having a mess that nothing
> >can ever be backported to.
> >
> >How many commits need to be backported? Have you tried?
>
> I have looked into the upstream commits. The commit that removed this
> vulnerable legacy code in mainline is:
> 02e2681ffe1a ("drm/vkms: Convert to DRM's vblank timer")
>
> I tried to apply it to 6.18.y, but it does not apply cleanly. The reason
> is that this upstream commit is not a simple bug fix, but a massive
> refactoring. It completely rips out the custom VKMS hrtimer and ports
> the driver to a newly introduced DRM core infrastructure
> (DRM_CRTC_VBLANK_TIMER_FUNCS and drm_vblank_helper.h).
>
> To backport commit 02e2681ffe1a, we would first need to backport the
> entire DRM generic vblank timer infrastructure to 6.18.y. This seems
> too intrusive and violates the minimal-risk policy for stable trees.
There is no "minimal-risk policy for stable trees". And if there was,
the least ammount of risk would be to take the reviewed and tested
patches that are already in Linus's tree, and NOT take anything that is
not already there, as 90% of the time that we do that, it comes back to
bite us hard.
So please, just backport all the needed changes here. Otherwise how are
we going to deal with the merge conflicts for the next 4 years in this
file?
Or, get the maintainers of this file to agree and review this one-off
change that it is acceptable. As they are going to be the ones getting
the bug reports and not having their patches applied over the years, not
anyone else :)
thanks,
greg k-h
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re:Re: Re: [PATCH 6.18.y] drm/vkms: Fix ABBA deadlock in vblank disable and timer callback
2026-05-16 9:51 ` Greg KH
@ 2026-05-18 2:22 ` w15303746062
2026-05-25 8:55 ` Maarten Lankhorst
0 siblings, 1 reply; 18+ messages in thread
From: w15303746062 @ 2026-05-18 2:22 UTC (permalink / raw)
To: Greg KH
Cc: louis.chauvet, hamohammed.sa, simona, melissa.srw,
maarten.lankhorst, mripard, tzimmermann, airlied, dri-devel,
linux-kernel, stable, Mingyu Wang
At 2026-05-16 17:51:59, "Greg KH" <gregkh@linuxfoundation.org> wrote:
>There is no "minimal-risk policy for stable trees". And if there was,
>the least ammount of risk would be to take the reviewed and tested
>patches that are already in Linus's tree, and NOT take anything that is
>not already there, as 90% of the time that we do that, it comes back to
>bite us hard.
>
>So please, just backport all the needed changes here. Otherwise how are
>we going to deal with the merge conflicts for the next 4 years in this
>file?
>
>Or, get the maintainers of this file to agree and review this one-off
>change that it is acceptable. As they are going to be the ones getting
>the bug reports and not having their patches applied over the years, not
>anyone else :)
Hi Greg,
Got it. After looking deeper into the dependency chain, backporting the mainline commit (02e2681ffe1a) would indeed require pulling in the entire new DRM generic vblank timer infrastructure to 6.18.y.
That scope is just too large and complex for this specific issue. Since a one-off patch is not the right approach either, I will just drop this patch and abandon the backport effort for 6.18.y.
Thanks for your time and the quick review.
Thanks,
Mingyu
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 6.18.y] drm/vkms: Fix ABBA deadlock in vblank disable and timer callback
2026-05-18 2:22 ` w15303746062
@ 2026-05-25 8:55 ` Maarten Lankhorst
2026-05-25 13:16 ` [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock w15303746062
2026-05-26 11:16 ` Re:Re: [PATCH 6.18.y] drm/vkms: Fix ABBA deadlock in vblank disable and timer callback w15303746062
0 siblings, 2 replies; 18+ messages in thread
From: Maarten Lankhorst @ 2026-05-25 8:55 UTC (permalink / raw)
To: w15303746062, Greg KH
Cc: louis.chauvet, hamohammed.sa, simona, melissa.srw, mripard,
tzimmermann, airlied, dri-devel, linux-kernel, stable,
Mingyu Wang
Hello Mingyu
Den 2026-05-18 kl. 04:22, skrev w15303746062:
>
>
> At 2026-05-16 17:51:59, "Greg KH" <gregkh@linuxfoundation.org> wrote:
>> There is no "minimal-risk policy for stable trees". And if there was,
>> the least ammount of risk would be to take the reviewed and tested
>> patches that are already in Linus's tree, and NOT take anything that is
>> not already there, as 90% of the time that we do that, it comes back to
>> bite us hard.
>>
>> So please, just backport all the needed changes here. Otherwise how are
>> we going to deal with the merge conflicts for the next 4 years in this
>> file?
>>
>> Or, get the maintainers of this file to agree and review this one-off
>> change that it is acceptable. As they are going to be the ones getting
>> the bug reports and not having their patches applied over the years, not
>> anyone else :)
>
> Hi Greg,
>
> Got it. After looking deeper into the dependency chain, backporting the mainline commit (02e2681ffe1a) would indeed require pulling in the entire new DRM generic vblank timer infrastructure to 6.18.y.
>
> That scope is just too large and complex for this specific issue. Since a one-off patch is not the right approach either, I will just drop this patch and abandon the backport effort for 6.18.y.
>
> Thanks for your time and the quick review.
>
> Thanks,
> Mingyu
>
As far as I can tell, if it's just a bug affecting vkms, all you need to do
is only a few commits:
74afeb812850 ("drm/vblank: Add vblank timer")
d54dbb5963bd ("drm/vblank: Add CRTC helpers for simple use cases")
02e2681ffe1a ("drm/vkms: Convert to DRM's vblank timer")
79ae8510b5b8 ("drm/atomic: Increase timeout in drm_atomic_helper_wait_for_vblanks()")
3946d3ba9934 ("drm/vblank: Fix kernel docs for vblank timer")
There's no need to convert all other drivers if it's only vkms that you're fixing.
But since you found this bug in one driver, it might be wise to check if others
have the same bug and ask for backports for those too.
Kind regards,
~Maarten Lankhorst
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock
2026-05-25 8:55 ` Maarten Lankhorst
@ 2026-05-25 13:16 ` w15303746062
2026-05-25 13:16 ` [PATCH 6.18.y 1/5] drm/vblank: Add vblank timer w15303746062
` (5 more replies)
2026-05-26 11:16 ` Re:Re: [PATCH 6.18.y] drm/vkms: Fix ABBA deadlock in vblank disable and timer callback w15303746062
1 sibling, 6 replies; 18+ messages in thread
From: w15303746062 @ 2026-05-25 13:16 UTC (permalink / raw)
To: stable, gregkh
Cc: tzimmermann, maarten.lankhorst, mripard, louis.chauvet, dri-devel,
linux-kernel, Mingyu Wang
From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
Hi Greg and all,
This patch series backports the generic DRM vblank timer infrastructure
and converts the vkms driver to use it, specifically targeting the
6.18.y stable branch.
During local fuzzing with Syzkaller, an RCU preempt stall (ABBA deadlock)
was consistently observed in the 6.18.y vkms driver. This deadlock occurs
between the legacy drm_vblank_disable_and_save() function and the
vkms_vblank_simulate() hrtimer callback.
A previous localized patch was submitted to address this in 6.18.y using
hrtimer_try_to_cancel. However, as discussed with Greg KH and Maarten
Lankhorst on the mailing list, the correct and most maintainable approach
is to backport the mainline commits that inherently resolve this by
removing the custom vkms hrtimer entirely.
Following Maarten's roadmap, this series cherry-picks the exact
dependency chain from mainline to introduce the drm_vblank_helper
infrastructure and migrate vkms to it.
The series applies smoothly to 6.18.y and completely resolves the soft
lockup in the fuzzing environment.
Thanks,
Mingyu Wang
Thomas Zimmermann (5):
drm/vblank: Add vblank timer
drm/vblank: Add CRTC helpers for simple use cases
drm/vkms: Convert to DRM's vblank timer
drm/atomic: Increase timeout in drm_atomic_helper_wait_for_vblanks()
drm/vblank: Fix kernel docs for vblank timer
Documentation/gpu/drm-kms-helpers.rst | 12 ++
drivers/gpu/drm/Makefile | 3 +-
drivers/gpu/drm/drm_atomic_helper.c | 2 +-
drivers/gpu/drm/drm_vblank.c | 172 +++++++++++++++++++++-
drivers/gpu/drm/drm_vblank_helper.c | 176 +++++++++++++++++++++++
drivers/gpu/drm/vkms/vkms_crtc.c | 83 +----------
drivers/gpu/drm/vkms/vkms_drv.h | 2 -
include/drm/drm_modeset_helper_vtables.h | 12 ++
include/drm/drm_vblank.h | 32 +++++
include/drm/drm_vblank_helper.h | 56 ++++++++
10 files changed, 468 insertions(+), 82 deletions(-)
create mode 100644 drivers/gpu/drm/drm_vblank_helper.c
create mode 100644 include/drm/drm_vblank_helper.h
--
2.34.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 6.18.y 1/5] drm/vblank: Add vblank timer
2026-05-25 13:16 ` [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock w15303746062
@ 2026-05-25 13:16 ` w15303746062
2026-05-25 13:16 ` [PATCH 6.18.y 2/5] drm/vblank: Add CRTC helpers for simple use cases w15303746062
` (4 subsequent siblings)
5 siblings, 0 replies; 18+ messages in thread
From: w15303746062 @ 2026-05-25 13:16 UTC (permalink / raw)
To: stable, gregkh
Cc: tzimmermann, maarten.lankhorst, mripard, louis.chauvet, dri-devel,
linux-kernel, Javier Martinez Canillas, Michael Kelley
From: Thomas Zimmermann <tzimmermann@suse.de>
The vblank timer simulates a vblank interrupt for hardware without
support. Rate-limits the display update frequency.
DRM drivers for hardware without vblank support apply display updates
ASAP. A vblank event informs DRM clients of the completed update.
Userspace compositors immediately schedule the next update, which
creates significant load on virtualization outputs. Display updates
are usually fast on virtualization outputs, as their framebuffers are
in regular system memory and there's no hardware vblank interrupt to
throttle the update rate.
The vblank timer is a HR timer that signals the vblank in software.
It limits the update frequency of a DRM driver similar to a hardware
vblank interrupt. The timer is not synchronized to the actual vblank
interval of the display.
The code has been adopted from vkms, which added the funtionality
in commit 3a0709928b17 ("drm/vkms: Add vblank events simulated by
hrtimers").
The new implementation is part of the existing vblank support,
which sets up the timer automatically. Drivers only have to start
and cancel the vblank timer as part of enabling and disabling the
CRTC. The new vblank helper library provides callbacks for struct
drm_crtc_funcs.
The standard way for handling vblank is to call drm_crtc_handle_vblank().
Drivers that require additional processing, such as vkms, can init
handle_vblank_timeout in struct drm_crtc_helper_funcs to refer to
their timeout handler.
There's a possible deadlock between drm_crtc_handle_vblank() and
hrtimer_cancel(). [1] The implementation avoids to call hrtimer_cancel()
directly and instead signals to the timer function to not restart
itself.
v4:
- fix possible race condition between timeout and atomic commit (Michael)
v3:
- avoid deadlock when cancelling timer (Ville, Lyude)
v2:
- implement vblank timer entirely in vblank helpers
- downgrade overrun warning to debug
- fix docs
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Tested-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Tested-by: Michael Kelley <mhklinux@outlook.com>
Link: https://lore.kernel.org/all/20250510094757.4174662-1-zengheng4@huawei.com/ # [1]
Link: https://lore.kernel.org/r/20250916083816.30275-2-tzimmermann@suse.de
(cherry picked from commit 74afeb8128502a529041a2566febd26053a7be11)
---
Documentation/gpu/drm-kms-helpers.rst | 12 ++
drivers/gpu/drm/Makefile | 3 +-
drivers/gpu/drm/drm_vblank.c | 172 ++++++++++++++++++++++-
drivers/gpu/drm/drm_vblank_helper.c | 96 +++++++++++++
include/drm/drm_modeset_helper_vtables.h | 12 ++
include/drm/drm_vblank.h | 32 +++++
include/drm/drm_vblank_helper.h | 33 +++++
7 files changed, 357 insertions(+), 3 deletions(-)
create mode 100644 drivers/gpu/drm/drm_vblank_helper.c
create mode 100644 include/drm/drm_vblank_helper.h
diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index 5139705089f2..781129f78b06 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -92,6 +92,18 @@ GEM Atomic Helper Reference
.. kernel-doc:: drivers/gpu/drm/drm_gem_atomic_helper.c
:export:
+VBLANK Helper Reference
+-----------------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_vblank_helper.c
+ :doc: overview
+
+.. kernel-doc:: include/drm/drm_vblank_helper.h
+ :internal:
+
+.. kernel-doc:: drivers/gpu/drm/drm_vblank_helper.c
+ :export:
+
Simple KMS Helper Reference
===========================
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index da2565e6de71..7789f42027ff 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -150,7 +150,8 @@ drm_kms_helper-y := \
drm_plane_helper.o \
drm_probe_helper.o \
drm_self_refresh_helper.o \
- drm_simple_kms_helper.o
+ drm_simple_kms_helper.o \
+ drm_vblank_helper.o
drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 46f59883183d..61e211fd3c9c 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -136,8 +136,17 @@
* vblanks after a timer has expired, which can be configured through the
* ``vblankoffdelay`` module parameter.
*
- * Drivers for hardware without support for vertical-blanking interrupts
- * must not call drm_vblank_init(). For such drivers, atomic helpers will
+ * Drivers for hardware without support for vertical-blanking interrupts can
+ * use DRM vblank timers to send vblank events at the rate of the current
+ * display mode's refresh. While not synchronized to the hardware's
+ * vertical-blanking regions, the timer helps DRM clients and compositors to
+ * adapt their update cycle to the display output. Drivers should set up
+ * vblanking as usual, but call drm_crtc_vblank_start_timer() and
+ * drm_crtc_vblank_cancel_timer() as part of their atomic mode setting.
+ * See also DRM vblank helpers for more information.
+ *
+ * Drivers without support for vertical-blanking interrupts nor timers must
+ * not call drm_vblank_init(). For these drivers, atomic helpers will
* automatically generate fake vblank events as part of the display update.
* This functionality also can be controlled by the driver by enabling and
* disabling struct drm_crtc_state.no_vblank.
@@ -508,6 +517,9 @@ static void drm_vblank_init_release(struct drm_device *dev, void *ptr)
drm_WARN_ON(dev, READ_ONCE(vblank->enabled) &&
drm_core_check_feature(dev, DRIVER_MODESET));
+ if (vblank->vblank_timer.crtc)
+ hrtimer_cancel(&vblank->vblank_timer.timer);
+
drm_vblank_destroy_worker(vblank);
timer_delete_sync(&vblank->disable_timer);
}
@@ -2162,3 +2174,159 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data,
return ret;
}
+/*
+ * VBLANK timer
+ */
+
+static enum hrtimer_restart drm_vblank_timer_function(struct hrtimer *timer)
+{
+ struct drm_vblank_crtc_timer *vtimer =
+ container_of(timer, struct drm_vblank_crtc_timer, timer);
+ struct drm_crtc *crtc = vtimer->crtc;
+ const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+ struct drm_device *dev = crtc->dev;
+ unsigned long flags;
+ ktime_t interval;
+ u64 ret_overrun;
+ bool succ;
+
+ spin_lock_irqsave(&vtimer->interval_lock, flags);
+ interval = vtimer->interval;
+ spin_unlock_irqrestore(&vtimer->interval_lock, flags);
+
+ if (!interval)
+ return HRTIMER_NORESTART;
+
+ ret_overrun = hrtimer_forward_now(&vtimer->timer, interval);
+ if (ret_overrun != 1)
+ drm_dbg_vbl(dev, "vblank timer overrun\n");
+
+ if (crtc_funcs->handle_vblank_timeout)
+ succ = crtc_funcs->handle_vblank_timeout(crtc);
+ else
+ succ = drm_crtc_handle_vblank(crtc);
+ if (!succ)
+ return HRTIMER_NORESTART;
+
+ return HRTIMER_RESTART;
+}
+
+/**
+ * drm_crtc_vblank_start_timer - Starts the vblank timer on the given CRTC
+ * @crtc: the CRTC
+ *
+ * Drivers should call this function from their CRTC's enable_vblank
+ * function to start a vblank timer. The timer will fire after the duration
+ * of a full frame. drm_crtc_vblank_cancel_timer() disables a running timer.
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise.
+ */
+int drm_crtc_vblank_start_timer(struct drm_crtc *crtc)
+{
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
+ struct drm_vblank_crtc_timer *vtimer = &vblank->vblank_timer;
+ unsigned long flags;
+
+ if (!vtimer->crtc) {
+ /*
+ * Set up the data structures on the first invocation.
+ */
+ vtimer->crtc = crtc;
+ spin_lock_init(&vtimer->interval_lock);
+ hrtimer_setup(&vtimer->timer, drm_vblank_timer_function,
+ CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ } else {
+ /*
+ * Timer should not be active. If it is, wait for the
+ * previous cancel operations to finish.
+ */
+ while (hrtimer_active(&vtimer->timer))
+ hrtimer_try_to_cancel(&vtimer->timer);
+ }
+
+ drm_calc_timestamping_constants(crtc, &crtc->mode);
+
+ spin_lock_irqsave(&vtimer->interval_lock, flags);
+ vtimer->interval = ns_to_ktime(vblank->framedur_ns);
+ spin_unlock_irqrestore(&vtimer->interval_lock, flags);
+
+ hrtimer_start(&vtimer->timer, vtimer->interval, HRTIMER_MODE_REL);
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_crtc_vblank_start_timer);
+
+/**
+ * drm_crtc_vblank_start_timer - Cancels the given CRTC's vblank timer
+ * @crtc: the CRTC
+ *
+ * Drivers should call this function from their CRTC's disable_vblank
+ * function to stop a vblank timer.
+ */
+void drm_crtc_vblank_cancel_timer(struct drm_crtc *crtc)
+{
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
+ struct drm_vblank_crtc_timer *vtimer = &vblank->vblank_timer;
+ unsigned long flags;
+
+ /*
+ * Calling hrtimer_cancel() can result in a deadlock with DRM's
+ * vblank_time_lime_lock and hrtimers' softirq_expiry_lock. So
+ * clear interval and indicate cancellation. The timer function
+ * will cancel itself on the next invocation.
+ */
+
+ spin_lock_irqsave(&vtimer->interval_lock, flags);
+ vtimer->interval = 0;
+ spin_unlock_irqrestore(&vtimer->interval_lock, flags);
+
+ hrtimer_try_to_cancel(&vtimer->timer);
+}
+EXPORT_SYMBOL(drm_crtc_vblank_cancel_timer);
+
+/**
+ * drm_crtc_vblank_get_vblank_timeout - Returns the vblank timeout
+ * @crtc: The CRTC
+ * @vblank_time: Returns the next vblank timestamp
+ *
+ * The helper drm_crtc_vblank_get_vblank_timeout() returns the next vblank
+ * timestamp of the CRTC's vblank timer according to the timer's expiry
+ * time.
+ */
+void drm_crtc_vblank_get_vblank_timeout(struct drm_crtc *crtc, ktime_t *vblank_time)
+{
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
+ struct drm_vblank_crtc_timer *vtimer = &vblank->vblank_timer;
+ u64 cur_count;
+ ktime_t cur_time;
+
+ if (!READ_ONCE(vblank->enabled)) {
+ *vblank_time = ktime_get();
+ return;
+ }
+
+ /*
+ * A concurrent vblank timeout could update the expires field before
+ * we compare it with the vblank time. Hence we'd compare the old
+ * expiry time to the new vblank time; deducing the timer had already
+ * expired. Reread until we get consistent values from both fields.
+ */
+ do {
+ cur_count = drm_crtc_vblank_count_and_time(crtc, &cur_time);
+ *vblank_time = READ_ONCE(vtimer->timer.node.expires);
+ } while (cur_count != drm_crtc_vblank_count_and_time(crtc, &cur_time));
+
+ if (drm_WARN_ON(crtc->dev, !ktime_compare(*vblank_time, cur_time)))
+ return; /* Already expired */
+
+ /*
+ * To prevent races we roll the hrtimer forward before we do any
+ * interrupt processing - this is how real hw works (the interrupt
+ * is only generated after all the vblank registers are updated)
+ * and what the vblank core expects. Therefore we need to always
+ * correct the timestamp by one frame.
+ */
+ *vblank_time = ktime_sub(*vblank_time, vtimer->interval);
+}
+EXPORT_SYMBOL(drm_crtc_vblank_get_vblank_timeout);
diff --git a/drivers/gpu/drm/drm_vblank_helper.c b/drivers/gpu/drm/drm_vblank_helper.c
new file mode 100644
index 000000000000..f94d1e706191
--- /dev/null
+++ b/drivers/gpu/drm/drm_vblank_helper.c
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: MIT
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_modeset_helper_vtables.h>
+#include <drm/drm_print.h>
+#include <drm/drm_vblank.h>
+#include <drm/drm_vblank_helper.h>
+
+/**
+ * DOC: overview
+ *
+ * The vblank helper library provides functions for supporting vertical
+ * blanking in DRM drivers.
+ *
+ * For vblank timers, several callback implementations are available.
+ * Drivers enable support for vblank timers by setting the vblank callbacks
+ * in struct &drm_crtc_funcs to the helpers provided by this library. The
+ * initializer macro DRM_CRTC_VBLANK_TIMER_FUNCS does this conveniently.
+ *
+ * Once the driver enables vblank support with drm_vblank_init(), each
+ * CRTC's vblank timer fires according to the programmed display mode. By
+ * default, the vblank timer invokes drm_crtc_handle_vblank(). Drivers with
+ * more specific requirements can set their own handler function in
+ * struct &drm_crtc_helper_funcs.handle_vblank_timeout.
+ */
+
+/*
+ * VBLANK timer
+ */
+
+/**
+ * drm_crtc_vblank_helper_enable_vblank_timer - Implements struct &drm_crtc_funcs.enable_vblank
+ * @crtc: The CRTC
+ *
+ * The helper drm_crtc_vblank_helper_enable_vblank_timer() implements
+ * enable_vblank of struct drm_crtc_helper_funcs for CRTCs that require
+ * a VBLANK timer. It sets up the timer on the first invocation. The
+ * started timer expires after the current frame duration. See struct
+ * &drm_vblank_crtc.framedur_ns.
+ *
+ * See also struct &drm_crtc_helper_funcs.enable_vblank.
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise.
+ */
+int drm_crtc_vblank_helper_enable_vblank_timer(struct drm_crtc *crtc)
+{
+ return drm_crtc_vblank_start_timer(crtc);
+}
+EXPORT_SYMBOL(drm_crtc_vblank_helper_enable_vblank_timer);
+
+/**
+ * drm_crtc_vblank_helper_disable_vblank_timer - Implements struct &drm_crtc_funcs.disable_vblank
+ * @crtc: The CRTC
+ *
+ * The helper drm_crtc_vblank_helper_disable_vblank_timer() implements
+ * disable_vblank of struct drm_crtc_funcs for CRTCs that require a
+ * VBLANK timer.
+ *
+ * See also struct &drm_crtc_helper_funcs.disable_vblank.
+ */
+void drm_crtc_vblank_helper_disable_vblank_timer(struct drm_crtc *crtc)
+{
+ drm_crtc_vblank_cancel_timer(crtc);
+}
+EXPORT_SYMBOL(drm_crtc_vblank_helper_disable_vblank_timer);
+
+/**
+ * drm_crtc_vblank_helper_get_vblank_timestamp_from_timer -
+ * Implements struct &drm_crtc_funcs.get_vblank_timestamp
+ * @crtc: The CRTC
+ * @max_error: Maximum acceptable error
+ * @vblank_time: Returns the next vblank timestamp
+ * @in_vblank_irq: True is called from drm_crtc_handle_vblank()
+ *
+ * The helper drm_crtc_helper_get_vblank_timestamp_from_timer() implements
+ * get_vblank_timestamp of struct drm_crtc_funcs for CRTCs that require a
+ * VBLANK timer. It returns the timestamp according to the timer's expiry
+ * time.
+ *
+ * See also struct &drm_crtc_funcs.get_vblank_timestamp.
+ *
+ * Returns:
+ * True on success, or false otherwise.
+ */
+bool drm_crtc_vblank_helper_get_vblank_timestamp_from_timer(struct drm_crtc *crtc,
+ int *max_error,
+ ktime_t *vblank_time,
+ bool in_vblank_irq)
+{
+ drm_crtc_vblank_get_vblank_timeout(crtc, vblank_time);
+
+ return true;
+}
+EXPORT_SYMBOL(drm_crtc_vblank_helper_get_vblank_timestamp_from_timer);
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index ce7c7aeac887..fe32854b7ffe 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -490,6 +490,18 @@ struct drm_crtc_helper_funcs {
bool in_vblank_irq, int *vpos, int *hpos,
ktime_t *stime, ktime_t *etime,
const struct drm_display_mode *mode);
+
+ /**
+ * @handle_vblank_timeout: Handles timeouts of the vblank timer.
+ *
+ * Called by CRTC's the vblank timer on each timeout. Semantics is
+ * equivalient to drm_crtc_handle_vblank(). Implementations should
+ * invoke drm_crtc_handle_vblank() as part of processing the timeout.
+ *
+ * This callback is optional. If unset, the vblank timer invokes
+ * drm_crtc_handle_vblank() directly.
+ */
+ bool (*handle_vblank_timeout)(struct drm_crtc *crtc);
};
/**
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index 151ab1e85b1b..ffa564d79638 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -25,6 +25,7 @@
#define _DRM_VBLANK_H_
#include <linux/seqlock.h>
+#include <linux/hrtimer.h>
#include <linux/idr.h>
#include <linux/poll.h>
#include <linux/kthread.h>
@@ -103,6 +104,28 @@ struct drm_vblank_crtc_config {
bool disable_immediate;
};
+/**
+ * struct drm_vblank_crtc_timer - vblank timer for a CRTC
+ */
+struct drm_vblank_crtc_timer {
+ /**
+ * @timer: The vblank's high-resolution timer
+ */
+ struct hrtimer timer;
+ /**
+ * @interval_lock: Protects @interval
+ */
+ spinlock_t interval_lock;
+ /**
+ * @interval: Duration between two vblanks
+ */
+ ktime_t interval;
+ /**
+ * @crtc: The timer's CRTC
+ */
+ struct drm_crtc *crtc;
+};
+
/**
* struct drm_vblank_crtc - vblank tracking for a CRTC
*
@@ -254,6 +277,11 @@ struct drm_vblank_crtc {
* cancelled.
*/
wait_queue_head_t work_wait_queue;
+
+ /**
+ * @vblank_timer: Holds the state of the vblank timer
+ */
+ struct drm_vblank_crtc_timer vblank_timer;
};
struct drm_vblank_crtc *drm_crtc_vblank_crtc(struct drm_crtc *crtc);
@@ -290,6 +318,10 @@ wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc);
void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc,
u32 max_vblank_count);
+int drm_crtc_vblank_start_timer(struct drm_crtc *crtc);
+void drm_crtc_vblank_cancel_timer(struct drm_crtc *crtc);
+void drm_crtc_vblank_get_vblank_timeout(struct drm_crtc *crtc, ktime_t *vblank_time);
+
/*
* Helpers for struct drm_crtc_funcs
*/
diff --git a/include/drm/drm_vblank_helper.h b/include/drm/drm_vblank_helper.h
new file mode 100644
index 000000000000..74a971d0cfba
--- /dev/null
+++ b/include/drm/drm_vblank_helper.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _DRM_VBLANK_HELPER_H_
+#define _DRM_VBLANK_HELPER_H_
+
+#include <linux/hrtimer_types.h>
+#include <linux/types.h>
+
+struct drm_crtc;
+
+/*
+ * VBLANK timer
+ */
+
+int drm_crtc_vblank_helper_enable_vblank_timer(struct drm_crtc *crtc);
+void drm_crtc_vblank_helper_disable_vblank_timer(struct drm_crtc *crtc);
+bool drm_crtc_vblank_helper_get_vblank_timestamp_from_timer(struct drm_crtc *crtc,
+ int *max_error,
+ ktime_t *vblank_time,
+ bool in_vblank_irq);
+
+/**
+ * DRM_CRTC_VBLANK_TIMER_FUNCS - Default implementation for VBLANK timers
+ *
+ * This macro initializes struct &drm_crtc_funcs to default helpers for
+ * VBLANK timers.
+ */
+#define DRM_CRTC_VBLANK_TIMER_FUNCS \
+ .enable_vblank = drm_crtc_vblank_helper_enable_vblank_timer, \
+ .disable_vblank = drm_crtc_vblank_helper_disable_vblank_timer, \
+ .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp_from_timer
+
+#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 6.18.y 2/5] drm/vblank: Add CRTC helpers for simple use cases
2026-05-25 13:16 ` [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock w15303746062
2026-05-25 13:16 ` [PATCH 6.18.y 1/5] drm/vblank: Add vblank timer w15303746062
@ 2026-05-25 13:16 ` w15303746062
2026-05-25 13:16 ` [PATCH 6.18.y 3/5] drm/vkms: Convert to DRM's vblank timer w15303746062
` (3 subsequent siblings)
5 siblings, 0 replies; 18+ messages in thread
From: w15303746062 @ 2026-05-25 13:16 UTC (permalink / raw)
To: stable, gregkh
Cc: tzimmermann, maarten.lankhorst, mripard, louis.chauvet, dri-devel,
linux-kernel, Javier Martinez Canillas, Michael Kelley
From: Thomas Zimmermann <tzimmermann@suse.de>
Implement atomic_flush, atomic_enable and atomic_disable of struct
drm_crtc_helper_funcs for vblank handling. Driver with no further
requirements can use these functions instead of adding their own.
Also simplifies the use of vblank timers.
The code has been adopted from vkms, which added the funtionality
in commit 3a0709928b17 ("drm/vkms: Add vblank events simulated by
hrtimers").
v3:
- mention vkms (Javier)
v2:
- fix docs
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Tested-by: Michael Kelley <mhklinux@outlook.com>
Link: https://lore.kernel.org/r/20250916083816.30275-3-tzimmermann@suse.de
(cherry picked from commit d54dbb5963bdbdf8559903fe2b2343e871adcb30)
---
drivers/gpu/drm/drm_vblank_helper.c | 80 +++++++++++++++++++++++++++++
include/drm/drm_vblank_helper.h | 23 +++++++++
2 files changed, 103 insertions(+)
diff --git a/drivers/gpu/drm/drm_vblank_helper.c b/drivers/gpu/drm/drm_vblank_helper.c
index f94d1e706191..a04a6ba1b0ca 100644
--- a/drivers/gpu/drm/drm_vblank_helper.c
+++ b/drivers/gpu/drm/drm_vblank_helper.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: MIT
+#include <drm/drm_atomic.h>
#include <drm/drm_crtc.h>
#include <drm/drm_managed.h>
#include <drm/drm_modeset_helper_vtables.h>
@@ -17,6 +18,12 @@
* Drivers enable support for vblank timers by setting the vblank callbacks
* in struct &drm_crtc_funcs to the helpers provided by this library. The
* initializer macro DRM_CRTC_VBLANK_TIMER_FUNCS does this conveniently.
+ * The driver further has to send the VBLANK event from its atomic_flush
+ * callback and control vblank from the CRTC's atomic_enable and atomic_disable
+ * callbacks. The callbacks are located in struct &drm_crtc_helper_funcs.
+ * The vblank helper library provides implementations of these callbacks
+ * for drivers without further requirements. The initializer macro
+ * DRM_CRTC_HELPER_VBLANK_FUNCS sets them coveniently.
*
* Once the driver enables vblank support with drm_vblank_init(), each
* CRTC's vblank timer fires according to the programmed display mode. By
@@ -25,6 +32,79 @@
* struct &drm_crtc_helper_funcs.handle_vblank_timeout.
*/
+/*
+ * VBLANK helpers
+ */
+
+/**
+ * drm_crtc_vblank_atomic_flush -
+ * Implements struct &drm_crtc_helper_funcs.atomic_flush
+ * @crtc: The CRTC
+ * @state: The atomic state to apply
+ *
+ * The helper drm_crtc_vblank_atomic_flush() implements atomic_flush of
+ * struct drm_crtc_helper_funcs for CRTCs that only need to send out a
+ * VBLANK event.
+ *
+ * See also struct &drm_crtc_helper_funcs.atomic_flush.
+ */
+void drm_crtc_vblank_atomic_flush(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+ struct drm_pending_vblank_event *event;
+
+ spin_lock_irq(&dev->event_lock);
+
+ event = crtc_state->event;
+ crtc_state->event = NULL;
+
+ if (event) {
+ if (drm_crtc_vblank_get(crtc) == 0)
+ drm_crtc_arm_vblank_event(crtc, event);
+ else
+ drm_crtc_send_vblank_event(crtc, event);
+ }
+
+ spin_unlock_irq(&dev->event_lock);
+}
+EXPORT_SYMBOL(drm_crtc_vblank_atomic_flush);
+
+/**
+ * drm_crtc_vblank_atomic_enable - Implements struct &drm_crtc_helper_funcs.atomic_enable
+ * @crtc: The CRTC
+ * @state: The atomic state
+ *
+ * The helper drm_crtc_vblank_atomic_enable() implements atomic_enable
+ * of struct drm_crtc_helper_funcs for CRTCs the only need to enable VBLANKs.
+ *
+ * See also struct &drm_crtc_helper_funcs.atomic_enable.
+ */
+void drm_crtc_vblank_atomic_enable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ drm_crtc_vblank_on(crtc);
+}
+EXPORT_SYMBOL(drm_crtc_vblank_atomic_enable);
+
+/**
+ * drm_crtc_vblank_atomic_disable - Implements struct &drm_crtc_helper_funcs.atomic_disable
+ * @crtc: The CRTC
+ * @state: The atomic state
+ *
+ * The helper drm_crtc_vblank_atomic_disable() implements atomic_disable
+ * of struct drm_crtc_helper_funcs for CRTCs the only need to disable VBLANKs.
+ *
+ * See also struct &drm_crtc_funcs.atomic_disable.
+ */
+void drm_crtc_vblank_atomic_disable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+ drm_crtc_vblank_off(crtc);
+}
+EXPORT_SYMBOL(drm_crtc_vblank_atomic_disable);
+
/*
* VBLANK timer
*/
diff --git a/include/drm/drm_vblank_helper.h b/include/drm/drm_vblank_helper.h
index 74a971d0cfba..fcd8a9b35846 100644
--- a/include/drm/drm_vblank_helper.h
+++ b/include/drm/drm_vblank_helper.h
@@ -6,8 +6,31 @@
#include <linux/hrtimer_types.h>
#include <linux/types.h>
+struct drm_atomic_state;
struct drm_crtc;
+/*
+ * VBLANK helpers
+ */
+
+void drm_crtc_vblank_atomic_flush(struct drm_crtc *crtc,
+ struct drm_atomic_state *state);
+void drm_crtc_vblank_atomic_enable(struct drm_crtc *crtc,
+ struct drm_atomic_state *state);
+void drm_crtc_vblank_atomic_disable(struct drm_crtc *crtc,
+ struct drm_atomic_state *crtc_state);
+
+/**
+ * DRM_CRTC_HELPER_VBLANK_FUNCS - Default implementation for VBLANK helpers
+ *
+ * This macro initializes struct &drm_crtc_helper_funcs to default helpers
+ * for VBLANK handling.
+ */
+#define DRM_CRTC_HELPER_VBLANK_FUNCS \
+ .atomic_flush = drm_crtc_vblank_atomic_flush, \
+ .atomic_enable = drm_crtc_vblank_atomic_enable, \
+ .atomic_disable = drm_crtc_vblank_atomic_disable
+
/*
* VBLANK timer
*/
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 6.18.y 3/5] drm/vkms: Convert to DRM's vblank timer
2026-05-25 13:16 ` [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock w15303746062
2026-05-25 13:16 ` [PATCH 6.18.y 1/5] drm/vblank: Add vblank timer w15303746062
2026-05-25 13:16 ` [PATCH 6.18.y 2/5] drm/vblank: Add CRTC helpers for simple use cases w15303746062
@ 2026-05-25 13:16 ` w15303746062
2026-05-25 13:16 ` [PATCH 6.18.y 4/5] drm/atomic: Increase timeout in drm_atomic_helper_wait_for_vblanks() w15303746062
` (2 subsequent siblings)
5 siblings, 0 replies; 18+ messages in thread
From: w15303746062 @ 2026-05-25 13:16 UTC (permalink / raw)
To: stable, gregkh
Cc: tzimmermann, maarten.lankhorst, mripard, louis.chauvet, dri-devel,
linux-kernel, Javier Martinez Canillas
From: Thomas Zimmermann <tzimmermann@suse.de>
Replace vkms' vblank timer with the DRM implementation. The DRM
code is identical in concept, but differs in implementation.
Vblank timers are covered in vblank helpers and initializer macros,
so remove the corresponding hrtimer in struct vkms_output. The
vblank timer calls vkms' custom timeout code via handle_vblank_timeout
in struct drm_crtc_helper_funcs.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Tested-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://lore.kernel.org/r/20250916083816.30275-4-tzimmermann@suse.de
(cherry picked from commit 02e2681ffe1addde1fc8c35d05657b16bfa79613)
---
drivers/gpu/drm/vkms/vkms_crtc.c | 83 +++-----------------------------
drivers/gpu/drm/vkms/vkms_drv.h | 2 -
2 files changed, 7 insertions(+), 78 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index e60573e0f3e9..bd79f24686dc 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -7,25 +7,18 @@
#include <drm/drm_managed.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
+#include <drm/drm_vblank_helper.h>
#include "vkms_drv.h"
-static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
+static bool vkms_crtc_handle_vblank_timeout(struct drm_crtc *crtc)
{
- struct vkms_output *output = container_of(timer, struct vkms_output,
- vblank_hrtimer);
- struct drm_crtc *crtc = &output->crtc;
+ struct vkms_output *output = drm_crtc_to_vkms_output(crtc);
struct vkms_crtc_state *state;
- u64 ret_overrun;
bool ret, fence_cookie;
fence_cookie = dma_fence_begin_signalling();
- ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
- output->period_ns);
- if (ret_overrun != 1)
- pr_warn("%s: vblank timer overrun\n", __func__);
-
spin_lock(&output->lock);
ret = drm_crtc_handle_vblank(crtc);
if (!ret)
@@ -57,55 +50,6 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
dma_fence_end_signalling(fence_cookie);
- return HRTIMER_RESTART;
-}
-
-static int vkms_enable_vblank(struct drm_crtc *crtc)
-{
- struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
- struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
-
- hrtimer_setup(&out->vblank_hrtimer, &vkms_vblank_simulate, CLOCK_MONOTONIC,
- HRTIMER_MODE_REL);
- out->period_ns = ktime_set(0, vblank->framedur_ns);
- hrtimer_start(&out->vblank_hrtimer, out->period_ns, HRTIMER_MODE_REL);
-
- return 0;
-}
-
-static void vkms_disable_vblank(struct drm_crtc *crtc)
-{
- struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
-
- hrtimer_cancel(&out->vblank_hrtimer);
-}
-
-static bool vkms_get_vblank_timestamp(struct drm_crtc *crtc,
- int *max_error, ktime_t *vblank_time,
- bool in_vblank_irq)
-{
- struct vkms_output *output = drm_crtc_to_vkms_output(crtc);
- struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
-
- if (!READ_ONCE(vblank->enabled)) {
- *vblank_time = ktime_get();
- return true;
- }
-
- *vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
-
- if (WARN_ON(*vblank_time == vblank->time))
- return true;
-
- /*
- * To prevent races we roll the hrtimer forward before we do any
- * interrupt processing - this is how real hw works (the interrupt is
- * only generated after all the vblank registers are updated) and what
- * the vblank core expects. Therefore we need to always correct the
- * timestampe by one frame.
- */
- *vblank_time -= output->period_ns;
-
return true;
}
@@ -159,9 +103,7 @@ static const struct drm_crtc_funcs vkms_crtc_funcs = {
.reset = vkms_atomic_crtc_reset,
.atomic_duplicate_state = vkms_atomic_crtc_duplicate_state,
.atomic_destroy_state = vkms_atomic_crtc_destroy_state,
- .enable_vblank = vkms_enable_vblank,
- .disable_vblank = vkms_disable_vblank,
- .get_vblank_timestamp = vkms_get_vblank_timestamp,
+ DRM_CRTC_VBLANK_TIMER_FUNCS,
.get_crc_sources = vkms_get_crc_sources,
.set_crc_source = vkms_set_crc_source,
.verify_crc_source = vkms_verify_crc_source,
@@ -213,18 +155,6 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
return 0;
}
-static void vkms_crtc_atomic_enable(struct drm_crtc *crtc,
- struct drm_atomic_state *state)
-{
- drm_crtc_vblank_on(crtc);
-}
-
-static void vkms_crtc_atomic_disable(struct drm_crtc *crtc,
- struct drm_atomic_state *state)
-{
- drm_crtc_vblank_off(crtc);
-}
-
static void vkms_crtc_atomic_begin(struct drm_crtc *crtc,
struct drm_atomic_state *state)
__acquires(&vkms_output->lock)
@@ -265,8 +195,9 @@ static const struct drm_crtc_helper_funcs vkms_crtc_helper_funcs = {
.atomic_check = vkms_crtc_atomic_check,
.atomic_begin = vkms_crtc_atomic_begin,
.atomic_flush = vkms_crtc_atomic_flush,
- .atomic_enable = vkms_crtc_atomic_enable,
- .atomic_disable = vkms_crtc_atomic_disable,
+ .atomic_enable = drm_crtc_vblank_atomic_enable,
+ .atomic_disable = drm_crtc_vblank_atomic_disable,
+ .handle_vblank_timeout = vkms_crtc_handle_vblank_timeout,
};
struct vkms_output *vkms_crtc_init(struct drm_device *dev, struct drm_plane *primary,
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 8013c31efe3b..fb9711e1c6fb 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -215,8 +215,6 @@ struct vkms_output {
struct drm_crtc crtc;
struct drm_writeback_connector wb_connector;
struct drm_encoder wb_encoder;
- struct hrtimer vblank_hrtimer;
- ktime_t period_ns;
struct workqueue_struct *composer_workq;
spinlock_t lock;
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 6.18.y 4/5] drm/atomic: Increase timeout in drm_atomic_helper_wait_for_vblanks()
2026-05-25 13:16 ` [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock w15303746062
` (2 preceding siblings ...)
2026-05-25 13:16 ` [PATCH 6.18.y 3/5] drm/vkms: Convert to DRM's vblank timer w15303746062
@ 2026-05-25 13:16 ` w15303746062
2026-05-25 13:16 ` [PATCH 6.18.y 5/5] drm/vblank: Fix kernel docs for vblank timer w15303746062
2026-05-26 11:35 ` [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock Sasha Levin
5 siblings, 0 replies; 18+ messages in thread
From: w15303746062 @ 2026-05-25 13:16 UTC (permalink / raw)
To: stable, gregkh
Cc: tzimmermann, maarten.lankhorst, mripard, louis.chauvet, dri-devel,
linux-kernel, syzbot+fcede535e7eb57cf5b43,
Ville Syrjälä
From: Thomas Zimmermann <tzimmermann@suse.de>
Increase the timeout for vblank events from 100 ms to 1000 ms. This
is the same fix as in commit f050da08a4ed ("drm/vblank: Increase
timeout in drm_wait_one_vblank()") for another vblank timeout.
After merging generic DRM vblank timers [1] and converting several
DRM drivers for virtual hardware, these drivers synchronize their
vblank events to the display refresh rate. This can trigger timeouts
within the DRM framework.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://lore.kernel.org/dri-devel/20250904145806.430568-1-tzimmermann@suse.de/ # [1]
Reported-by: syzbot+fcede535e7eb57cf5b43@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/dri-devel/69381d6c.050a0220.4004e.0017.GAE@google.com/
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Fixes: 74afeb812850 ("drm/vblank: Add vblank timer")
Link: https://patch.msgid.link/20251209143325.102056-1-tzimmermann@suse.de
(cherry picked from commit 79ae8510b5b81b9500370f89c619b50ca9c0990f)
---
drivers/gpu/drm/drm_atomic_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index d5ebe6ea0acb..f9d328dcaed8 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1837,7 +1837,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
ret = wait_event_timeout(dev->vblank[i].queue,
state->crtcs[i].last_vblank_count !=
drm_crtc_vblank_count(crtc),
- msecs_to_jiffies(100));
+ msecs_to_jiffies(1000));
WARN(!ret, "[CRTC:%d:%s] vblank wait timed out\n",
crtc->base.id, crtc->name);
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 6.18.y 5/5] drm/vblank: Fix kernel docs for vblank timer
2026-05-25 13:16 ` [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock w15303746062
` (3 preceding siblings ...)
2026-05-25 13:16 ` [PATCH 6.18.y 4/5] drm/atomic: Increase timeout in drm_atomic_helper_wait_for_vblanks() w15303746062
@ 2026-05-25 13:16 ` w15303746062
2026-05-26 11:35 ` [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock Sasha Levin
5 siblings, 0 replies; 18+ messages in thread
From: w15303746062 @ 2026-05-25 13:16 UTC (permalink / raw)
To: stable, gregkh
Cc: tzimmermann, maarten.lankhorst, mripard, louis.chauvet, dri-devel,
linux-kernel, Stephen Rothwell, Javier Martinez Canillas,
David Airlie, Simona Vetter
From: Thomas Zimmermann <tzimmermann@suse.de>
Fix documentation for drm_crtc_vblank_start_timer(), which referred
to drm_crtc_vblank_cancel_timer().
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Closes: https://lore.kernel.org/dri-devel/20251106152201.6f248c09@canb.auug.org.au/
Fixes: 74afeb812850 ("drm/vblank: Add vblank timer")
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Louis Chauvet <louis.chauvet@bootlin.com>
Cc: Javier Martinez Canillas <javierm@redhat.com>
Cc: David Airlie <airlied@gmail.com>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: dri-devel@lists.freedesktop.org
Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
Link: https://patch.msgid.link/20251106073207.11192-1-tzimmermann@suse.de
(cherry picked from commit 3946d3ba99342f3b9996e621f05e7003d4308171)
---
drivers/gpu/drm/drm_vblank.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 61e211fd3c9c..451ec9620226 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -2258,7 +2258,7 @@ int drm_crtc_vblank_start_timer(struct drm_crtc *crtc)
EXPORT_SYMBOL(drm_crtc_vblank_start_timer);
/**
- * drm_crtc_vblank_start_timer - Cancels the given CRTC's vblank timer
+ * drm_crtc_vblank_cancel_timer - Cancels the given CRTC's vblank timer
* @crtc: the CRTC
*
* Drivers should call this function from their CRTC's disable_vblank
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re:Re: [PATCH 6.18.y] drm/vkms: Fix ABBA deadlock in vblank disable and timer callback
2026-05-25 8:55 ` Maarten Lankhorst
2026-05-25 13:16 ` [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock w15303746062
@ 2026-05-26 11:16 ` w15303746062
1 sibling, 0 replies; 18+ messages in thread
From: w15303746062 @ 2026-05-26 11:16 UTC (permalink / raw)
To: Maarten Lankhorst
Cc: Greg KH, louis.chauvet, hamohammed.sa, simona, melissa.srw,
mripard, tzimmermann, airlied, dri-devel, linux-kernel, stable,
Mingyu Wang
Hi Maarten,
>As far as I can tell, if it's just a bug affecting vkms, all you need to do
>is only a few commits:
>
>74afeb812850 ("drm/vblank: Add vblank timer")
>d54dbb5963bd ("drm/vblank: Add CRTC helpers for simple use cases")
>02e2681ffe1a ("drm/vkms: Convert to DRM's vblank timer")
>79ae8510b5b8 ("drm/atomic: Increase timeout in drm_atomic_helper_wait_for_vblanks()")
>3946d3ba9934 ("drm/vblank: Fix kernel docs for vblank timer")
>
>There's no need to convert all other drivers if it's only vkms that you're fixing.
Thank you very much for pointing out this precise dependency chain. It completely saved the backport effort. I have cherry-picked these 5 commits onto the 6.18.y branch, and they apply cleanly without pulling in the massive DRM core refactoring.
This series completely resolves the Syzkaller RCU stall (soft lockup) I was observing in my local fuzzing environment. I have just submitted this 5-patch series to the list.
>But since you found this bug in one driver, it might be wise to check if others
>have the same bug and ask for backports for those too.
Following your suggestion, I conducted a static lock dependency audit across the drivers/gpu/drm/ subsystem in the 6.18.y tree, specifically looking for similar abuses of hrtimer_cancel paired with custom vblank/polling timers.
I audited the highly suspicious candidates, including:
1. i915/gvt (virtual display emulation: vblank_timer_fn vs intel_vgpu_clean_display)
2. xe (OA buffer polling: xe_oa_poll_check_timer_cb vs xe_oa_stream_disable)
3. msm (fence deadlines & devfreq: deadline_timer vs msm_update_fence)
Fortunately, these drivers are structurally safe from this specific ABBA deadlock pattern. They successfully avoid it either by heavily decoupling the timer callback from the lock context via workqueues (msm_fence and i915/gvt only use the timer to safely wake_up or queue work without holding mutexes/spinlocks), or by utilizing fine-grained locking where the cancel path and the timer callback do not contest the same lock (xe stream polling).
Therefore, it seems vkms was a unique legacy outlier in this regard. No further backports are needed for other DRM drivers for this specific vulnerability.
Thanks again for the roadmap and the thorough review.
Best regards,
Mingyu
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock
2026-05-25 13:16 ` [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock w15303746062
` (4 preceding siblings ...)
2026-05-25 13:16 ` [PATCH 6.18.y 5/5] drm/vblank: Fix kernel docs for vblank timer w15303746062
@ 2026-05-26 11:35 ` Sasha Levin
2026-05-26 12:06 ` w15303746062
5 siblings, 1 reply; 18+ messages in thread
From: Sasha Levin @ 2026-05-26 11:35 UTC (permalink / raw)
To: stable, gregkh
Cc: Sasha Levin, tzimmermann, maarten.lankhorst, mripard,
louis.chauvet, dri-devel, linux-kernel, Mingyu Wang, w15303746062
> [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock
>
> 1/5 drm/vblank: Add vblank timer (74afeb812850)
> 2/5 drm/vblank: Add CRTC helpers for simple use cases (d54dbb5963bd)
> 3/5 drm/vkms: Convert to DRM's vblank timer (02e2681ffe1a)
> 4/5 drm/atomic: Increase timeout in drm_atomic_helper_wait_for_vblanks() (79ae8510b5b8)
> 5/5 drm/vblank: Fix kernel docs for vblank timer (3946d3ba9934)
Thanks for putting this together.
Looking at the five commits:
- 1/5 (74afeb812850) is the one that actually fixes the ABBA
deadlock you observed under Syzkaller; it adds the generic vblank
timer that replaces the open-coded vkms hrtimer path.
- 2/5 (d54dbb5963bd) adds new CRTC helpers for "simple use cases".
No Fixes:/Cc:stable, no described bug.
- 3/5 (02e2681ffe1a) is a refactor that converts vkms to the new
helpers. No Fixes:/Cc:stable, no described bug.
- 4/5 (79ae8510b5b8) is a v7.1-rc1 timeout bump that depends on 1/5.
It is not yet in any released stable, so applying it to 6.18.y
would put it on an LTS before any LTS contains it.
- 5/5 (3946d3ba9934) is a doc fix for 1/5.
Per stable-kernel-rules, what I need to queue is the minimum set that
fixes the bug. Could you explain, per patch, why 2/5..5/5 are required
to make 1/5 work / are required to actually fix the deadlock? If only
1/5 is needed, please resend just that one with your Signed-off-by
added (the carried patches today only have Thomas's S-o-b, which
breaks the chain of custody on a stable submission).
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re:Re: [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock
2026-05-26 11:35 ` [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock Sasha Levin
@ 2026-05-26 12:06 ` w15303746062
2026-05-26 12:48 ` Maarten Lankhorst
0 siblings, 1 reply; 18+ messages in thread
From: w15303746062 @ 2026-05-26 12:06 UTC (permalink / raw)
To: Sasha Levin
Cc: stable, gregkh, tzimmermann, maarten.lankhorst, mripard,
louis.chauvet, dri-devel, linux-kernel, Mingyu Wang
Hi Sasha,
>Looking at the five commits:
>
> - 1/5 (74afeb812850) is the one that actually fixes the ABBA
> deadlock you observed under Syzkaller; it adds the generic vblank
> timer that replaces the open-coded vkms hrtimer path.
>
> - 2/5 (d54dbb5963bd) adds new CRTC helpers for "simple use cases".
> No Fixes:/Cc:stable, no described bug.
>
> - 3/5 (02e2681ffe1a) is a refactor that converts vkms to the new
> helpers. No Fixes:/Cc:stable, no described bug.
>
> - 4/5 (79ae8510b5b8) is a v7.1-rc1 timeout bump that depends on 1/5.
> It is not yet in any released stable, so applying it to 6.18.y
> would put it on an LTS before any LTS contains it.
>
> - 5/5 (3946d3ba9934) is a doc fix for 1/5.
>
>Per stable-kernel-rules, what I need to queue is the minimum set that
>fixes the bug. Could you explain, per patch, why 2/5..5/5 are required
>to make 1/5 work / are required to actually fix the deadlock? If only
>1/5 is needed, please resend just that one with your Signed-off-by
>added (the carried patches today only have Thomas's S-o-b, which
>breaks the chain of custody on a stable submission).
Thanks for the quick review and for pointing out the missing Signed-off-by. I apologize for that omission; it was my mistake during the cherry-pick process.
Regarding the dependency chain, I would like to clarify why commit 1/5 alone cannot fix the issue:
Commits 1/5 and 2/5 introduce the new generic vblank timer infrastructure to the DRM core but do *not* touch the vkms driver at all.
Commit 3/5 (02e2681ffe1a) is the actual fix that modifies `drivers/gpu/drm/vkms/vkms_crtc.c`. It removes the buggy open-coded hrtimer that causes the ABBA deadlock and switches vkms to use the new infrastructure introduced in 1/5 and 2/5.
Therefore, 1/5, 2/5, and 3/5 form an indivisible set. Applying only 1/5 would leave the deadlock in vkms completely unpatched.
As for 4/5 and 5/5 (the timeout bump and doc fix), Maarten Lankhorst (DRM maintainer) explicitly recommended pulling in this exact 5-commit list as the proper upstream fix for this specific vkms issue (see the mailing list link in this thread).
However, if you feel 4/5 and 5/5 introduce unnecessary risk for the 6.18.y stable tree, I can absolutely drop them and only submit 1/5, 2/5, and 3/5.
I am preparing a v2 patch series now with my Signed-off-by added to the chain of custody. Could you let me know if you prefer the full 5-patch series as recommended by DRM maintainers, or just the minimal 3-patch series?
Best regards,
Mingyu
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock
2026-05-26 12:06 ` w15303746062
@ 2026-05-26 12:48 ` Maarten Lankhorst
2026-05-26 12:50 ` Sasha Levin
0 siblings, 1 reply; 18+ messages in thread
From: Maarten Lankhorst @ 2026-05-26 12:48 UTC (permalink / raw)
To: w15303746062, Sasha Levin
Cc: stable, gregkh, tzimmermann, mripard, louis.chauvet, dri-devel,
linux-kernel, Mingyu Wang
Hello,
Den 2026-05-26 kl. 14:06, skrev w15303746062:
>
> Hi Sasha,
>
>> Looking at the five commits:
>>
>> - 1/5 (74afeb812850) is the one that actually fixes the ABBA
>> deadlock you observed under Syzkaller; it adds the generic vblank
>> timer that replaces the open-coded vkms hrtimer path.
>>
>> - 2/5 (d54dbb5963bd) adds new CRTC helpers for "simple use cases".
>> No Fixes:/Cc:stable, no described bug.
>>
>> - 3/5 (02e2681ffe1a) is a refactor that converts vkms to the new
>> helpers. No Fixes:/Cc:stable, no described bug.
>>
>> - 4/5 (79ae8510b5b8) is a v7.1-rc1 timeout bump that depends on 1/5.
>> It is not yet in any released stable, so applying it to 6.18.y
>> would put it on an LTS before any LTS contains it.
>>
>> - 5/5 (3946d3ba9934) is a doc fix for 1/5.
>>
>> Per stable-kernel-rules, what I need to queue is the minimum set that
>> fixes the bug. Could you explain, per patch, why 2/5..5/5 are required
>> to make 1/5 work / are required to actually fix the deadlock? If only
>> 1/5 is needed, please resend just that one with your Signed-off-by
>> added (the carried patches today only have Thomas's S-o-b, which
>> breaks the chain of custody on a stable submission).
>
> Thanks for the quick review and for pointing out the missing Signed-off-by. I apologize for that omission; it was my mistake during the cherry-pick process.
>
> Regarding the dependency chain, I would like to clarify why commit 1/5 alone cannot fix the issue:
>
> Commits 1/5 and 2/5 introduce the new generic vblank timer infrastructure to the DRM core but do *not* touch the vkms driver at all.
> Commit 3/5 (02e2681ffe1a) is the actual fix that modifies `drivers/gpu/drm/vkms/vkms_crtc.c`. It removes the buggy open-coded hrtimer that causes the ABBA deadlock and switches vkms to use the new infrastructure introduced in 1/5 and 2/5.
>
> Therefore, 1/5, 2/5, and 3/5 form an indivisible set. Applying only 1/5 would leave the deadlock in vkms completely unpatched.
>
> As for 4/5 and 5/5 (the timeout bump and doc fix), Maarten Lankhorst (DRM maintainer) explicitly recommended pulling in this exact 5-commit list as the proper upstream fix for this specific vkms issue (see the mailing list link in this thread).
>
> However, if you feel 4/5 and 5/5 introduce unnecessary risk for the 6.18.y stable tree, I can absolutely drop them and only submit 1/5, 2/5, and 3/5.
>
> I am preparing a v2 patch series now with my Signed-off-by added to the chain of custody. Could you let me know if you prefer the full 5-patch series as recommended by DRM maintainers, or just the minimal 3-patch series?
>
> Best regards,
> Mingyu
5/5 might strictly speaking not be needed as it's a documentation fix and I have no idea of the policy about those.
The reporter made a bug report of an ABBA deadlock that was fixed in upstream by the first 4 patches, perhaps it's good to those attach here to this discussion.
Kind regards,
~Maarten Lankhorst
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock
2026-05-26 12:48 ` Maarten Lankhorst
@ 2026-05-26 12:50 ` Sasha Levin
2026-05-26 12:59 ` Maarten Lankhorst
0 siblings, 1 reply; 18+ messages in thread
From: Sasha Levin @ 2026-05-26 12:50 UTC (permalink / raw)
To: Maarten Lankhorst
Cc: w15303746062, stable, gregkh, tzimmermann, mripard, louis.chauvet,
dri-devel, linux-kernel, Mingyu Wang
On Tue, May 26, 2026 at 02:48:55PM +0200, Maarten Lankhorst wrote:
>Hello,
>
>Den 2026-05-26 kl. 14:06, skrev w15303746062:
>>
>> Hi Sasha,
>>
>>> Looking at the five commits:
>>>
>>> - 1/5 (74afeb812850) is the one that actually fixes the ABBA
>>> deadlock you observed under Syzkaller; it adds the generic vblank
>>> timer that replaces the open-coded vkms hrtimer path.
>>>
>>> - 2/5 (d54dbb5963bd) adds new CRTC helpers for "simple use cases".
>>> No Fixes:/Cc:stable, no described bug.
>>>
>>> - 3/5 (02e2681ffe1a) is a refactor that converts vkms to the new
>>> helpers. No Fixes:/Cc:stable, no described bug.
>>>
>>> - 4/5 (79ae8510b5b8) is a v7.1-rc1 timeout bump that depends on 1/5.
>>> It is not yet in any released stable, so applying it to 6.18.y
>>> would put it on an LTS before any LTS contains it.
>>>
>>> - 5/5 (3946d3ba9934) is a doc fix for 1/5.
>>>
>>> Per stable-kernel-rules, what I need to queue is the minimum set that
>>> fixes the bug. Could you explain, per patch, why 2/5..5/5 are required
>>> to make 1/5 work / are required to actually fix the deadlock? If only
>>> 1/5 is needed, please resend just that one with your Signed-off-by
>>> added (the carried patches today only have Thomas's S-o-b, which
>>> breaks the chain of custody on a stable submission).
>>
>> Thanks for the quick review and for pointing out the missing Signed-off-by. I apologize for that omission; it was my mistake during the cherry-pick process.
>>
>> Regarding the dependency chain, I would like to clarify why commit 1/5 alone cannot fix the issue:
>>
>> Commits 1/5 and 2/5 introduce the new generic vblank timer infrastructure to the DRM core but do *not* touch the vkms driver at all.
>> Commit 3/5 (02e2681ffe1a) is the actual fix that modifies `drivers/gpu/drm/vkms/vkms_crtc.c`. It removes the buggy open-coded hrtimer that causes the ABBA deadlock and switches vkms to use the new infrastructure introduced in 1/5 and 2/5.
>>
>> Therefore, 1/5, 2/5, and 3/5 form an indivisible set. Applying only 1/5 would leave the deadlock in vkms completely unpatched.
>>
>> As for 4/5 and 5/5 (the timeout bump and doc fix), Maarten Lankhorst (DRM maintainer) explicitly recommended pulling in this exact 5-commit list as the proper upstream fix for this specific vkms issue (see the mailing list link in this thread).
>>
>> However, if you feel 4/5 and 5/5 introduce unnecessary risk for the 6.18.y stable tree, I can absolutely drop them and only submit 1/5, 2/5, and 3/5.
>>
>> I am preparing a v2 patch series now with my Signed-off-by added to the chain of custody. Could you let me know if you prefer the full 5-patch series as recommended by DRM maintainers, or just the minimal 3-patch series?
>>
>> Best regards,
>> Mingyu
>
>5/5 might strictly speaking not be needed as it's a documentation fix and I have no idea of the policy about those.
>
>The reporter made a bug report of an ABBA deadlock that was fixed in upstream by the first 4 patches, perhaps it's good to those attach here to this discussion.
I have no objection to taking all 5 if you're okay with it.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock
2026-05-26 12:50 ` Sasha Levin
@ 2026-05-26 12:59 ` Maarten Lankhorst
0 siblings, 0 replies; 18+ messages in thread
From: Maarten Lankhorst @ 2026-05-26 12:59 UTC (permalink / raw)
To: Sasha Levin
Cc: w15303746062, stable, gregkh, tzimmermann, mripard, louis.chauvet,
dri-devel, linux-kernel, Mingyu Wang
Den 2026-05-26 kl. 14:50, skrev Sasha Levin:
> On Tue, May 26, 2026 at 02:48:55PM +0200, Maarten Lankhorst wrote:
>> Hello,
>>
>> Den 2026-05-26 kl. 14:06, skrev w15303746062:
>>>
>>> Hi Sasha,
>>>
>>>> Looking at the five commits:
>>>>
>>>> - 1/5 (74afeb812850) is the one that actually fixes the ABBA
>>>> deadlock you observed under Syzkaller; it adds the generic vblank
>>>> timer that replaces the open-coded vkms hrtimer path.
>>>>
>>>> - 2/5 (d54dbb5963bd) adds new CRTC helpers for "simple use cases".
>>>> No Fixes:/Cc:stable, no described bug.
>>>>
>>>> - 3/5 (02e2681ffe1a) is a refactor that converts vkms to the new
>>>> helpers. No Fixes:/Cc:stable, no described bug.
>>>>
>>>> - 4/5 (79ae8510b5b8) is a v7.1-rc1 timeout bump that depends on 1/5.
>>>> It is not yet in any released stable, so applying it to 6.18.y
>>>> would put it on an LTS before any LTS contains it.
>>>>
>>>> - 5/5 (3946d3ba9934) is a doc fix for 1/5.
>>>>
>>>> Per stable-kernel-rules, what I need to queue is the minimum set that
>>>> fixes the bug. Could you explain, per patch, why 2/5..5/5 are required
>>>> to make 1/5 work / are required to actually fix the deadlock? If only
>>>> 1/5 is needed, please resend just that one with your Signed-off-by
>>>> added (the carried patches today only have Thomas's S-o-b, which
>>>> breaks the chain of custody on a stable submission).
>>>
>>> Thanks for the quick review and for pointing out the missing Signed-off-by. I apologize for that omission; it was my mistake during the cherry-pick process.
>>>
>>> Regarding the dependency chain, I would like to clarify why commit 1/5 alone cannot fix the issue:
>>>
>>> Commits 1/5 and 2/5 introduce the new generic vblank timer infrastructure to the DRM core but do *not* touch the vkms driver at all.
>>> Commit 3/5 (02e2681ffe1a) is the actual fix that modifies `drivers/gpu/drm/vkms/vkms_crtc.c`. It removes the buggy open-coded hrtimer that causes the ABBA deadlock and switches vkms to use the new infrastructure introduced in 1/5 and 2/5.
>>>
>>> Therefore, 1/5, 2/5, and 3/5 form an indivisible set. Applying only 1/5 would leave the deadlock in vkms completely unpatched.
>>>
>>> As for 4/5 and 5/5 (the timeout bump and doc fix), Maarten Lankhorst (DRM maintainer) explicitly recommended pulling in this exact 5-commit list as the proper upstream fix for this specific vkms issue (see the mailing list link in this thread).
>>>
>>> However, if you feel 4/5 and 5/5 introduce unnecessary risk for the 6.18.y stable tree, I can absolutely drop them and only submit 1/5, 2/5, and 3/5.
>>>
>>> I am preparing a v2 patch series now with my Signed-off-by added to the chain of custody. Could you let me know if you prefer the full 5-patch series as recommended by DRM maintainers, or just the minimal 3-patch series?
>>>
>>> Best regards,
>>> Mingyu
>>
>> 5/5 might strictly speaking not be needed as it's a documentation fix and I have no idea of the policy about those.
>>
>> The reporter made a bug report of an ABBA deadlock that was fixed in upstream by the first 4 patches, perhaps it's good to those attach here to this discussion.
>
> I have no objection to taking all 5 if you're okay with it.
>
Mingyu made an effort to reproduce, check if commits fixed it and then checked if other
drivers needed the same bug fixed. I'm ok with the series.
Kind regards,
~Maarten Lankhorst
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2026-05-26 12:59 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-15 13:18 [PATCH 6.18.y] drm/vkms: Fix ABBA deadlock in vblank disable and timer callback w15303746062
2026-05-15 15:09 ` Greg KH
2026-05-16 2:43 ` w15303746062
2026-05-16 9:51 ` Greg KH
2026-05-18 2:22 ` w15303746062
2026-05-25 8:55 ` Maarten Lankhorst
2026-05-25 13:16 ` [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock w15303746062
2026-05-25 13:16 ` [PATCH 6.18.y 1/5] drm/vblank: Add vblank timer w15303746062
2026-05-25 13:16 ` [PATCH 6.18.y 2/5] drm/vblank: Add CRTC helpers for simple use cases w15303746062
2026-05-25 13:16 ` [PATCH 6.18.y 3/5] drm/vkms: Convert to DRM's vblank timer w15303746062
2026-05-25 13:16 ` [PATCH 6.18.y 4/5] drm/atomic: Increase timeout in drm_atomic_helper_wait_for_vblanks() w15303746062
2026-05-25 13:16 ` [PATCH 6.18.y 5/5] drm/vblank: Fix kernel docs for vblank timer w15303746062
2026-05-26 11:35 ` [PATCH 6.18.y 0/5] drm/vkms: Backport generic vblank timer to fix ABBA deadlock Sasha Levin
2026-05-26 12:06 ` w15303746062
2026-05-26 12:48 ` Maarten Lankhorst
2026-05-26 12:50 ` Sasha Levin
2026-05-26 12:59 ` Maarten Lankhorst
2026-05-26 11:16 ` Re:Re: [PATCH 6.18.y] drm/vkms: Fix ABBA deadlock in vblank disable and timer callback w15303746062
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox