From nobody Mon Jun 8 21:47:55 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.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 8D89B3FD133; Tue, 26 May 2026 13:32:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.4 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779802372; cv=none; b=kfpsUtA82s8KYg2IAEDdhR2l9kdE0yncTvkXY8MvwldSbbnTgjWHQOB4/xD3M8vum3GPT1F2imQvpmzU8kQlqwDcMkkptz/B0j5OM+g1WY33y1CDq+nbsaY9ckCW+8HnWE6twlRtmtL+gr2grA16U2drqJDRJF1BwvZ6WZT6CAA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779802372; c=relaxed/simple; bh=aWg+kAGWILCjhRJ6WP947ExugrLT74iJD5dFG7NYaoA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=twbM0EouCAq38NviTUzpTLDu3OEEAstlj7//gHxmB6Ho1Lop420UBdlU8Dm2HbWj+KkNhiSxMvj8Wiw4Fp2zjfyctgNVOphbUR51RiEXjStmzPu8E+Fu3PAoacz4JocGFCvvtNaioYZe1ZwL8m7ThmoGlLd7skri80re7ekSsp0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=pqR8dC3M; arc=none smtp.client-ip=220.197.31.4 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="pqR8dC3M" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=iY cVFtYBl6Q5P7xqiRi17Yj5nOVHMhCFVGqjtL+m6BI=; b=pqR8dC3M+NDiS8Spii h9JVksCfWNWJKTikTcjvezAmsUtQs1fdcTPEkuwTUE4Do4U0/YMsWRkIXF0n/Dit RyhrYw5y4Iit8IroEoYWciTA2W3C09be3Wvf7xxd3a1aTLZvxjUjAe7y62nZxt6b oXcTJem2NOs9SJh07E/MEdQlw= Received: from 163.com (unknown []) by gzga-smtp-mtada-g0-3 (Coremail) with SMTP id _____wD3v0evoBVqYN9KDg--.14290S3; Tue, 26 May 2026 21:31:33 +0800 (CST) From: w15303746062@163.com To: stable@vger.kernel.org, gregkh@linuxfoundation.org, sashal@kernel.org Cc: tzimmermann@suse.de, maarten.lankhorst@linux.intel.com, mripard@kernel.org, louis.chauvet@bootlin.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Javier Martinez Canillas , Michael Kelley , Mingyu Wang <25181214217@stu.xidian.edu.cn> Subject: [PATCH v2 6.18.y 1/5] drm/vblank: Add vblank timer Date: Tue, 26 May 2026 21:31:19 +0800 Message-Id: <20260526133123.691465-2-w15303746062@163.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260526133123.691465-1-w15303746062@163.com> References: <20260526133123.691465-1-w15303746062@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wD3v0evoBVqYN9KDg--.14290S3 X-Coremail-Antispam: 1Uf129KBjvAXoW3CryfKF45CrWDZF15Jw1rtFb_yoW8Cw1DWo WIyF45Zw1UGw1fX34Dtr12kasrXa95Wr1akrn8Gws5Za1q9w1jvF17GF1UAFWxAr1jyrn7 Z34Uu3W7XFWUXF4xn29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjxU21xRDUUUU X-CM-SenderInfo: jzrvjiatxuliiws6il2tof0z/xtbDABc1GWoVoLf1-wAA3Z Content-Type: text/plain; charset="utf-8" From: Thomas Zimmermann 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 Tested-by: Louis Chauvet Reviewed-by: Louis Chauvet Reviewed-by: Javier Martinez Canillas Tested-by: Michael Kelley 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) Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn> --- 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: =20 +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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D =20 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 :=3D \ 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) +=3D bridge/panel.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) +=3D drm_fb_helper.o obj-$(CONFIG_DRM_KMS_HELPER) +=3D 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 c= an + * 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)); =20 + 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; } =20 +/* + * VBLANK timer + */ + +static enum hrtimer_restart drm_vblank_timer_function(struct hrtimer *time= r) +{ + struct drm_vblank_crtc_timer *vtimer =3D + container_of(timer, struct drm_vblank_crtc_timer, timer); + struct drm_crtc *crtc =3D vtimer->crtc; + const struct drm_crtc_helper_funcs *crtc_funcs =3D crtc->helper_private; + struct drm_device *dev =3D crtc->dev; + unsigned long flags; + ktime_t interval; + u64 ret_overrun; + bool succ; + + spin_lock_irqsave(&vtimer->interval_lock, flags); + interval =3D vtimer->interval; + spin_unlock_irqrestore(&vtimer->interval_lock, flags); + + if (!interval) + return HRTIMER_NORESTART; + + ret_overrun =3D hrtimer_forward_now(&vtimer->timer, interval); + if (ret_overrun !=3D 1) + drm_dbg_vbl(dev, "vblank timer overrun\n"); + + if (crtc_funcs->handle_vblank_timeout) + succ =3D crtc_funcs->handle_vblank_timeout(crtc); + else + succ =3D 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 time= r. + * + * 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 =3D drm_crtc_vblank_crtc(crtc); + struct drm_vblank_crtc_timer *vtimer =3D &vblank->vblank_timer; + unsigned long flags; + + if (!vtimer->crtc) { + /* + * Set up the data structures on the first invocation. + */ + vtimer->crtc =3D 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 =3D 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 =3D drm_crtc_vblank_crtc(crtc); + struct drm_vblank_crtc_timer *vtimer =3D &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 =3D 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 *vb= lank_time) +{ + struct drm_vblank_crtc *vblank =3D drm_crtc_vblank_crtc(crtc); + struct drm_vblank_crtc_timer *vtimer =3D &vblank->vblank_timer; + u64 cur_count; + ktime_t cur_time; + + if (!READ_ONCE(vblank->enabled)) { + *vblank_time =3D 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 =3D drm_crtc_vblank_count_and_time(crtc, &cur_time); + *vblank_time =3D READ_ONCE(vtimer->timer.node.expires); + } while (cur_count !=3D 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 =3D 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_vbla= nk_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 +#include +#include +#include +#include +#include + +/** + * 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_crt= c_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_cr= tc_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_crt= c *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_mod= eset_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); }; =20 /** 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_ =20 #include +#include #include #include #include @@ -103,6 +104,28 @@ struct drm_vblank_crtc_config { bool disable_immediate; }; =20 +/** + * 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; }; =20 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 dr= m_crtc *crtc); void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc, u32 max_vblank_count); =20 +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 *vb= lank_time); + /* * Helpers for struct drm_crtc_funcs */ diff --git a/include/drm/drm_vblank_helper.h b/include/drm/drm_vblank_helpe= r.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 +#include + +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_crt= c *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 =3D drm_crtc_vblank_helper_enable_vblank_timer, \ + .disable_vblank =3D drm_crtc_vblank_helper_disable_vblank_timer, \ + .get_vblank_timestamp =3D drm_crtc_vblank_helper_get_vblank_timestamp_fro= m_timer + +#endif --=20 2.34.1 From nobody Mon Jun 8 21:47:55 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.2]) (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 A25943E0C4F; Tue, 26 May 2026 13:32:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.2 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779802373; cv=none; b=s0VqR6KXGa0WlZxxC2YFhfzFtRAN8LtzrLtRvCrj+Kt2kPYHxlhW9rnbd7jhh/yZR2zUupFoGb3rGypphdDRLc0AKeO6XOoABg8iza9Im0hIcESW6ArdrJLorM2Xn2pzeaN2xzt3eHCOEY9oxBOtpGleo14B30s1QWgNWdPPqG8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779802373; c=relaxed/simple; bh=SV8gANXriicy3xro8WpIf2z6iUM6Kqr4jZKvbVPnjP8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=k4HWIWAAbnffcLkSYwxPLoLaEsTQ46cB6PCLM5+BNabT35bDb0h0YkOhtKMNB0NL5h/HlwRAky6Hc2HEJDo87u0sBUOm+xuYY6a26FoAjOFIirQ6kSI/rW0HdYGnvsu+SmN/TgB+He/iQgaJvIxr/+8pe67v0NikTfa04EpG4Qw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=nQKSiyXr; arc=none smtp.client-ip=220.197.31.2 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="nQKSiyXr" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=6w dUSydCAldsf7w8+0XqwnOjjPoxBTMdvmgLiBqHNPE=; b=nQKSiyXrZjMuh/O2qe ozGMluuvgNx9hnYA8IP7Hf0iMNZQQRPvHvxvTfsalTXiCZCS35dnk4guSelx9fjI YmwM4Tr7fLsp0//iWMW7d/LUkcX7ceh9arpp/bS0ItQFo+b58WT5c6bXdGGYOH/j oG7z76ivEYD22A7Gg9hzLmk5k= Received: from 163.com (unknown []) by gzga-smtp-mtada-g0-3 (Coremail) with SMTP id _____wD3v0evoBVqYN9KDg--.14290S4; Tue, 26 May 2026 21:31:39 +0800 (CST) From: w15303746062@163.com To: stable@vger.kernel.org, gregkh@linuxfoundation.org, sashal@kernel.org Cc: tzimmermann@suse.de, maarten.lankhorst@linux.intel.com, mripard@kernel.org, louis.chauvet@bootlin.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Javier Martinez Canillas , Michael Kelley , Mingyu Wang <25181214217@stu.xidian.edu.cn> Subject: [PATCH v2 6.18.y 2/5] drm/vblank: Add CRTC helpers for simple use cases Date: Tue, 26 May 2026 21:31:20 +0800 Message-Id: <20260526133123.691465-3-w15303746062@163.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260526133123.691465-1-w15303746062@163.com> References: <20260526133123.691465-1-w15303746062@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wD3v0evoBVqYN9KDg--.14290S4 X-Coremail-Antispam: 1Uf129KBjvJXoW3AFyxZr4UWF15ur13JFyrWFg_yoW7tr1kpF srGry5Kr4YqFy5W3sxJws2yw1ag3yFyas7XrykG343Z3Z5KrnxuF18AryxuF13XrnrJ3Wf X342yr15C3WrCa7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jIPfdUUUUU= X-CM-SenderInfo: jzrvjiatxuliiws6il2tof0z/xtbC5Bs2GmoVoLuDWgAA3u Content-Type: text/plain; charset="utf-8" From: Thomas Zimmermann 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 Reviewed-by: Javier Martinez Canillas Tested-by: Michael Kelley Link: https://lore.kernel.org/r/20250916083816.30275-3-tzimmermann@suse.de (cherry picked from commit d54dbb5963bdbdf8559903fe2b2343e871adcb30) Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn> --- 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_vbla= nk_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 =20 +#include #include #include #include @@ -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_di= sable + * 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. */ =20 +/* + * 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 =3D crtc->dev; + struct drm_crtc_state *crtc_state =3D drm_atomic_get_new_crtc_state(state= , crtc); + struct drm_pending_vblank_event *event; + + spin_lock_irq(&dev->event_lock); + + event =3D crtc_state->event; + crtc_state->event =3D NULL; + + if (event) { + if (drm_crtc_vblank_get(crtc) =3D=3D 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_func= s.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 VBLAN= Ks. + * + * 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_fun= cs.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 VBLA= NKs. + * + * 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_helpe= r.h index 74a971d0cfba..fcd8a9b35846 100644 --- a/include/drm/drm_vblank_helper.h +++ b/include/drm/drm_vblank_helper.h @@ -6,8 +6,31 @@ #include #include =20 +struct drm_atomic_state; struct drm_crtc; =20 +/* + * 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 =3D drm_crtc_vblank_atomic_flush, \ + .atomic_enable =3D drm_crtc_vblank_atomic_enable, \ + .atomic_disable =3D drm_crtc_vblank_atomic_disable + /* * VBLANK timer */ --=20 2.34.1 From nobody Mon Jun 8 21:47:55 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.3]) (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 3FE4C3FA5C6; Tue, 26 May 2026 13:32:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.3 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779802381; cv=none; b=jRPaFSdExb4ji4Ohl6UlclRUqDUCI8thS3gGGtWMwzRWYl9YdoO2v0qiZ+PKT/DQw4TVVXF/LHy1Nc2hT+flEDVHyNBfhdcqdN7H+/osEUdkf3rdsW4ovgo8xqACxeXDEgzL7FgqyGfOez8WXj0PIv+t4qyKY4m2gN6EwqGQreM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779802381; c=relaxed/simple; bh=zPKOnI+eCh6TITh5o719WgZc/7yXFTbcBgxOuiILBko=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=G4khvOvALc84z2NXqI7MgHMhVLNCI4bQMP6yczm4tTnkyOd3X3F8Q2dfBTnubxSMrqRWaod7yNmMgeAqiV//S2d3h49fTDHV2OL1U9981IElwrLf/xBPov4xuo++um54QGjJDgXsKJE8A+kpDsTaXa88BEdNJ2NU/XXqekcWeUI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=dMftMtk1; arc=none smtp.client-ip=220.197.31.3 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="dMftMtk1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=4h VCpdYFEFDtvN0xhS/XhmVq2wEshicj2yXlZWbzaZ0=; b=dMftMtk1q9+lOjYvSA Qbvgj9ZjnYYrFoea8Q3EG2FdJGyLecxR33GlJjMQlGPMBf4e456bwNK72PR0nyHH zKmxcUYi7btUw4EYZJ1BQRySDmaO6CBsbYomIVCoyGZLa8xK0CSh8Cj466XU2Tc0 agASb2GmofUdmNks7hRVgn5+0= Received: from 163.com (unknown []) by gzga-smtp-mtada-g0-3 (Coremail) with SMTP id _____wD3v0evoBVqYN9KDg--.14290S5; Tue, 26 May 2026 21:31:41 +0800 (CST) From: w15303746062@163.com To: stable@vger.kernel.org, gregkh@linuxfoundation.org, sashal@kernel.org Cc: tzimmermann@suse.de, maarten.lankhorst@linux.intel.com, mripard@kernel.org, louis.chauvet@bootlin.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Javier Martinez Canillas , Mingyu Wang <25181214217@stu.xidian.edu.cn> Subject: [PATCH v2 6.18.y 3/5] drm/vkms: Convert to DRM's vblank timer Date: Tue, 26 May 2026 21:31:21 +0800 Message-Id: <20260526133123.691465-4-w15303746062@163.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260526133123.691465-1-w15303746062@163.com> References: <20260526133123.691465-1-w15303746062@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wD3v0evoBVqYN9KDg--.14290S5 X-Coremail-Antispam: 1Uf129KBjvJXoWxKw1UAw1ktF1DGFWxAFy5Arb_yoWxJF4kpF sFyr97Kr4rtF1UWa4DJF4kCw1F934Fyas7X3y8K3yav3WFkF13J3W8ArW3uFW3XF9rXw4a qF1xtw15Ar109F7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jINtxUUUUU= X-CM-SenderInfo: jzrvjiatxuliiws6il2tof0z/xtbC-x03G2oVoL3gcAAA38 Content-Type: text/plain; charset="utf-8" From: Thomas Zimmermann 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 Tested-by: Louis Chauvet Reviewed-by: Louis Chauvet Reviewed-by: Javier Martinez Canillas Link: https://lore.kernel.org/r/20250916083816.30275-4-tzimmermann@suse.de (cherry picked from commit 02e2681ffe1addde1fc8c35d05657b16bfa79613) Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn> --- 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_c= rtc.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 #include #include +#include =20 #include "vkms_drv.h" =20 -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 =3D container_of(timer, struct vkms_output, - vblank_hrtimer); - struct drm_crtc *crtc =3D &output->crtc; + struct vkms_output *output =3D drm_crtc_to_vkms_output(crtc); struct vkms_crtc_state *state; - u64 ret_overrun; bool ret, fence_cookie; =20 fence_cookie =3D dma_fence_begin_signalling(); =20 - ret_overrun =3D hrtimer_forward_now(&output->vblank_hrtimer, - output->period_ns); - if (ret_overrun !=3D 1) - pr_warn("%s: vblank timer overrun\n", __func__); - spin_lock(&output->lock); ret =3D drm_crtc_handle_vblank(crtc); if (!ret) @@ -57,55 +50,6 @@ static enum hrtimer_restart vkms_vblank_simulate(struct = hrtimer *timer) =20 dma_fence_end_signalling(fence_cookie); =20 - return HRTIMER_RESTART; -} - -static int vkms_enable_vblank(struct drm_crtc *crtc) -{ - struct drm_vblank_crtc *vblank =3D drm_crtc_vblank_crtc(crtc); - struct vkms_output *out =3D drm_crtc_to_vkms_output(crtc); - - hrtimer_setup(&out->vblank_hrtimer, &vkms_vblank_simulate, CLOCK_MONOTONI= C, - HRTIMER_MODE_REL); - out->period_ns =3D 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 =3D 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 =3D drm_crtc_to_vkms_output(crtc); - struct drm_vblank_crtc *vblank =3D drm_crtc_vblank_crtc(crtc); - - if (!READ_ONCE(vblank->enabled)) { - *vblank_time =3D ktime_get(); - return true; - } - - *vblank_time =3D READ_ONCE(output->vblank_hrtimer.node.expires); - - if (WARN_ON(*vblank_time =3D=3D 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 -=3D output->period_ns; - return true; } =20 @@ -159,9 +103,7 @@ static const struct drm_crtc_funcs vkms_crtc_funcs =3D { .reset =3D vkms_atomic_crtc_reset, .atomic_duplicate_state =3D vkms_atomic_crtc_duplicate_state, .atomic_destroy_state =3D vkms_atomic_crtc_destroy_state, - .enable_vblank =3D vkms_enable_vblank, - .disable_vblank =3D vkms_disable_vblank, - .get_vblank_timestamp =3D vkms_get_vblank_timestamp, + DRM_CRTC_VBLANK_TIMER_FUNCS, .get_crc_sources =3D vkms_get_crc_sources, .set_crc_source =3D vkms_set_crc_source, .verify_crc_source =3D vkms_verify_crc_source, @@ -213,18 +155,6 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crt= c, return 0; } =20 -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_hel= per_funcs =3D { .atomic_check =3D vkms_crtc_atomic_check, .atomic_begin =3D vkms_crtc_atomic_begin, .atomic_flush =3D vkms_crtc_atomic_flush, - .atomic_enable =3D vkms_crtc_atomic_enable, - .atomic_disable =3D vkms_crtc_atomic_disable, + .atomic_enable =3D drm_crtc_vblank_atomic_enable, + .atomic_disable =3D drm_crtc_vblank_atomic_disable, + .handle_vblank_timeout =3D vkms_crtc_handle_vblank_timeout, }; =20 struct vkms_output *vkms_crtc_init(struct drm_device *dev, struct drm_plan= e *primary, diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_dr= v.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; =20 --=20 2.34.1 From nobody Mon Jun 8 21:47:55 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.2]) (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 B33EE3FD133; Tue, 26 May 2026 13:32:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.2 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779802381; cv=none; b=bDObms9aFWklH1sNP0MRPY2aBLJ/3MGAeN1qy1UVG23heT5piPXxJysAoE5YBcQOzVHWz4ulz+mFPrzrLKXEVeeilF1ny8bhRWoLS+bp8fkVAFsnyttowxAm1FLZzthFvZWXAGM2coklDAB7pwWOMywy2+OuoeSitd1L6IOYB5w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779802381; c=relaxed/simple; bh=96sdcHFIzygI3sTd332mCW5JQKGfjIBya5Dkceyl0FU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=d9D2JKdOTFPPD0dHruXomgeVRu1AXOsDKFPfoAjZ99cE2EY0ZA0EIOiNKya7MRvbVdOFE949JhrCvgLgqwr7Umzo2hASU/+EnipCvr2G3z0YPspbS952tRri+eIbeEGK9bxWw6L1+/vgxsNgmaFbQjoRP66vmNjSC0DSvNVVwzE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=Hq6wihak; arc=none smtp.client-ip=220.197.31.2 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="Hq6wihak" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-Id:MIME-Version: Content-Type; bh=UEeCL38PHXnSztjS/6CD3ugZQl17GiH4O46J5Qeh2ow=; b=Hq6wihakIVrABfWAspSMpgZ4h9RCajB1RhhaOQz1G3Q5Y8BIelyUs5lyjJVI0I e3mn1lUeLX8Upyxm34xbvI+k9u0bMI/YMmRkOT+Z6SlHGp2pI3GMYe24vVe+I3+v iuyxHpCUjZITpMncf4HZGaioIKXMbsIYXfCgqKW8uzhHo= Received: from 163.com (unknown []) by gzga-smtp-mtada-g0-3 (Coremail) with SMTP id _____wD3v0evoBVqYN9KDg--.14290S6; Tue, 26 May 2026 21:31:43 +0800 (CST) From: w15303746062@163.com To: stable@vger.kernel.org, gregkh@linuxfoundation.org, sashal@kernel.org Cc: tzimmermann@suse.de, maarten.lankhorst@linux.intel.com, mripard@kernel.org, louis.chauvet@bootlin.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, syzbot+fcede535e7eb57cf5b43@syzkaller.appspotmail.com, =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Mingyu Wang <25181214217@stu.xidian.edu.cn> Subject: [PATCH v2 6.18.y 4/5] drm/atomic: Increase timeout in drm_atomic_helper_wait_for_vblanks() Date: Tue, 26 May 2026 21:31:22 +0800 Message-Id: <20260526133123.691465-5-w15303746062@163.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260526133123.691465-1-w15303746062@163.com> References: <20260526133123.691465-1-w15303746062@163.com> 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 X-CM-TRANSID: _____wD3v0evoBVqYN9KDg--.14290S6 X-Coremail-Antispam: 1Uf129KBjvJXoW7ZrW8Cw4kKrykXF13ZrWUArb_yoW8CFW3pF srKFyUtrsYqF1Dt34DAa1xZa4Y9ay7XFyIg3srtw1ruw4qyF9IyF1SvrW3GFyUZrsrur4a vas7Jr13Cr15CFJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jFGQDUUUUU= X-CM-SenderInfo: jzrvjiatxuliiws6il2tof0z/xtbDAB83G2oVoL-2sQAA3U From: Thomas Zimmermann 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 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=C3=A4l=C3=A4 Fixes: 74afeb812850 ("drm/vblank: Add vblank timer") Link: https://patch.msgid.link/20251209143325.102056-1-tzimmermann@suse.de (cherry picked from commit 79ae8510b5b81b9500370f89c619b50ca9c0990f) Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn> --- 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_atom= ic_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 =3D wait_event_timeout(dev->vblank[i].queue, state->crtcs[i].last_vblank_count !=3D drm_crtc_vblank_count(crtc), - msecs_to_jiffies(100)); + msecs_to_jiffies(1000)); =20 WARN(!ret, "[CRTC:%d:%s] vblank wait timed out\n", crtc->base.id, crtc->name); --=20 2.34.1 From nobody Mon Jun 8 21:47:55 2026 Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.2]) (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 3BBF53FA5EC; Tue, 26 May 2026 13:33:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=220.197.31.2 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779802393; cv=none; b=jYI3B6O7ABDxzaQ8jTDaeZkK2VeDIoJA+87zgHcuYN70LtYaVNuJSRnwgZH4xMbbxN5mkkfC3dBTFPpXn7uLTFM7ZNA1c43LKIXAQchYPJijneGt7qKVMxodp8K/P5o+pAiHah/Wqr35kHOV1vlcFjtsmGql1LCaVEE3QbilZ3k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779802393; c=relaxed/simple; bh=8c455aXFF7HLlHYcNMeNADliusp09afhq5rjFXml4XM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=G9BNA0gikUrqsluLedvoScYhOp5YmE/EZjbl4bthpzS3ednaqkNAjtTPbNEVaq/MML0fp8loZzRerFG0hivUQZo8DYG5cNFU2kodqys9NRCGFJJwiZpyvKWMn4a5+2Z8Hr4moWafS6eI281egyL7KxqIRNtDxPG6VSS8N4oyyh4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com; spf=pass smtp.mailfrom=163.com; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b=G3HNf0FM; arc=none smtp.client-ip=220.197.31.2 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=163.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=163.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=163.com header.i=@163.com header.b="G3HNf0FM" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=1N 4mxlQmcxLBqdU9q8trXnA6PzPq3w4ggMHk2XEFBAc=; b=G3HNf0FMpBpjlMusbE L2dD3uUhcARQYiHVYysLKrYXcjPGeYn5hx9AM5TgIifYYyrHzSq3MwRml3HUvLWq dYB8n9WS3hMQvbwWOH65NoAHwKYHqs/Suudj5vTMG5C3Jo5UtUxx1xdYT9qKWak9 z5m5z9jEbdsJUIKi1mdZYsv/4= Received: from 163.com (unknown []) by gzga-smtp-mtada-g0-3 (Coremail) with SMTP id _____wD3v0evoBVqYN9KDg--.14290S7; Tue, 26 May 2026 21:31:45 +0800 (CST) From: w15303746062@163.com To: stable@vger.kernel.org, gregkh@linuxfoundation.org, sashal@kernel.org Cc: tzimmermann@suse.de, maarten.lankhorst@linux.intel.com, mripard@kernel.org, louis.chauvet@bootlin.com, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Stephen Rothwell , Javier Martinez Canillas , David Airlie , Simona Vetter , Mingyu Wang <25181214217@stu.xidian.edu.cn> Subject: [PATCH v2 6.18.y 5/5] drm/vblank: Fix kernel docs for vblank timer Date: Tue, 26 May 2026 21:31:23 +0800 Message-Id: <20260526133123.691465-6-w15303746062@163.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260526133123.691465-1-w15303746062@163.com> References: <20260526133123.691465-1-w15303746062@163.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: _____wD3v0evoBVqYN9KDg--.14290S7 X-Coremail-Antispam: 1Uf129KBjvJXoW7ZrWUKryfuw4rWFykZw17Awb_yoW8Aw48pr srGry3trs5tF90g3WDC3Z7CFyY9a45JFyxuF9rt3y5Zwnayr1ayF1Fyr43uFyUXrnxCa1a qr9xXr13AF1rCFJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jFXdbUUUUU= X-CM-SenderInfo: jzrvjiatxuliiws6il2tof0z/xtbC4wE4HGoVoMF7xwAA3k Content-Type: text/plain; charset="utf-8" From: Thomas Zimmermann Fix documentation for drm_crtc_vblank_start_timer(), which referred to drm_crtc_vblank_cancel_timer(). Signed-off-by: Thomas Zimmermann Reported-by: Stephen Rothwell Closes: https://lore.kernel.org/dri-devel/20251106152201.6f248c09@canb.auug= .org.au/ Fixes: 74afeb812850 ("drm/vblank: Add vblank timer") Cc: Thomas Zimmermann Cc: Louis Chauvet Cc: Javier Martinez Canillas Cc: David Airlie Cc: Simona Vetter Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: dri-devel@lists.freedesktop.org Reviewed-by: Louis Chauvet Link: https://patch.msgid.link/20251106073207.11192-1-tzimmermann@suse.de (cherry picked from commit 3946d3ba99342f3b9996e621f05e7003d4308171) Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn> --- 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); =20 /** - * 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 --=20 2.34.1