* [PATCH 00/24] drm/vblank: refactoring and cleanups
@ 2025-11-10 16:17 Jani Nikula
2025-11-10 16:17 ` [PATCH 01/24] drm/vblank: Unexport drm_wait_one_vblank() Jani Nikula
` (24 more replies)
0 siblings, 25 replies; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Mostly, pass vblank around a lot more instead of dev, pipe pair. This
allows cleanup of pipe bounds checks, etc.
BR,
Jani.
Jani Nikula (23):
drm/vblank: remove drm_wait_one_vblank() completely
drm/vblank: remove superfluous pipe check
drm/vblank: add return value to drm_crtc_wait_one_vblank()
drm/vblank: use the drm_vblank_crtc() and drm_crtc_vblank_crtc()
helpers more
drm/vblank: prefer drm_crtc_vblank_crtc() over drm_vblank_crtc()
drm/vblank: pass vlank to drm_vblank_get()/_put()/_count()
drm/vblank: pass vblank to drm_update_vblank_count()
drm/vblank: pass vblank to drm_handle_vblank_events()
drm/vblank: use the vblank based interfaces more
drm/vblank: pass vblank to drm_queue_vblank_event()
drm/vblank: pass vblank to drm_wait_vblank_reply()
drm/vblank: pass vblank to drm_vblank_count_and_time()
drm/vblank: pass vblank to drm_reset_vblank_timestamp()
drm/vblank: pass vblank to store_vblank()
drm/vblank: pass vblank to drm_vblank_enable()
drm/vblank: merge drm_vblank_restore() into drm_crtc_vblank_restore()
drm/vblank: add drm_crtc_from_vblank() helper
drm/vblank: pass vblank to __get_vblank_counter() and
drm_max_vblank_count()
drm/vblank: pass vblank to __{enable,disable}_vblank()
drm/vblank: pass vblank to drm_get_last_vbltimestamp()
drm/vblank: pass vblank to drm_vblank_disable_and_save(), make static
drm/vblank: reduce pipe checks
drm/vblank: clean up debug logging
Thomas Zimmermann (1):
drm/vblank: Unexport drm_wait_one_vblank()
drivers/gpu/drm/drm_internal.h | 7 +-
drivers/gpu/drm/drm_vblank.c | 470 ++++++++++++++----------------
drivers/gpu/drm/drm_vblank_work.c | 12 +-
include/drm/drm_vblank.h | 3 +-
4 files changed, 224 insertions(+), 268 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 59+ messages in thread
* [PATCH 01/24] drm/vblank: Unexport drm_wait_one_vblank()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-11 8:14 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 02/24] drm/vblank: remove drm_wait_one_vblank() completely Jani Nikula
` (23 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
From: Thomas Zimmermann <tzimmermann@suse.de>
Make drm_wait_on_vblank() static. The function is an internal interface
and not invoked directly by drivers.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 14 +-------------
include/drm/drm_vblank.h | 1 -
2 files changed, 1 insertion(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 32d013c5c8fc..c15d6d9d0082 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1286,18 +1286,7 @@ void drm_crtc_vblank_put(struct drm_crtc *crtc)
}
EXPORT_SYMBOL(drm_crtc_vblank_put);
-/**
- * drm_wait_one_vblank - wait for one vblank
- * @dev: DRM device
- * @pipe: CRTC index
- *
- * This waits for one vblank to pass on @pipe, using the irq driver interfaces.
- * It is a failure to call this when the vblank irq for @pipe is disabled, e.g.
- * due to lack of driver support or because the crtc is off.
- *
- * This is the legacy version of drm_crtc_wait_one_vblank().
- */
-void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
+static void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
{
struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
int ret;
@@ -1321,7 +1310,6 @@ void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
drm_vblank_put(dev, pipe);
}
-EXPORT_SYMBOL(drm_wait_one_vblank);
/**
* drm_crtc_wait_one_vblank - wait for one vblank
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index ffa564d79638..94ee09b48895 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -302,7 +302,6 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe);
bool drm_crtc_handle_vblank(struct drm_crtc *crtc);
int drm_crtc_vblank_get(struct drm_crtc *crtc);
void drm_crtc_vblank_put(struct drm_crtc *crtc);
-void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe);
void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
void drm_crtc_vblank_off(struct drm_crtc *crtc);
void drm_crtc_vblank_reset(struct drm_crtc *crtc);
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 02/24] drm/vblank: remove drm_wait_one_vblank() completely
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
2025-11-10 16:17 ` [PATCH 01/24] drm/vblank: Unexport drm_wait_one_vblank() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-11 8:17 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 03/24] drm/vblank: remove superfluous pipe check Jani Nikula
` (22 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
There's really no need for the extra static function at all.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index c15d6d9d0082..1d12836e3d80 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1286,8 +1286,18 @@ void drm_crtc_vblank_put(struct drm_crtc *crtc)
}
EXPORT_SYMBOL(drm_crtc_vblank_put);
-static void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
+/**
+ * drm_crtc_wait_one_vblank - wait for one vblank
+ * @crtc: DRM crtc
+ *
+ * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
+ * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
+ * due to lack of driver support or because the crtc is off.
+ */
+void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
{
+ struct drm_device *dev = crtc->dev;
+ int pipe = drm_crtc_index(crtc);
struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
int ret;
u64 last;
@@ -1310,19 +1320,6 @@ static void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
drm_vblank_put(dev, pipe);
}
-
-/**
- * drm_crtc_wait_one_vblank - wait for one vblank
- * @crtc: DRM crtc
- *
- * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
- * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
- * due to lack of driver support or because the crtc is off.
- */
-void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
-{
- drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc));
-}
EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
/**
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 03/24] drm/vblank: remove superfluous pipe check
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
2025-11-10 16:17 ` [PATCH 01/24] drm/vblank: Unexport drm_wait_one_vblank() Jani Nikula
2025-11-10 16:17 ` [PATCH 02/24] drm/vblank: remove drm_wait_one_vblank() completely Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-11 8:18 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 04/24] drm/vblank: add return value to drm_crtc_wait_one_vblank() Jani Nikula
` (21 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Now that the pipe is crtc->pipe, there's no need to check it's within
range.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 1d12836e3d80..f4d1fe182a4d 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1302,9 +1302,6 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
int ret;
u64 last;
- if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
- return;
-
ret = drm_vblank_get(dev, pipe);
if (drm_WARN(dev, ret, "vblank not available on crtc %i, ret=%i\n",
pipe, ret))
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 04/24] drm/vblank: add return value to drm_crtc_wait_one_vblank()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (2 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 03/24] drm/vblank: remove superfluous pipe check Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-10 16:17 ` [PATCH 05/24] drm/vblank: use the drm_vblank_crtc() and drm_crtc_vblank_crtc() helpers more Jani Nikula
` (20 subsequent siblings)
24 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Let drivers deal with the vblank wait failures if they so desire. If the
current warning backtrace gets toned down to a simple warning message,
the drivers may wish to add the backtrace themselves.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 8 ++++++--
include/drm/drm_vblank.h | 2 +-
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index f4d1fe182a4d..503eb23d38d2 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1293,8 +1293,10 @@ EXPORT_SYMBOL(drm_crtc_vblank_put);
* This waits for one vblank to pass on @crtc, using the irq driver interfaces.
* It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
* due to lack of driver support or because the crtc is off.
+ *
+ * Returns: 0 on success, negative error on failures.
*/
-void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
+int drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
int pipe = drm_crtc_index(crtc);
@@ -1305,7 +1307,7 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
ret = drm_vblank_get(dev, pipe);
if (drm_WARN(dev, ret, "vblank not available on crtc %i, ret=%i\n",
pipe, ret))
- return;
+ return ret;
last = drm_vblank_count(dev, pipe);
@@ -1316,6 +1318,8 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
drm_WARN(dev, ret == 0, "vblank wait timed out on crtc %i\n", pipe);
drm_vblank_put(dev, pipe);
+
+ return ret ? 0 : -ETIMEDOUT;
}
EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index 94ee09b48895..2fcef9c0f5b1 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -302,7 +302,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe);
bool drm_crtc_handle_vblank(struct drm_crtc *crtc);
int drm_crtc_vblank_get(struct drm_crtc *crtc);
void drm_crtc_vblank_put(struct drm_crtc *crtc);
-void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
+int drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
void drm_crtc_vblank_off(struct drm_crtc *crtc);
void drm_crtc_vblank_reset(struct drm_crtc *crtc);
void drm_crtc_vblank_on_config(struct drm_crtc *crtc,
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 05/24] drm/vblank: use the drm_vblank_crtc() and drm_crtc_vblank_crtc() helpers more
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (3 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 04/24] drm/vblank: add return value to drm_crtc_wait_one_vblank() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-11 8:23 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 06/24] drm/vblank: prefer drm_crtc_vblank_crtc() over drm_vblank_crtc() Jani Nikula
` (19 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
We have the helpers to avoid open coding dev->vblank[pipe] access.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 503eb23d38d2..e3a5a783686f 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -551,7 +551,7 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
dev->num_crtcs = num_crtcs;
for (i = 0; i < num_crtcs; i++) {
- struct drm_vblank_crtc *vblank = &dev->vblank[i];
+ struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, i);
vblank->dev = dev;
vblank->pipe = i;
@@ -605,7 +605,9 @@ EXPORT_SYMBOL(drm_dev_has_vblank);
*/
wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc)
{
- return &crtc->dev->vblank[drm_crtc_index(crtc)].queue;
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
+
+ return &vblank->queue;
}
EXPORT_SYMBOL(drm_crtc_vblank_waitqueue);
@@ -710,7 +712,7 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
{
struct drm_device *dev = crtc->dev;
unsigned int pipe = crtc->index;
- struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
+ struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
struct timespec64 ts_etime, ts_vblank_time;
ktime_t stime, etime;
bool vbl_status;
@@ -1782,7 +1784,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
if (pipe >= dev->num_crtcs)
return -EINVAL;
- vblank = &dev->vblank[pipe];
+ vblank = drm_vblank_crtc(dev, pipe);
/* If the counter is currently enabled and accurate, short-circuit
* queries to return the cached timestamp of the last vblank.
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 06/24] drm/vblank: prefer drm_crtc_vblank_crtc() over drm_vblank_crtc()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (4 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 05/24] drm/vblank: use the drm_vblank_crtc() and drm_crtc_vblank_crtc() helpers more Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-11 8:26 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 07/24] drm/vblank: pass vlank to drm_vblank_get()/_put()/_count() Jani Nikula
` (18 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the higher level function where crtc is available.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index e3a5a783686f..96dbff63f52d 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -712,7 +712,7 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
{
struct drm_device *dev = crtc->dev;
unsigned int pipe = crtc->index;
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
struct timespec64 ts_etime, ts_vblank_time;
ktime_t stime, etime;
bool vbl_status;
@@ -1302,7 +1302,7 @@ int drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
int pipe = drm_crtc_index(crtc);
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
int ret;
u64 last;
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 07/24] drm/vblank: pass vlank to drm_vblank_get()/_put()/_count()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (5 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 06/24] drm/vblank: prefer drm_crtc_vblank_crtc() over drm_vblank_crtc() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-11 8:32 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 08/24] drm/vblank: pass vblank to drm_update_vblank_count() Jani Nikula
` (17 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Pass struct drm_vblank_crtc * to drm_vblank_get(), drm_vblank_put(), and
drm_vblank_count(). They'll figure out the vblank pointer as the first
thing anyway, so it's handy to pass it when available. We can also rely
on vblank having a valid pipe, and can reduce the number of checks we
do.
Add underscore prefixed helpers for using dev/pipe until we've converted
all users to pass in the vblank. Directly convert the call sites that
already have the vblank pointer available.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_internal.h | 6 +--
drivers/gpu/drm/drm_vblank.c | 77 ++++++++++++++++++-------------
drivers/gpu/drm/drm_vblank_work.c | 12 ++---
3 files changed, 55 insertions(+), 40 deletions(-)
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 5a3bed48ab1f..e9c85c3681f1 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -101,9 +101,9 @@ static inline bool drm_vblank_passed(u64 seq, u64 ref)
}
void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
-int drm_vblank_get(struct drm_device *dev, unsigned int pipe);
-void drm_vblank_put(struct drm_device *dev, unsigned int pipe);
-u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe);
+int drm_vblank_get(struct drm_vblank_crtc *vblank);
+void drm_vblank_put(struct drm_vblank_crtc *vblank);
+u64 drm_vblank_count(struct drm_vblank_crtc *vblank);
/* drm_vblank_work.c */
static inline void drm_vblank_flush_worker(struct drm_vblank_crtc *vblank)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 96dbff63f52d..0ae34f848660 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -384,14 +384,10 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
}
-u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
+u64 drm_vblank_count(struct drm_vblank_crtc *vblank)
{
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
u64 count;
- if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
- return 0;
-
count = atomic64_read(&vblank->count);
/*
@@ -406,6 +402,14 @@ u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
return count;
}
+static u64 _drm_vblank_count(struct drm_device *dev, unsigned int pipe)
+{
+ if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
+ return 0;
+
+ return drm_vblank_count(drm_vblank_crtc(dev, pipe));
+}
+
/**
* drm_crtc_accurate_vblank_count - retrieve the master vblank counter
* @crtc: which counter to retrieve
@@ -431,7 +435,7 @@ u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
spin_lock_irqsave(&dev->vblank_time_lock, flags);
drm_update_vblank_count(dev, pipe, false);
- vblank = drm_vblank_count(dev, pipe);
+ vblank = _drm_vblank_count(dev, pipe);
spin_unlock_irqrestore(&dev->vblank_time_lock, flags);
@@ -935,7 +939,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
*/
u64 drm_crtc_vblank_count(struct drm_crtc *crtc)
{
- return drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
+ return _drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
}
EXPORT_SYMBOL(drm_crtc_vblank_count);
@@ -1208,18 +1212,16 @@ static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
return ret;
}
-int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
+int drm_vblank_get(struct drm_vblank_crtc *vblank)
{
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
+ struct drm_device *dev = vblank->dev;
+ int pipe = vblank->pipe;
unsigned long irqflags;
int ret = 0;
if (!drm_dev_has_vblank(dev))
return -EINVAL;
- if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
- return -EINVAL;
-
spin_lock_irqsave(&dev->vbl_lock, irqflags);
/* Going from 0->1 means we have to enable interrupts again */
if (atomic_add_return(1, &vblank->refcount) == 1) {
@@ -1235,6 +1237,14 @@ int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
return ret;
}
+static int _drm_vblank_get(struct drm_device *dev, unsigned int pipe)
+{
+ if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
+ return -EINVAL;
+
+ return drm_vblank_get(drm_vblank_crtc(dev, pipe));
+}
+
/**
* drm_crtc_vblank_get - get a reference count on vblank events
* @crtc: which CRTC to own
@@ -1247,18 +1257,15 @@ int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
*/
int drm_crtc_vblank_get(struct drm_crtc *crtc)
{
- return drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
+ return _drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
}
EXPORT_SYMBOL(drm_crtc_vblank_get);
-void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
+void drm_vblank_put(struct drm_vblank_crtc *vblank)
{
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
+ struct drm_device *dev = vblank->dev;
int vblank_offdelay = vblank->config.offdelay_ms;
- if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
- return;
-
if (drm_WARN_ON(dev, atomic_read(&vblank->refcount) == 0))
return;
@@ -1274,6 +1281,14 @@ void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
}
}
+static void _drm_vblank_put(struct drm_device *dev, unsigned int pipe)
+{
+ if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
+ return;
+
+ drm_vblank_put(drm_vblank_crtc(dev, pipe));
+}
+
/**
* drm_crtc_vblank_put - give up ownership of vblank events
* @crtc: which counter to give up
@@ -1284,7 +1299,7 @@ void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
*/
void drm_crtc_vblank_put(struct drm_crtc *crtc)
{
- drm_vblank_put(crtc->dev, drm_crtc_index(crtc));
+ _drm_vblank_put(crtc->dev, drm_crtc_index(crtc));
}
EXPORT_SYMBOL(drm_crtc_vblank_put);
@@ -1306,20 +1321,20 @@ int drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
int ret;
u64 last;
- ret = drm_vblank_get(dev, pipe);
+ ret = drm_vblank_get(vblank);
if (drm_WARN(dev, ret, "vblank not available on crtc %i, ret=%i\n",
pipe, ret))
return ret;
- last = drm_vblank_count(dev, pipe);
+ last = drm_vblank_count(vblank);
ret = wait_event_timeout(vblank->queue,
- last != drm_vblank_count(dev, pipe),
+ last != drm_vblank_count(vblank),
msecs_to_jiffies(1000));
drm_WARN(dev, ret == 0, "vblank wait timed out on crtc %i\n", pipe);
- drm_vblank_put(dev, pipe);
+ drm_vblank_put(vblank);
return ret ? 0 : -ETIMEDOUT;
}
@@ -1385,7 +1400,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
"wanted %llu, current %llu\n",
e->sequence, seq);
list_del(&e->base.link);
- drm_vblank_put(dev, pipe);
+ _drm_vblank_put(dev, pipe);
send_vblank_event(dev, e, seq, now);
}
@@ -1661,7 +1676,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
e->sequence = req_seq;
if (drm_vblank_passed(seq, req_seq)) {
- drm_vblank_put(dev, pipe);
+ _drm_vblank_put(dev, pipe);
send_vblank_event(dev, e, seq, now);
vblwait->reply.sequence = seq;
} else {
@@ -1678,7 +1693,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
spin_unlock_irq(&dev->event_lock);
kfree(e);
err_put:
- drm_vblank_put(dev, pipe);
+ _drm_vblank_put(dev, pipe);
return ret;
}
@@ -1796,14 +1811,14 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
return 0;
}
- ret = drm_vblank_get(dev, pipe);
+ ret = _drm_vblank_get(dev, pipe);
if (ret) {
drm_dbg_core(dev,
"crtc %d failed to acquire vblank counter, %d\n",
pipe, ret);
return ret;
}
- seq = drm_vblank_count(dev, pipe);
+ seq = _drm_vblank_count(dev, pipe);
switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
case _DRM_VBLANK_RELATIVE:
@@ -1839,7 +1854,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
drm_dbg_core(dev, "waiting on vblank count %llu, crtc %u\n",
req_seq, pipe);
wait = wait_event_interruptible_timeout(vblank->queue,
- drm_vblank_passed(drm_vblank_count(dev, pipe), req_seq) ||
+ drm_vblank_passed(_drm_vblank_count(dev, pipe), req_seq) ||
!READ_ONCE(vblank->enabled),
msecs_to_jiffies(3000));
@@ -1869,7 +1884,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
}
done:
- drm_vblank_put(dev, pipe);
+ _drm_vblank_put(dev, pipe);
return ret;
}
@@ -1895,7 +1910,7 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe)
e->sequence, seq);
list_del(&e->base.link);
- drm_vblank_put(dev, pipe);
+ _drm_vblank_put(dev, pipe);
send_vblank_event(dev, e, seq, now);
}
diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c
index 70f0199251ea..2ef006626d50 100644
--- a/drivers/gpu/drm/drm_vblank_work.c
+++ b/drivers/gpu/drm/drm_vblank_work.c
@@ -58,7 +58,7 @@ void drm_handle_vblank_works(struct drm_vblank_crtc *vblank)
continue;
list_del_init(&work->node);
- drm_vblank_put(vblank->dev, vblank->pipe);
+ drm_vblank_put(vblank);
kthread_queue_work(vblank->worker, &work->base);
wake = true;
}
@@ -80,7 +80,7 @@ void drm_vblank_cancel_pending_works(struct drm_vblank_crtc *vblank)
list_for_each_entry_safe(work, next, &vblank->pending_work, node) {
list_del_init(&work->node);
- drm_vblank_put(vblank->dev, vblank->pipe);
+ drm_vblank_put(vblank);
}
wake_up_all(&vblank->work_wait_queue);
@@ -129,7 +129,7 @@ int drm_vblank_work_schedule(struct drm_vblank_work *work,
goto out;
if (list_empty(&work->node)) {
- ret = drm_vblank_get(dev, vblank->pipe);
+ ret = drm_vblank_get(vblank);
if (ret < 0)
goto out;
} else if (work->count == count) {
@@ -140,7 +140,7 @@ int drm_vblank_work_schedule(struct drm_vblank_work *work,
}
work->count = count;
- cur_vbl = drm_vblank_count(dev, vblank->pipe);
+ cur_vbl = drm_vblank_count(vblank);
passed = drm_vblank_passed(cur_vbl, count);
if (passed)
drm_dbg_core(dev,
@@ -148,7 +148,7 @@ int drm_vblank_work_schedule(struct drm_vblank_work *work,
vblank->pipe, count, cur_vbl);
if (!nextonmiss && passed) {
- drm_vblank_put(dev, vblank->pipe);
+ drm_vblank_put(vblank);
ret = kthread_queue_work(vblank->worker, &work->base);
if (rescheduling) {
@@ -193,7 +193,7 @@ bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work)
spin_lock_irq(&dev->event_lock);
if (!list_empty(&work->node)) {
list_del_init(&work->node);
- drm_vblank_put(vblank->dev, vblank->pipe);
+ drm_vblank_put(vblank);
ret = true;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 08/24] drm/vblank: pass vblank to drm_update_vblank_count()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (6 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 07/24] drm/vblank: pass vlank to drm_vblank_get()/_put()/_count() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 15:54 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 09/24] drm/vblank: pass vblank to drm_handle_vblank_events() Jani Nikula
` (16 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the vblank pointer instead of a dev, pipe pair to simplify code.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 0ae34f848660..d2748ed01c34 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -292,10 +292,11 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe
* Note: caller must hold &drm_device.vbl_lock since this reads & writes
* device vblank fields.
*/
-static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
+static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
bool in_vblank_irq)
{
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
+ struct drm_device *dev = vblank->dev;
+ unsigned int pipe = vblank->pipe;
u32 cur_vblank, diff;
bool rc;
ktime_t t_vblank;
@@ -424,8 +425,8 @@ static u64 _drm_vblank_count(struct drm_device *dev, unsigned int pipe)
u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
- unsigned int pipe = drm_crtc_index(crtc);
- u64 vblank;
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
+ u64 vblank_count;
unsigned long flags;
drm_WARN_ONCE(dev, drm_debug_enabled(DRM_UT_VBL) &&
@@ -434,12 +435,12 @@ u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
spin_lock_irqsave(&dev->vblank_time_lock, flags);
- drm_update_vblank_count(dev, pipe, false);
- vblank = _drm_vblank_count(dev, pipe);
+ drm_update_vblank_count(vblank, false);
+ vblank_count = drm_vblank_count(vblank);
spin_unlock_irqrestore(&dev->vblank_time_lock, flags);
- return vblank;
+ return vblank_count;
}
EXPORT_SYMBOL(drm_crtc_accurate_vblank_count);
@@ -490,7 +491,7 @@ void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
* this time. This makes the count account for the entire time
* between drm_crtc_vblank_on() and drm_crtc_vblank_off().
*/
- drm_update_vblank_count(dev, pipe, false);
+ drm_update_vblank_count(vblank, false);
__disable_vblank(dev, pipe);
vblank->enabled = false;
@@ -1197,7 +1198,7 @@ static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
if (ret) {
atomic_dec(&vblank->refcount);
} else {
- drm_update_vblank_count(dev, pipe, 0);
+ drm_update_vblank_count(vblank, 0);
/* drm_update_vblank_count() includes a wmb so we just
* need to ensure that the compiler emits the write
* to mark the vblank as enabled after the call
@@ -1957,7 +1958,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
return false;
}
- drm_update_vblank_count(dev, pipe, true);
+ drm_update_vblank_count(vblank, true);
spin_unlock(&dev->vblank_time_lock);
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 09/24] drm/vblank: pass vblank to drm_handle_vblank_events()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (7 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 08/24] drm/vblank: pass vblank to drm_update_vblank_count() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 15:56 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 10/24] drm/vblank: use the vblank based interfaces more Jani Nikula
` (15 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the vblank pointer instead of a dev, pipe pair to simplify code.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index d2748ed01c34..91bedf8e6ea8 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1889,8 +1889,10 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
return ret;
}
-static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe)
+static void drm_handle_vblank_events(struct drm_vblank_crtc *vblank)
{
+ struct drm_device *dev = vblank->dev;
+ unsigned int pipe = vblank->pipe;
struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
bool high_prec = false;
struct drm_pending_vblank_event *e, *t;
@@ -1911,7 +1913,7 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe)
e->sequence, seq);
list_del(&e->base.link);
- _drm_vblank_put(dev, pipe);
+ drm_vblank_put(vblank);
send_vblank_event(dev, e, seq, now);
}
@@ -1973,7 +1975,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
vblank->config.offdelay_ms > 0 &&
!atomic_read(&vblank->refcount));
- drm_handle_vblank_events(dev, pipe);
+ drm_handle_vblank_events(vblank);
drm_handle_vblank_works(vblank);
spin_unlock_irqrestore(&dev->event_lock, irqflags);
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 10/24] drm/vblank: use the vblank based interfaces more
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (8 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 09/24] drm/vblank: pass vblank to drm_handle_vblank_events() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 15:56 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 11/24] drm/vblank: pass vblank to drm_queue_vblank_event() Jani Nikula
` (14 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
With the prep work in place, we can get rid of _drm_vblank_get(),
_drm_vblank_put(), and _drm_vblank_count().
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 44 ++++++++----------------------------
1 file changed, 10 insertions(+), 34 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 91bedf8e6ea8..1c0ade41a57f 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -403,14 +403,6 @@ u64 drm_vblank_count(struct drm_vblank_crtc *vblank)
return count;
}
-static u64 _drm_vblank_count(struct drm_device *dev, unsigned int pipe)
-{
- if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
- return 0;
-
- return drm_vblank_count(drm_vblank_crtc(dev, pipe));
-}
-
/**
* drm_crtc_accurate_vblank_count - retrieve the master vblank counter
* @crtc: which counter to retrieve
@@ -940,7 +932,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
*/
u64 drm_crtc_vblank_count(struct drm_crtc *crtc)
{
- return _drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
+ return drm_vblank_count(drm_crtc_vblank_crtc(crtc));
}
EXPORT_SYMBOL(drm_crtc_vblank_count);
@@ -1238,14 +1230,6 @@ int drm_vblank_get(struct drm_vblank_crtc *vblank)
return ret;
}
-static int _drm_vblank_get(struct drm_device *dev, unsigned int pipe)
-{
- if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
- return -EINVAL;
-
- return drm_vblank_get(drm_vblank_crtc(dev, pipe));
-}
-
/**
* drm_crtc_vblank_get - get a reference count on vblank events
* @crtc: which CRTC to own
@@ -1258,7 +1242,7 @@ static int _drm_vblank_get(struct drm_device *dev, unsigned int pipe)
*/
int drm_crtc_vblank_get(struct drm_crtc *crtc)
{
- return _drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
+ return drm_vblank_get(drm_crtc_vblank_crtc(crtc));
}
EXPORT_SYMBOL(drm_crtc_vblank_get);
@@ -1282,14 +1266,6 @@ void drm_vblank_put(struct drm_vblank_crtc *vblank)
}
}
-static void _drm_vblank_put(struct drm_device *dev, unsigned int pipe)
-{
- if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
- return;
-
- drm_vblank_put(drm_vblank_crtc(dev, pipe));
-}
-
/**
* drm_crtc_vblank_put - give up ownership of vblank events
* @crtc: which counter to give up
@@ -1300,7 +1276,7 @@ static void _drm_vblank_put(struct drm_device *dev, unsigned int pipe)
*/
void drm_crtc_vblank_put(struct drm_crtc *crtc)
{
- _drm_vblank_put(crtc->dev, drm_crtc_index(crtc));
+ drm_vblank_put(drm_crtc_vblank_crtc(crtc));
}
EXPORT_SYMBOL(drm_crtc_vblank_put);
@@ -1401,7 +1377,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
"wanted %llu, current %llu\n",
e->sequence, seq);
list_del(&e->base.link);
- _drm_vblank_put(dev, pipe);
+ drm_vblank_put(vblank);
send_vblank_event(dev, e, seq, now);
}
@@ -1677,7 +1653,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
e->sequence = req_seq;
if (drm_vblank_passed(seq, req_seq)) {
- _drm_vblank_put(dev, pipe);
+ drm_vblank_put(vblank);
send_vblank_event(dev, e, seq, now);
vblwait->reply.sequence = seq;
} else {
@@ -1694,7 +1670,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
spin_unlock_irq(&dev->event_lock);
kfree(e);
err_put:
- _drm_vblank_put(dev, pipe);
+ drm_vblank_put(vblank);
return ret;
}
@@ -1812,14 +1788,14 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
return 0;
}
- ret = _drm_vblank_get(dev, pipe);
+ ret = drm_vblank_get(vblank);
if (ret) {
drm_dbg_core(dev,
"crtc %d failed to acquire vblank counter, %d\n",
pipe, ret);
return ret;
}
- seq = _drm_vblank_count(dev, pipe);
+ seq = drm_vblank_count(vblank);
switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
case _DRM_VBLANK_RELATIVE:
@@ -1855,7 +1831,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
drm_dbg_core(dev, "waiting on vblank count %llu, crtc %u\n",
req_seq, pipe);
wait = wait_event_interruptible_timeout(vblank->queue,
- drm_vblank_passed(_drm_vblank_count(dev, pipe), req_seq) ||
+ drm_vblank_passed(drm_vblank_count(vblank), req_seq) ||
!READ_ONCE(vblank->enabled),
msecs_to_jiffies(3000));
@@ -1885,7 +1861,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
}
done:
- _drm_vblank_put(dev, pipe);
+ drm_vblank_put(vblank);
return ret;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 11/24] drm/vblank: pass vblank to drm_queue_vblank_event()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (9 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 10/24] drm/vblank: use the vblank based interfaces more Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 15:57 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 12/24] drm/vblank: pass vblank to drm_wait_vblank_reply() Jani Nikula
` (13 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the vblank pointer instead of a dev, pipe pair to simplify code.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 1c0ade41a57f..5880c43e19a0 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1596,12 +1596,13 @@ void drm_crtc_vblank_restore(struct drm_crtc *crtc)
}
EXPORT_SYMBOL(drm_crtc_vblank_restore);
-static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
+static int drm_queue_vblank_event(struct drm_vblank_crtc *vblank,
u64 req_seq,
union drm_wait_vblank *vblwait,
struct drm_file *file_priv)
{
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
+ struct drm_device *dev = vblank->dev;
+ unsigned int pipe = vblank->pipe;
struct drm_pending_vblank_event *e;
ktime_t now;
u64 seq;
@@ -1822,7 +1823,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
/* must hold on to the vblank ref until the event fires
* drm_vblank_put will be called asynchronously
*/
- return drm_queue_vblank_event(dev, pipe, req_seq, vblwait, file_priv);
+ return drm_queue_vblank_event(vblank, req_seq, vblwait, file_priv);
}
if (req_seq != seq) {
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 12/24] drm/vblank: pass vblank to drm_wait_vblank_reply()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (10 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 11/24] drm/vblank: pass vblank to drm_queue_vblank_event() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 16:01 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 13/24] drm/vblank: pass vblank to drm_vblank_count_and_time() Jani Nikula
` (12 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the vblank pointer instead of a dev, pipe pair to simplify code.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 5880c43e19a0..e33b7fa6f19a 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1702,7 +1702,7 @@ static u64 widen_32_to_64(u32 narrow, u64 near)
return near + (s32) (narrow - near);
}
-static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe,
+static void drm_wait_vblank_reply(struct drm_vblank_crtc *vblank,
struct drm_wait_vblank_reply *reply)
{
ktime_t now;
@@ -1713,7 +1713,7 @@ static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe,
* to store the seconds. This is safe as we always use monotonic
* timestamps since linux-4.15.
*/
- reply->sequence = drm_vblank_count_and_time(dev, pipe, &now);
+ reply->sequence = drm_vblank_count_and_time(vblank->dev, vblank->pipe, &now);
ts = ktime_to_timespec64(now);
reply->tval_sec = (u32)ts.tv_sec;
reply->tval_usec = ts.tv_nsec / 1000;
@@ -1785,7 +1785,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
if (vblank->config.disable_immediate &&
drm_wait_vblank_is_query(vblwait) &&
READ_ONCE(vblank->enabled)) {
- drm_wait_vblank_reply(dev, pipe, &vblwait->reply);
+ drm_wait_vblank_reply(vblank, &vblwait->reply);
return 0;
}
@@ -1852,7 +1852,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
}
if (ret != -EINTR) {
- drm_wait_vblank_reply(dev, pipe, &vblwait->reply);
+ drm_wait_vblank_reply(vblank, &vblwait->reply);
drm_dbg_core(dev, "crtc %d returning %u to client\n",
pipe, vblwait->reply.sequence);
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 13/24] drm/vblank: pass vblank to drm_vblank_count_and_time()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (11 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 12/24] drm/vblank: pass vblank to drm_wait_vblank_reply() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-11 6:52 ` kernel test robot
2025-11-12 16:03 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 14/24] drm/vblank: pass vblank to drm_reset_vblank_timestamp() Jani Nikula
` (11 subsequent siblings)
24 siblings, 2 replies; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the vblank pointer instead of a dev, pipe pair to simplify code.
Drop the pipe check warning, as we can be sure vblank->pipe is within
limits.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 28 +++++++++++-----------------
1 file changed, 11 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index e33b7fa6f19a..0a2e372dd549 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -950,18 +950,12 @@ EXPORT_SYMBOL(drm_crtc_vblank_count);
*
* This is the legacy version of drm_crtc_vblank_count_and_time().
*/
-static u64 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe,
+static u64 drm_vblank_count_and_time(struct drm_vblank_crtc *vblank,
ktime_t *vblanktime)
{
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
u64 vblank_count;
unsigned int seq;
- if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) {
- *vblanktime = 0;
- return 0;
- }
-
do {
seq = read_seqbegin(&vblank->seqlock);
vblank_count = atomic64_read(&vblank->count);
@@ -993,7 +987,7 @@ static u64 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe,
u64 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc,
ktime_t *vblanktime)
{
- return drm_vblank_count_and_time(crtc->dev, drm_crtc_index(crtc),
+ return drm_vblank_count_and_time(drm_crtc_vblank_crtc(crtc),
vblanktime);
}
EXPORT_SYMBOL(drm_crtc_vblank_count_and_time);
@@ -1136,18 +1130,18 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
struct drm_pending_vblank_event *e)
{
struct drm_device *dev = crtc->dev;
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
u64 seq;
- unsigned int pipe = drm_crtc_index(crtc);
ktime_t now;
if (drm_dev_has_vblank(dev)) {
- seq = drm_vblank_count_and_time(dev, pipe, &now);
+ seq = drm_vblank_count_and_time(vblank, &now);
} else {
seq = 0;
now = ktime_get();
}
- e->pipe = pipe;
+ e->pipe = vblank->pipe;
send_vblank_event(dev, e, seq, now);
}
EXPORT_SYMBOL(drm_crtc_send_vblank_event);
@@ -1368,7 +1362,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
spin_unlock(&dev->vbl_lock);
/* Send any queued vblank events, lest the natives grow disquiet */
- seq = drm_vblank_count_and_time(dev, pipe, &now);
+ seq = drm_vblank_count_and_time(vblank, &now);
list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
if (e->pipe != pipe)
@@ -1645,7 +1639,7 @@ static int drm_queue_vblank_event(struct drm_vblank_crtc *vblank,
if (ret)
goto err_unlock;
- seq = drm_vblank_count_and_time(dev, pipe, &now);
+ seq = drm_vblank_count_and_time(vblank, &now);
drm_dbg_core(dev, "event on vblank count %llu, current %llu, crtc %u\n",
req_seq, seq, pipe);
@@ -1713,7 +1707,7 @@ static void drm_wait_vblank_reply(struct drm_vblank_crtc *vblank,
* to store the seconds. This is safe as we always use monotonic
* timestamps since linux-4.15.
*/
- reply->sequence = drm_vblank_count_and_time(vblank->dev, vblank->pipe, &now);
+ reply->sequence = drm_vblank_count_and_time(vblank, &now);
ts = ktime_to_timespec64(now);
reply->tval_sec = (u32)ts.tv_sec;
reply->tval_usec = ts.tv_nsec / 1000;
@@ -1878,7 +1872,7 @@ static void drm_handle_vblank_events(struct drm_vblank_crtc *vblank)
assert_spin_locked(&dev->event_lock);
- seq = drm_vblank_count_and_time(dev, pipe, &now);
+ seq = drm_vblank_count_and_time(vblank, &now);
list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
if (e->pipe != pipe)
@@ -2040,7 +2034,7 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data,
else
get_seq->active = crtc->enabled;
drm_modeset_unlock(&crtc->mutex);
- get_seq->sequence = drm_vblank_count_and_time(dev, pipe, &now);
+ get_seq->sequence = drm_vblank_count_and_time(vblank, &now);
get_seq->sequence_ns = ktime_to_ns(now);
if (!vblank_enabled)
drm_crtc_vblank_put(crtc);
@@ -2101,7 +2095,7 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data,
goto err_free;
}
- seq = drm_vblank_count_and_time(dev, pipe, &now);
+ seq = drm_vblank_count_and_time(vblank, &now);
req_seq = queue_seq->sequence;
if (flags & DRM_CRTC_SEQUENCE_RELATIVE)
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 14/24] drm/vblank: pass vblank to drm_reset_vblank_timestamp()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (12 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 13/24] drm/vblank: pass vblank to drm_vblank_count_and_time() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 16:07 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 15/24] drm/vblank: pass vblank to store_vblank() Jani Nikula
` (10 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the vblank pointer instead of a dev, pipe pair to simplify code.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 0a2e372dd549..93ad785cbc32 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -245,8 +245,10 @@ static u32 __get_vblank_counter(struct drm_device *dev, unsigned int pipe)
* Note: caller must hold &drm_device.vbl_lock since this reads & writes
* device vblank fields.
*/
-static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe)
+static void drm_reset_vblank_timestamp(struct drm_vblank_crtc *vblank)
{
+ struct drm_device *dev = vblank->dev;
+ unsigned int pipe = vblank->pipe;
u32 cur_vblank;
bool rc;
ktime_t t_vblank;
@@ -1487,7 +1489,7 @@ void drm_crtc_vblank_on_config(struct drm_crtc *crtc,
vblank->inmodeset = 0;
}
- drm_reset_vblank_timestamp(dev, pipe);
+ drm_reset_vblank_timestamp(vblank);
/*
* re-enable interrupts if there are users left, or the
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 15/24] drm/vblank: pass vblank to store_vblank()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (13 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 14/24] drm/vblank: pass vblank to drm_reset_vblank_timestamp() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 16:08 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 16/24] drm/vblank: pass vblank to drm_vblank_enable() Jani Nikula
` (9 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the vblank pointer instead of a dev, pipe pair to simplify code.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 93ad785cbc32..86919b1c0c2c 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -188,11 +188,11 @@ drm_crtc_vblank_crtc(struct drm_crtc *crtc)
}
EXPORT_SYMBOL(drm_crtc_vblank_crtc);
-static void store_vblank(struct drm_device *dev, unsigned int pipe,
+static void store_vblank(struct drm_vblank_crtc *vblank,
u32 vblank_count_inc,
ktime_t t_vblank, u32 last)
{
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
+ struct drm_device *dev = vblank->dev;
assert_spin_locked(&dev->vblank_time_lock);
@@ -277,7 +277,7 @@ static void drm_reset_vblank_timestamp(struct drm_vblank_crtc *vblank)
* +1 to make sure user will never see the same
* vblank counter value before and after a modeset
*/
- store_vblank(dev, pipe, 1, t_vblank, cur_vblank);
+ store_vblank(vblank, 1, t_vblank, cur_vblank);
spin_unlock(&dev->vblank_time_lock);
}
@@ -384,7 +384,7 @@ static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
if (!rc && !in_vblank_irq)
t_vblank = 0;
- store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
+ store_vblank(vblank, diff, t_vblank, cur_vblank);
}
u64 drm_vblank_count(struct drm_vblank_crtc *vblank)
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 16/24] drm/vblank: pass vblank to drm_vblank_enable()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (14 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 15/24] drm/vblank: pass vblank to store_vblank() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 16:08 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 17/24] drm/vblank: merge drm_vblank_restore() into drm_crtc_vblank_restore() Jani Nikula
` (8 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the vblank pointer instead of a dev, pipe pair to simplify code.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 86919b1c0c2c..0ff69b06b2bd 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1163,9 +1163,10 @@ static int __enable_vblank(struct drm_device *dev, unsigned int pipe)
return -EINVAL;
}
-static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
+static int drm_vblank_enable(struct drm_vblank_crtc *vblank)
{
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
+ struct drm_device *dev = vblank->dev;
+ unsigned int pipe = vblank->pipe;
int ret = 0;
assert_spin_locked(&dev->vbl_lock);
@@ -1204,7 +1205,6 @@ static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
int drm_vblank_get(struct drm_vblank_crtc *vblank)
{
struct drm_device *dev = vblank->dev;
- int pipe = vblank->pipe;
unsigned long irqflags;
int ret = 0;
@@ -1214,7 +1214,7 @@ int drm_vblank_get(struct drm_vblank_crtc *vblank)
spin_lock_irqsave(&dev->vbl_lock, irqflags);
/* Going from 0->1 means we have to enable interrupts again */
if (atomic_add_return(1, &vblank->refcount) == 1) {
- ret = drm_vblank_enable(dev, pipe);
+ ret = drm_vblank_enable(vblank);
} else {
if (!vblank->enabled) {
atomic_dec(&vblank->refcount);
@@ -1496,7 +1496,7 @@ void drm_crtc_vblank_on_config(struct drm_crtc *crtc,
* user wishes vblank interrupts to be enabled all the time.
*/
if (atomic_read(&vblank->refcount) != 0 || !vblank->config.offdelay_ms)
- drm_WARN_ON(dev, drm_vblank_enable(dev, pipe));
+ drm_WARN_ON(dev, drm_vblank_enable(vblank));
spin_unlock_irq(&dev->vbl_lock);
}
EXPORT_SYMBOL(drm_crtc_vblank_on_config);
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 17/24] drm/vblank: merge drm_vblank_restore() into drm_crtc_vblank_restore()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (15 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 16/24] drm/vblank: pass vblank to drm_vblank_enable() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 16:10 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 18/24] drm/vblank: add drm_crtc_from_vblank() helper Jani Nikula
` (7 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
The extra function serves no useful purpose.
This allows us to drop another superfluous pipe check warning.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 57 +++++++++++++++---------------------
1 file changed, 23 insertions(+), 34 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 0ff69b06b2bd..64cd96207ad5 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1524,23 +1524,41 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc)
}
EXPORT_SYMBOL(drm_crtc_vblank_on);
-static void drm_vblank_restore(struct drm_device *dev, unsigned int pipe)
+/**
+ * drm_crtc_vblank_restore - estimate missed vblanks and update vblank count.
+ * @crtc: CRTC in question
+ *
+ * Power manamement features can cause frame counter resets between vblank
+ * disable and enable. Drivers can use this function in their
+ * &drm_crtc_funcs.enable_vblank implementation to estimate missed vblanks since
+ * the last &drm_crtc_funcs.disable_vblank using timestamps and update the
+ * vblank counter.
+ *
+ * Note that drivers must have race-free high-precision timestamping support,
+ * i.e. &drm_crtc_funcs.get_vblank_timestamp must be hooked up and
+ * &drm_vblank_crtc_config.disable_immediate must be set to indicate the
+ * time-stamping functions are race-free against vblank hardware counter
+ * increments.
+ */
+void drm_crtc_vblank_restore(struct drm_crtc *crtc)
{
+ struct drm_device *dev = crtc->dev;
+ unsigned int pipe = drm_crtc_index(crtc);
+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
ktime_t t_vblank;
- struct drm_vblank_crtc *vblank;
int framedur_ns;
u64 diff_ns;
u32 cur_vblank, diff = 1;
int count = DRM_TIMESTAMP_MAXRETRIES;
u32 max_vblank_count = drm_max_vblank_count(dev, pipe);
- if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
- return;
+ drm_WARN_ON_ONCE(dev, !crtc->funcs->get_vblank_timestamp);
+ drm_WARN_ON_ONCE(dev, vblank->inmodeset);
+ drm_WARN_ON_ONCE(dev, !vblank->config.disable_immediate);
assert_spin_locked(&dev->vbl_lock);
assert_spin_locked(&dev->vblank_time_lock);
- vblank = drm_vblank_crtc(dev, pipe);
drm_WARN_ONCE(dev,
drm_debug_enabled(DRM_UT_VBL) && !vblank->framedur_ns,
"Cannot compute missed vblanks without frame duration\n");
@@ -1561,35 +1579,6 @@ static void drm_vblank_restore(struct drm_device *dev, unsigned int pipe)
diff, diff_ns, framedur_ns, cur_vblank - vblank->last);
vblank->last = (cur_vblank - diff) & max_vblank_count;
}
-
-/**
- * drm_crtc_vblank_restore - estimate missed vblanks and update vblank count.
- * @crtc: CRTC in question
- *
- * Power manamement features can cause frame counter resets between vblank
- * disable and enable. Drivers can use this function in their
- * &drm_crtc_funcs.enable_vblank implementation to estimate missed vblanks since
- * the last &drm_crtc_funcs.disable_vblank using timestamps and update the
- * vblank counter.
- *
- * Note that drivers must have race-free high-precision timestamping support,
- * i.e. &drm_crtc_funcs.get_vblank_timestamp must be hooked up and
- * &drm_vblank_crtc_config.disable_immediate must be set to indicate the
- * time-stamping functions are race-free against vblank hardware counter
- * increments.
- */
-void drm_crtc_vblank_restore(struct drm_crtc *crtc)
-{
- struct drm_device *dev = crtc->dev;
- unsigned int pipe = drm_crtc_index(crtc);
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
-
- drm_WARN_ON_ONCE(dev, !crtc->funcs->get_vblank_timestamp);
- drm_WARN_ON_ONCE(dev, vblank->inmodeset);
- drm_WARN_ON_ONCE(dev, !vblank->config.disable_immediate);
-
- drm_vblank_restore(dev, pipe);
-}
EXPORT_SYMBOL(drm_crtc_vblank_restore);
static int drm_queue_vblank_event(struct drm_vblank_crtc *vblank,
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 18/24] drm/vblank: add drm_crtc_from_vblank() helper
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (16 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 17/24] drm/vblank: merge drm_vblank_restore() into drm_crtc_vblank_restore() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 16:38 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 19/24] drm/vblank: pass vblank to __get_vblank_counter() and drm_max_vblank_count() Jani Nikula
` (6 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
We have a handful of places where we need to get the crtc from the
vblank. Add a small helper for it.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 64cd96207ad5..34d0b6939d52 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -188,6 +188,11 @@ drm_crtc_vblank_crtc(struct drm_crtc *crtc)
}
EXPORT_SYMBOL(drm_crtc_vblank_crtc);
+static struct drm_crtc *drm_crtc_from_vblank(struct drm_vblank_crtc *vblank)
+{
+ return drm_crtc_from_index(vblank->dev, vblank->pipe);
+}
+
static void store_vblank(struct drm_vblank_crtc *vblank,
u32 vblank_count_inc,
ktime_t t_vblank, u32 last)
@@ -1605,7 +1610,7 @@ static int drm_queue_vblank_event(struct drm_vblank_crtc *vblank,
e->event.vbl.user_data = vblwait->request.signal;
e->event.vbl.crtc_id = 0;
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
+ struct drm_crtc *crtc = drm_crtc_from_vblank(vblank);
if (crtc)
e->event.vbl.crtc_id = crtc->base.id;
@@ -1855,7 +1860,7 @@ static void drm_handle_vblank_events(struct drm_vblank_crtc *vblank)
{
struct drm_device *dev = vblank->dev;
unsigned int pipe = vblank->pipe;
- struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
+ struct drm_crtc *crtc = drm_crtc_from_vblank(vblank);
bool high_prec = false;
struct drm_pending_vblank_event *e, *t;
ktime_t now;
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 19/24] drm/vblank: pass vblank to __get_vblank_counter() and drm_max_vblank_count()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (17 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 18/24] drm/vblank: add drm_crtc_from_vblank() helper Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 16:40 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 20/24] drm/vblank: pass vblank to __{enable,disable}_vblank() Jani Nikula
` (5 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the vblank pointer instead of a dev, pipe pair to simplify code.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 34d0b6939d52..955cea949d3d 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -209,27 +209,27 @@ static void store_vblank(struct drm_vblank_crtc *vblank,
write_sequnlock(&vblank->seqlock);
}
-static u32 drm_max_vblank_count(struct drm_device *dev, unsigned int pipe)
+static u32 drm_max_vblank_count(struct drm_vblank_crtc *vblank)
{
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
-
- return vblank->max_vblank_count ?: dev->max_vblank_count;
+ return vblank->max_vblank_count ?: vblank->dev->max_vblank_count;
}
/*
* "No hw counter" fallback implementation of .get_vblank_counter() hook,
* if there is no usable hardware frame counter available.
*/
-static u32 drm_vblank_no_hw_counter(struct drm_device *dev, unsigned int pipe)
+static u32 drm_vblank_no_hw_counter(struct drm_vblank_crtc *vblank)
{
- drm_WARN_ON_ONCE(dev, drm_max_vblank_count(dev, pipe) != 0);
+ drm_WARN_ON_ONCE(vblank->dev, drm_max_vblank_count(vblank) != 0);
return 0;
}
-static u32 __get_vblank_counter(struct drm_device *dev, unsigned int pipe)
+static u32 __get_vblank_counter(struct drm_vblank_crtc *vblank)
{
+ struct drm_device *dev = vblank->dev;
+
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
+ struct drm_crtc *crtc = drm_crtc_from_vblank(vblank);
if (drm_WARN_ON(dev, !crtc))
return 0;
@@ -238,7 +238,7 @@ static u32 __get_vblank_counter(struct drm_device *dev, unsigned int pipe)
return crtc->funcs->get_vblank_counter(crtc);
}
- return drm_vblank_no_hw_counter(dev, pipe);
+ return drm_vblank_no_hw_counter(vblank);
}
/*
@@ -266,9 +266,9 @@ static void drm_reset_vblank_timestamp(struct drm_vblank_crtc *vblank)
* when drm_vblank_enable() applies the diff
*/
do {
- cur_vblank = __get_vblank_counter(dev, pipe);
+ cur_vblank = __get_vblank_counter(vblank);
rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false);
- } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
+ } while (cur_vblank != __get_vblank_counter(vblank) && --count > 0);
/*
* Only reinitialize corresponding vblank timestamp if high-precision query
@@ -309,7 +309,7 @@ static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
ktime_t t_vblank;
int count = DRM_TIMESTAMP_MAXRETRIES;
int framedur_ns = vblank->framedur_ns;
- u32 max_vblank_count = drm_max_vblank_count(dev, pipe);
+ u32 max_vblank_count = drm_max_vblank_count(vblank);
/*
* Interrupts were disabled prior to this call, so deal with counter
@@ -324,9 +324,9 @@ static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
* corresponding vblank timestamp.
*/
do {
- cur_vblank = __get_vblank_counter(dev, pipe);
+ cur_vblank = __get_vblank_counter(vblank);
rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, in_vblank_irq);
- } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
+ } while (cur_vblank != __get_vblank_counter(vblank) && --count > 0);
if (max_vblank_count) {
/* trust the hw counter when it's around */
@@ -1555,7 +1555,7 @@ void drm_crtc_vblank_restore(struct drm_crtc *crtc)
u64 diff_ns;
u32 cur_vblank, diff = 1;
int count = DRM_TIMESTAMP_MAXRETRIES;
- u32 max_vblank_count = drm_max_vblank_count(dev, pipe);
+ u32 max_vblank_count = drm_max_vblank_count(vblank);
drm_WARN_ON_ONCE(dev, !crtc->funcs->get_vblank_timestamp);
drm_WARN_ON_ONCE(dev, vblank->inmodeset);
@@ -1570,9 +1570,9 @@ void drm_crtc_vblank_restore(struct drm_crtc *crtc)
framedur_ns = vblank->framedur_ns;
do {
- cur_vblank = __get_vblank_counter(dev, pipe);
+ cur_vblank = __get_vblank_counter(vblank);
drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false);
- } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
+ } while (cur_vblank != __get_vblank_counter(vblank) && --count > 0);
diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
if (framedur_ns)
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 20/24] drm/vblank: pass vblank to __{enable,disable}_vblank()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (18 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 19/24] drm/vblank: pass vblank to __get_vblank_counter() and drm_max_vblank_count() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 16:41 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 21/24] drm/vblank: pass vblank to drm_get_last_vbltimestamp() Jani Nikula
` (4 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the vblank pointer instead of a dev, pipe pair to simplify code.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 955cea949d3d..a274b4a7b1c2 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -443,10 +443,12 @@ u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
}
EXPORT_SYMBOL(drm_crtc_accurate_vblank_count);
-static void __disable_vblank(struct drm_device *dev, unsigned int pipe)
+static void __disable_vblank(struct drm_vblank_crtc *vblank)
{
+ struct drm_device *dev = vblank->dev;
+
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
+ struct drm_crtc *crtc = drm_crtc_from_vblank(vblank);
if (drm_WARN_ON(dev, !crtc))
return;
@@ -491,7 +493,7 @@ void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
* between drm_crtc_vblank_on() and drm_crtc_vblank_off().
*/
drm_update_vblank_count(vblank, false);
- __disable_vblank(dev, pipe);
+ __disable_vblank(vblank);
vblank->enabled = false;
out:
@@ -1153,10 +1155,12 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
}
EXPORT_SYMBOL(drm_crtc_send_vblank_event);
-static int __enable_vblank(struct drm_device *dev, unsigned int pipe)
+static int __enable_vblank(struct drm_vblank_crtc *vblank)
{
+ struct drm_device *dev = vblank->dev;
+
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
- struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
+ struct drm_crtc *crtc = drm_crtc_from_vblank(vblank);
if (drm_WARN_ON(dev, !crtc))
return 0;
@@ -1186,7 +1190,7 @@ static int drm_vblank_enable(struct drm_vblank_crtc *vblank)
* timestamps. Filtercode in drm_handle_vblank() will
* prevent double-accounting of same vblank interval.
*/
- ret = __enable_vblank(dev, pipe);
+ ret = __enable_vblank(vblank);
drm_dbg_core(dev, "enabling vblank on crtc %u, ret: %d\n",
pipe, ret);
if (ret) {
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 21/24] drm/vblank: pass vblank to drm_get_last_vbltimestamp()
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (19 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 20/24] drm/vblank: pass vblank to __{enable,disable}_vblank() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 16:44 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 22/24] drm/vblank: pass vblank to drm_vblank_disable_and_save(), make static Jani Nikula
` (3 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the vblank pointer instead of a dev, pipe pair to simplify code.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 20 ++++++++------------
1 file changed, 8 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index a274b4a7b1c2..ee9355d5069b 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -162,9 +162,8 @@
*/
#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
-static bool
-drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
- ktime_t *tvblank, bool in_vblank_irq);
+static bool drm_get_last_vbltimestamp(struct drm_vblank_crtc *vblank,
+ ktime_t *tvblank, bool in_vblank_irq);
static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */
@@ -253,7 +252,6 @@ static u32 __get_vblank_counter(struct drm_vblank_crtc *vblank)
static void drm_reset_vblank_timestamp(struct drm_vblank_crtc *vblank)
{
struct drm_device *dev = vblank->dev;
- unsigned int pipe = vblank->pipe;
u32 cur_vblank;
bool rc;
ktime_t t_vblank;
@@ -267,7 +265,7 @@ static void drm_reset_vblank_timestamp(struct drm_vblank_crtc *vblank)
*/
do {
cur_vblank = __get_vblank_counter(vblank);
- rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false);
+ rc = drm_get_last_vbltimestamp(vblank, &t_vblank, false);
} while (cur_vblank != __get_vblank_counter(vblank) && --count > 0);
/*
@@ -325,7 +323,7 @@ static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
*/
do {
cur_vblank = __get_vblank_counter(vblank);
- rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, in_vblank_irq);
+ rc = drm_get_last_vbltimestamp(vblank, &t_vblank, in_vblank_irq);
} while (cur_vblank != __get_vblank_counter(vblank) && --count > 0);
if (max_vblank_count) {
@@ -909,11 +907,10 @@ drm_crtc_get_last_vbltimestamp(struct drm_crtc *crtc, ktime_t *tvblank,
return ret;
}
-static bool
-drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
- ktime_t *tvblank, bool in_vblank_irq)
+static bool drm_get_last_vbltimestamp(struct drm_vblank_crtc *vblank,
+ ktime_t *tvblank, bool in_vblank_irq)
{
- struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
+ struct drm_crtc *crtc = drm_crtc_from_vblank(vblank);
return drm_crtc_get_last_vbltimestamp(crtc, tvblank, in_vblank_irq);
}
@@ -1552,7 +1549,6 @@ EXPORT_SYMBOL(drm_crtc_vblank_on);
void drm_crtc_vblank_restore(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
- unsigned int pipe = drm_crtc_index(crtc);
struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
ktime_t t_vblank;
int framedur_ns;
@@ -1575,7 +1571,7 @@ void drm_crtc_vblank_restore(struct drm_crtc *crtc)
do {
cur_vblank = __get_vblank_counter(vblank);
- drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false);
+ drm_get_last_vbltimestamp(vblank, &t_vblank, false);
} while (cur_vblank != __get_vblank_counter(vblank) && --count > 0);
diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 22/24] drm/vblank: pass vblank to drm_vblank_disable_and_save(), make static
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (20 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 21/24] drm/vblank: pass vblank to drm_get_last_vbltimestamp() Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-12 16:46 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 23/24] drm/vblank: reduce pipe checks Jani Nikula
` (2 subsequent siblings)
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the vblank pointer instead of a dev, pipe pair to simplify code.
drm_vblank_disable_and_save() is also no longer used outside of
drm_vblank.c; make it static while at it.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_internal.h | 1 -
drivers/gpu/drm/drm_vblank.c | 8 ++++----
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index e9c85c3681f1..6a7b53de03a8 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -100,7 +100,6 @@ static inline bool drm_vblank_passed(u64 seq, u64 ref)
return (seq - ref) <= (1 << 23);
}
-void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
int drm_vblank_get(struct drm_vblank_crtc *vblank);
void drm_vblank_put(struct drm_vblank_crtc *vblank);
u64 drm_vblank_count(struct drm_vblank_crtc *vblank);
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index ee9355d5069b..44fb8d225485 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -462,9 +462,9 @@ static void __disable_vblank(struct drm_vblank_crtc *vblank)
* are preserved, even if there are any spurious vblank irq's after
* disable.
*/
-void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
+static void drm_vblank_disable_and_save(struct drm_vblank_crtc *vblank)
{
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
+ struct drm_device *dev = vblank->dev;
unsigned long irqflags;
assert_spin_locked(&dev->vbl_lock);
@@ -509,7 +509,7 @@ static void vblank_disable_fn(struct timer_list *t)
spin_lock_irqsave(&dev->vbl_lock, irqflags);
if (atomic_read(&vblank->refcount) == 0 && vblank->enabled) {
drm_dbg_core(dev, "disabling vblank on crtc %u\n", pipe);
- drm_vblank_disable_and_save(dev, pipe);
+ drm_vblank_disable_and_save(vblank);
}
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
}
@@ -1355,7 +1355,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
/* Avoid redundant vblank disables without previous
* drm_crtc_vblank_on(). */
if (drm_core_check_feature(dev, DRIVER_ATOMIC) || !vblank->inmodeset)
- drm_vblank_disable_and_save(dev, pipe);
+ drm_vblank_disable_and_save(vblank);
wake_up(&vblank->queue);
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 23/24] drm/vblank: reduce pipe checks
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (21 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 22/24] drm/vblank: pass vblank to drm_vblank_disable_and_save(), make static Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-10 17:45 ` Ville Syrjälä
2025-11-12 16:54 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 24/24] drm/vblank: clean up debug logging Jani Nikula
2025-11-10 17:12 ` ✗ CI.KUnit: failure for drm/vblank: refactoring and cleanups Patchwork
24 siblings, 2 replies; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Now that drm_vblank_crtc() is the only place that indexes dev->vblank[],
and its usage has reduced considerably, add the primary pipe
out-of-bounds check there, and return NULL. Expect callers to check it
and act accordingly.
In drm_crtc_vblank_crtc(), warn and return NULL, and let it go boom. If
the crtc->pipe is out of bounds, it's a driver error that needs to be
fixed.
Remove superfluous pipe checks all around.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 36 +++++++++++++++---------------------
1 file changed, 15 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 44fb8d225485..7829e64e42b4 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -177,13 +177,22 @@ MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
static struct drm_vblank_crtc *
drm_vblank_crtc(struct drm_device *dev, unsigned int pipe)
{
+ if (pipe >= dev->num_crtcs)
+ return NULL;
+
return &dev->vblank[pipe];
}
struct drm_vblank_crtc *
drm_crtc_vblank_crtc(struct drm_crtc *crtc)
{
- return drm_vblank_crtc(crtc->dev, drm_crtc_index(crtc));
+ struct drm_vblank_crtc *vblank;
+
+ vblank = drm_vblank_crtc(crtc->dev, drm_crtc_index(crtc));
+ if (drm_WARN_ON(crtc->dev, !vblank))
+ return NULL;
+
+ return vblank;
}
EXPORT_SYMBOL(drm_crtc_vblank_crtc);
@@ -631,7 +640,6 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
const struct drm_display_mode *mode)
{
struct drm_device *dev = crtc->dev;
- unsigned int pipe = drm_crtc_index(crtc);
struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
int linedur_ns = 0, framedur_ns = 0;
int dotclock = mode->crtc_clock;
@@ -639,9 +647,6 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
if (!drm_dev_has_vblank(dev))
return;
- if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
- return;
-
/* Valid dotclock? */
if (dotclock > 0) {
int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
@@ -724,11 +729,6 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
int vpos, hpos, i;
int delta_ns, duration_ns;
- if (pipe >= dev->num_crtcs) {
- drm_err(dev, "Invalid crtc %u\n", pipe);
- return false;
- }
-
/* Scanout position query not supported? Should not happen. */
if (!get_scanout_position) {
drm_err(dev, "Called from CRTC w/o get_scanout_position()!?\n");
@@ -1339,9 +1339,6 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
ktime_t now;
u64 seq;
- if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
- return;
-
/*
* Grab event_lock early to prevent vblank work from being scheduled
* while we're in the middle of shutting down vblank interrupts
@@ -1480,9 +1477,6 @@ void drm_crtc_vblank_on_config(struct drm_crtc *crtc,
unsigned int pipe = drm_crtc_index(crtc);
struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
- if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
- return;
-
spin_lock_irq(&dev->vbl_lock);
drm_dbg_vbl(dev, "crtc %d, vblank enabled %d, inmodeset %d\n",
pipe, vblank->enabled, vblank->inmodeset);
@@ -1764,10 +1758,9 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
pipe = pipe_index;
}
- if (pipe >= dev->num_crtcs)
- return -EINVAL;
-
vblank = drm_vblank_crtc(dev, pipe);
+ if (!vblank)
+ return -EINVAL;
/* If the counter is currently enabled and accurate, short-circuit
* queries to return the cached timestamp of the last vblank.
@@ -1902,14 +1895,15 @@ static void drm_handle_vblank_events(struct drm_vblank_crtc *vblank)
*/
bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
{
- struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
+ struct drm_vblank_crtc *vblank;
unsigned long irqflags;
bool disable_irq;
if (drm_WARN_ON_ONCE(dev, !drm_dev_has_vblank(dev)))
return false;
- if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
+ vblank = drm_vblank_crtc(dev, pipe);
+ if (drm_WARN_ON(dev, !vblank))
return false;
spin_lock_irqsave(&dev->event_lock, irqflags);
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 24/24] drm/vblank: clean up debug logging
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (22 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 23/24] drm/vblank: reduce pipe checks Jani Nikula
@ 2025-11-10 16:17 ` Jani Nikula
2025-11-13 14:05 ` Thomas Zimmermann
2025-11-10 17:12 ` ✗ CI.KUnit: failure for drm/vblank: refactoring and cleanups Patchwork
24 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-10 16:17 UTC (permalink / raw)
To: dri-devel
Cc: intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Use the usual [CRTC:%d:%s] when crtc is available. Start using a new
uniform [VBLANK:%u] prefix with the pipe when crtc is not
available. Remove extra line breaks. Use string choice helpers here and
there. Use %pe to decode error returns.
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
drivers/gpu/drm/drm_vblank.c | 109 ++++++++++++++++-------------------
1 file changed, 50 insertions(+), 59 deletions(-)
diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 7829e64e42b4..5ee132b3a6b5 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -27,6 +27,7 @@
#include <linux/export.h>
#include <linux/kthread.h>
#include <linux/moduleparam.h>
+#include <linux/string_choices.h>
#include <drm/drm_crtc.h>
#include <drm/drm_drv.h>
@@ -347,14 +348,13 @@ static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
* frame/field duration.
*/
- drm_dbg_vbl(dev, "crtc %u: Calculating number of vblanks."
- " diff_ns = %lld, framedur_ns = %d)\n",
+ drm_dbg_vbl(dev, "[VBLANK:%u] Calculating number of vblanks. diff_ns = %lld, framedur_ns = %d)\n",
pipe, (long long)diff_ns, framedur_ns);
diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
if (diff == 0 && in_vblank_irq)
- drm_dbg_vbl(dev, "crtc %u: Redundant vblirq ignored\n",
+ drm_dbg_vbl(dev, "[VBLANK:%u] Redundant vblirq ignored\n",
pipe);
} else {
/* some kind of default for drivers w/o accurate vbl timestamping */
@@ -372,13 +372,12 @@ static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
*/
if (diff > 1 && (vblank->inmodeset & 0x2)) {
drm_dbg_vbl(dev,
- "clamping vblank bump to 1 on crtc %u: diffr=%u"
- " due to pre-modeset.\n", pipe, diff);
+ "[VBLANK:%u] clamping vblank bump to 1: diffr=%u due to pre-modeset.\n",
+ pipe, diff);
diff = 1;
}
- drm_dbg_vbl(dev, "updating vblank count on crtc %u:"
- " current=%llu, diff=%u, hw=%u hw_last=%u\n",
+ drm_dbg_vbl(dev, "[VBLANK:%u] updating vblank count: current=%llu, diff=%u, hw=%u hw_last=%u\n",
pipe, (unsigned long long)atomic64_read(&vblank->count),
diff, cur_vblank, vblank->last);
@@ -517,7 +516,7 @@ static void vblank_disable_fn(struct timer_list *t)
spin_lock_irqsave(&dev->vbl_lock, irqflags);
if (atomic_read(&vblank->refcount) == 0 && vblank->enabled) {
- drm_dbg_core(dev, "disabling vblank on crtc %u\n", pipe);
+ drm_dbg_core(dev, "[VBLANK:%u] disabling vblank\n", pipe);
drm_vblank_disable_and_save(vblank);
}
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
@@ -665,8 +664,8 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
framedur_ns /= 2;
} else {
- drm_err(dev, "crtc %u: Can't calculate constants, dotclock = 0!\n",
- crtc->base.id);
+ drm_err(dev, "[CRTC:%d:%s] Can't calculate constants, dotclock = 0!\n",
+ crtc->base.id, crtc->name);
}
vblank->linedur_ns = linedur_ns;
@@ -674,11 +673,11 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
drm_mode_copy(&vblank->hwmode, mode);
drm_dbg_core(dev,
- "crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
- crtc->base.id, mode->crtc_htotal,
+ "[CRTC:%d:%s] hwmode: htotal %d, vtotal %d, vdisplay %d\n",
+ crtc->base.id, crtc->name, mode->crtc_htotal,
mode->crtc_vtotal, mode->crtc_vdisplay);
- drm_dbg_core(dev, "crtc %u: clock %d kHz framedur %d linedur %d\n",
- crtc->base.id, dotclock, framedur_ns, linedur_ns);
+ drm_dbg_core(dev, "[CRTC:%d:%s] clock %d kHz framedur %d linedur %d\n",
+ crtc->base.id, crtc->name, dotclock, framedur_ns, linedur_ns);
}
EXPORT_SYMBOL(drm_calc_timestamping_constants);
@@ -731,7 +730,8 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
/* Scanout position query not supported? Should not happen. */
if (!get_scanout_position) {
- drm_err(dev, "Called from CRTC w/o get_scanout_position()!?\n");
+ drm_err(dev, "[CRTC:%d:%s] Called from CRTC w/o get_scanout_position()!?\n",
+ crtc->base.id, crtc->name);
return false;
}
@@ -744,7 +744,7 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
* Happens during initial modesetting of a crtc.
*/
if (mode->crtc_clock == 0) {
- drm_dbg_core(dev, "crtc %u: Noop due to uninitialized mode.\n",
+ drm_dbg_core(dev, "[VBLANK:%u] Noop due to uninitialized mode.\n",
pipe);
drm_WARN_ON_ONCE(dev, drm_drv_uses_atomic_modeset(dev));
return false;
@@ -769,9 +769,8 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
/* Return as no-op if scanout query unsupported or failed. */
if (!vbl_status) {
- drm_dbg_core(dev,
- "crtc %u : scanoutpos query failed.\n",
- pipe);
+ drm_dbg_core(dev, "[CRTC:%d:%s] scanoutpos query failed.\n",
+ crtc->base.id, crtc->name);
return false;
}
@@ -785,9 +784,8 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
/* Noisy system timing? */
if (i == DRM_TIMESTAMP_MAXRETRIES) {
- drm_dbg_core(dev,
- "crtc %u: Noisy timestamp %d us > %d us [%d reps].\n",
- pipe, duration_ns / 1000, *max_error / 1000, i);
+ drm_dbg_core(dev, "[CRTC:%d:%s] Noisy timestamp %d us > %d us [%d reps].\n",
+ crtc->base.id, crtc->name, duration_ns / 1000, *max_error / 1000, i);
}
/* Return upper bound of timestamp precision error. */
@@ -811,9 +809,8 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
ts_etime = ktime_to_timespec64(etime);
ts_vblank_time = ktime_to_timespec64(*vblank_time);
- drm_dbg_vbl(dev,
- "crtc %u : v p(%d,%d)@ %lld.%06ld -> %lld.%06ld [e %d us, %d rep]\n",
- pipe, hpos, vpos,
+ drm_dbg_vbl(dev, "[CRTC:%d:%s] v p(%d,%d)@ %lld.%06ld -> %lld.%06ld [e %d us, %d rep]\n",
+ crtc->base.id, crtc->name, hpos, vpos,
(u64)ts_etime.tv_sec, ts_etime.tv_nsec / 1000,
(u64)ts_vblank_time.tv_sec, ts_vblank_time.tv_nsec / 1000,
duration_ns / 1000, i);
@@ -1188,7 +1185,7 @@ static int drm_vblank_enable(struct drm_vblank_crtc *vblank)
* prevent double-accounting of same vblank interval.
*/
ret = __enable_vblank(vblank);
- drm_dbg_core(dev, "enabling vblank on crtc %u, ret: %d\n",
+ drm_dbg_core(dev, "[VBLANK:%u] enabling vblank, ret: %d\n",
pipe, ret);
if (ret) {
atomic_dec(&vblank->refcount);
@@ -1346,8 +1343,9 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
spin_lock_irq(&dev->event_lock);
spin_lock(&dev->vbl_lock);
- drm_dbg_vbl(dev, "crtc %d, vblank enabled %d, inmodeset %d\n",
- pipe, vblank->enabled, vblank->inmodeset);
+ drm_dbg_vbl(dev, "[CRTC:%d:%s] vblank %s, inmodeset: %s\n",
+ crtc->base.id, crtc->name, str_enabled_disabled(vblank->enabled),
+ str_yes_no(vblank->inmodeset));
/* Avoid redundant vblank disables without previous
* drm_crtc_vblank_on(). */
@@ -1372,9 +1370,8 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
if (e->pipe != pipe)
continue;
- drm_dbg_core(dev, "Sending premature vblank event on disable: "
- "wanted %llu, current %llu\n",
- e->sequence, seq);
+ drm_dbg_core(dev, "[CRTC:%d:%s] Sending premature vblank event on disable: wanted %llu, current %llu\n",
+ crtc->base.id, crtc->name, e->sequence, seq);
list_del(&e->base.link);
drm_vblank_put(vblank);
send_vblank_event(dev, e, seq, now);
@@ -1474,12 +1471,12 @@ void drm_crtc_vblank_on_config(struct drm_crtc *crtc,
const struct drm_vblank_crtc_config *config)
{
struct drm_device *dev = crtc->dev;
- unsigned int pipe = drm_crtc_index(crtc);
struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
spin_lock_irq(&dev->vbl_lock);
- drm_dbg_vbl(dev, "crtc %d, vblank enabled %d, inmodeset %d\n",
- pipe, vblank->enabled, vblank->inmodeset);
+ drm_dbg_vbl(dev, "[CRTC:%d:%s] vblank %s, inmodeset: %s\n",
+ crtc->base.id, crtc->name, str_enabled_disabled(vblank->enabled),
+ str_yes_no(vblank->inmodeset));
vblank->config = *config;
@@ -1573,8 +1570,8 @@ void drm_crtc_vblank_restore(struct drm_crtc *crtc)
diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
- drm_dbg_vbl(dev,
- "missed %d vblanks in %lld ns, frame duration=%d ns, hw_diff=%d\n",
+ drm_dbg_vbl(dev, "[CRTC:%d:%s] missed %d vblanks in %lld ns, frame duration=%d ns, hw_diff=%d\n",
+ crtc->base.id, crtc->name,
diff, diff_ns, framedur_ns, cur_vblank - vblank->last);
vblank->last = (cur_vblank - diff) & max_vblank_count;
}
@@ -1631,8 +1628,8 @@ static int drm_queue_vblank_event(struct drm_vblank_crtc *vblank,
seq = drm_vblank_count_and_time(vblank, &now);
- drm_dbg_core(dev, "event on vblank count %llu, current %llu, crtc %u\n",
- req_seq, seq, pipe);
+ drm_dbg_core(dev, "[VBLANK:%u] event on vblank count %llu, current %llu\n",
+ pipe, req_seq, seq);
trace_drm_vblank_event_queued(file_priv, pipe, req_seq);
@@ -1728,8 +1725,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
if (vblwait->request.type &
~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK |
_DRM_VBLANK_HIGH_CRTC_MASK)) {
- drm_dbg_core(dev,
- "Unsupported type value 0x%x, supported mask 0x%x\n",
+ drm_dbg_core(dev, "Unsupported type value 0x%x, supported mask 0x%x\n",
vblwait->request.type,
(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK |
_DRM_VBLANK_HIGH_CRTC_MASK));
@@ -1774,9 +1770,8 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
ret = drm_vblank_get(vblank);
if (ret) {
- drm_dbg_core(dev,
- "crtc %d failed to acquire vblank counter, %d\n",
- pipe, ret);
+ drm_dbg_core(dev, "[VBLANK:%u] failed to acquire vblank counter %pe\n",
+ pipe, ERR_PTR(ret));
return ret;
}
seq = drm_vblank_count(vblank);
@@ -1812,8 +1807,8 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
if (req_seq != seq) {
int wait;
- drm_dbg_core(dev, "waiting on vblank count %llu, crtc %u\n",
- req_seq, pipe);
+ drm_dbg_core(dev, "[VBLANK:%d] waiting on vblank count %llu\n",
+ pipe, req_seq);
wait = wait_event_interruptible_timeout(vblank->queue,
drm_vblank_passed(drm_vblank_count(vblank), req_seq) ||
!READ_ONCE(vblank->enabled),
@@ -1837,10 +1832,10 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
if (ret != -EINTR) {
drm_wait_vblank_reply(vblank, &vblwait->reply);
- drm_dbg_core(dev, "crtc %d returning %u to client\n",
+ drm_dbg_core(dev, "[VBLANK:%u] returning %u to client\n",
pipe, vblwait->reply.sequence);
} else {
- drm_dbg_core(dev, "crtc %d vblank wait interrupted by signal\n",
+ drm_dbg_core(dev, "[VBLANK:%u] vblank wait interrupted by signal\n",
pipe);
}
@@ -1869,8 +1864,8 @@ static void drm_handle_vblank_events(struct drm_vblank_crtc *vblank)
if (!drm_vblank_passed(seq, e->sequence))
continue;
- drm_dbg_core(dev, "vblank event on %llu, current %llu\n",
- e->sequence, seq);
+ drm_dbg_core(dev, "[VBLANK:%u] vblank event on %llu, current %llu\n",
+ pipe, e->sequence, seq);
list_del(&e->base.link);
drm_vblank_put(vblank);
@@ -1987,7 +1982,6 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data,
{
struct drm_crtc *crtc;
struct drm_vblank_crtc *vblank;
- int pipe;
struct drm_crtc_get_sequence *get_seq = data;
ktime_t now;
bool vblank_enabled;
@@ -2003,8 +1997,6 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data,
if (!crtc)
return -ENOENT;
- pipe = drm_crtc_index(crtc);
-
vblank = drm_crtc_vblank_crtc(crtc);
vblank_enabled = READ_ONCE(vblank->config.disable_immediate) &&
READ_ONCE(vblank->enabled);
@@ -2012,9 +2004,8 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data,
if (!vblank_enabled) {
ret = drm_crtc_vblank_get(crtc);
if (ret) {
- drm_dbg_core(dev,
- "crtc %d failed to acquire vblank counter, %d\n",
- pipe, ret);
+ drm_dbg_core(dev, "[CRTC:%d:%s] failed to acquire vblank counter %pe\n",
+ crtc->base.id, crtc->name, ERR_PTR(ret));
return ret;
}
}
@@ -2079,9 +2070,8 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data,
ret = drm_crtc_vblank_get(crtc);
if (ret) {
- drm_dbg_core(dev,
- "crtc %d failed to acquire vblank counter, %d\n",
- pipe, ret);
+ drm_dbg_core(dev, "[CRTC:%d:%s] failed to acquire vblank counter %pe\n",
+ crtc->base.id, crtc->name, ERR_PTR(ret));
goto err_free;
}
@@ -2166,7 +2156,8 @@ static enum hrtimer_restart drm_vblank_timer_function(struct hrtimer *timer)
ret_overrun = hrtimer_forward_now(&vtimer->timer, interval);
if (ret_overrun != 1)
- drm_dbg_vbl(dev, "vblank timer overrun\n");
+ drm_dbg_vbl(dev, "[CRTC:%d:%s] vblank timer overrun\n",
+ crtc->base.id, crtc->name);
if (crtc_funcs->handle_vblank_timeout)
succ = crtc_funcs->handle_vblank_timeout(crtc);
--
2.47.3
^ permalink raw reply related [flat|nested] 59+ messages in thread
* ✗ CI.KUnit: failure for drm/vblank: refactoring and cleanups
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
` (23 preceding siblings ...)
2025-11-10 16:17 ` [PATCH 24/24] drm/vblank: clean up debug logging Jani Nikula
@ 2025-11-10 17:12 ` Patchwork
24 siblings, 0 replies; 59+ messages in thread
From: Patchwork @ 2025-11-10 17:12 UTC (permalink / raw)
To: Jani Nikula; +Cc: intel-xe
== Series Details ==
Series: drm/vblank: refactoring and cleanups
URL : https://patchwork.freedesktop.org/series/157332/
State : failure
== Summary ==
+ trap cleanup EXIT
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/xe/.kunitconfig
[17:11:12] Configuring KUnit Kernel ...
Generating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[17:11:16] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=48
[17:11:47] Starting KUnit Kernel (1/1)...
[17:11:47] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[17:11:47] ================== guc_buf (11 subtests) ===================
[17:11:47] [PASSED] test_smallest
[17:11:47] [PASSED] test_largest
[17:11:47] [PASSED] test_granular
[17:11:47] [PASSED] test_unique
[17:11:47] [PASSED] test_overlap
[17:11:47] [PASSED] test_reusable
[17:11:47] [PASSED] test_too_big
[17:11:47] [PASSED] test_flush
[17:11:47] [PASSED] test_lookup
[17:11:47] [PASSED] test_data
[17:11:47] [PASSED] test_class
[17:11:47] ===================== [PASSED] guc_buf =====================
[17:11:47] =================== guc_dbm (7 subtests) ===================
[17:11:47] [PASSED] test_empty
[17:11:47] [PASSED] test_default
[17:11:47] ======================== test_size ========================
[17:11:47] [PASSED] 4
[17:11:47] [PASSED] 8
[17:11:47] [PASSED] 32
[17:11:47] [PASSED] 256
[17:11:47] ==================== [PASSED] test_size ====================
[17:11:47] ======================= test_reuse ========================
[17:11:47] [PASSED] 4
[17:11:47] [PASSED] 8
[17:11:47] [PASSED] 32
[17:11:47] [PASSED] 256
[17:11:47] =================== [PASSED] test_reuse ====================
[17:11:47] =================== test_range_overlap ====================
[17:11:47] [PASSED] 4
[17:11:47] [PASSED] 8
[17:11:47] [PASSED] 32
[17:11:47] [PASSED] 256
[17:11:47] =============== [PASSED] test_range_overlap ================
[17:11:47] =================== test_range_compact ====================
[17:11:47] [PASSED] 4
[17:11:47] [PASSED] 8
[17:11:47] [PASSED] 32
[17:11:47] [PASSED] 256
[17:11:47] =============== [PASSED] test_range_compact ================
[17:11:47] ==================== test_range_spare =====================
[17:11:47] [PASSED] 4
[17:11:47] [PASSED] 8
[17:11:47] [PASSED] 32
[17:11:47] [PASSED] 256
[17:11:47] ================ [PASSED] test_range_spare =================
[17:11:47] ===================== [PASSED] guc_dbm =====================
[17:11:47] =================== guc_idm (6 subtests) ===================
[17:11:47] [PASSED] bad_init
[17:11:47] [PASSED] no_init
[17:11:47] [PASSED] init_fini
[17:11:47] [PASSED] check_used
[17:11:47] [PASSED] check_quota
[17:11:47] [PASSED] check_all
[17:11:47] ===================== [PASSED] guc_idm =====================
[17:11:47] ================== no_relay (3 subtests) ===================
[17:11:47] [PASSED] xe_drops_guc2pf_if_not_ready
[17:11:47] [PASSED] xe_drops_guc2vf_if_not_ready
[17:11:47] [PASSED] xe_rejects_send_if_not_ready
[17:11:47] ==================== [PASSED] no_relay =====================
[17:11:47] ================== pf_relay (14 subtests) ==================
[17:11:47] [PASSED] pf_rejects_guc2pf_too_short
[17:11:47] [PASSED] pf_rejects_guc2pf_too_long
[17:11:47] [PASSED] pf_rejects_guc2pf_no_payload
[17:11:47] [PASSED] pf_fails_no_payload
[17:11:47] [PASSED] pf_fails_bad_origin
[17:11:47] [PASSED] pf_fails_bad_type
[17:11:47] [PASSED] pf_txn_reports_error
[17:11:47] [PASSED] pf_txn_sends_pf2guc
[17:11:47] [PASSED] pf_sends_pf2guc
[17:11:47] [SKIPPED] pf_loopback_nop
[17:11:47] [SKIPPED] pf_loopback_echo
[17:11:47] [SKIPPED] pf_loopback_fail
[17:11:47] [SKIPPED] pf_loopback_busy
[17:11:47] [SKIPPED] pf_loopback_retry
[17:11:47] ==================== [PASSED] pf_relay =====================
[17:11:47] ================== vf_relay (3 subtests) ===================
[17:11:47] [PASSED] vf_rejects_guc2vf_too_short
[17:11:47] [PASSED] vf_rejects_guc2vf_too_long
[17:11:47] [PASSED] vf_rejects_guc2vf_no_payload
[17:11:47] ==================== [PASSED] vf_relay =====================
[17:11:47] ================ pf_gt_config (4 subtests) =================
[17:11:47] [PASSED] fair_contexts_1vf
[17:11:47] [PASSED] fair_doorbells_1vf
[17:11:47] ====================== fair_contexts ======================
[17:11:47] [PASSED] 1 VF
[17:11:47] [PASSED] 2 VFs
[17:11:47] [PASSED] 3 VFs
[17:11:47] [PASSED] 4 VFs
[17:11:47] [PASSED] 5 VFs
[17:11:47] [PASSED] 6 VFs
[17:11:47] [PASSED] 7 VFs
[17:11:47] [PASSED] 8 VFs
[17:11:47] [PASSED] 9 VFs
[17:11:47] [PASSED] 10 VFs
[17:11:47] [PASSED] 11 VFs
[17:11:47] [PASSED] 12 VFs
[17:11:47] [PASSED] 13 VFs
[17:11:47] [PASSED] 14 VFs
[17:11:47] [PASSED] 15 VFs
[17:11:47] [PASSED] 16 VFs
[17:11:47] [PASSED] 17 VFs
[17:11:47] [PASSED] 18 VFs
[17:11:47] [PASSED] 19 VFs
[17:11:47] [PASSED] 20 VFs
[17:11:47] [PASSED] 21 VFs
[17:11:47] [PASSED] 22 VFs
[17:11:47] [PASSED] 23 VFs
[17:11:47] [PASSED] 24 VFs
[17:11:47] [PASSED] 25 VFs
[17:11:47] [PASSED] 26 VFs
[17:11:47] [PASSED] 27 VFs
[17:11:47] [PASSED] 28 VFs
[17:11:47] [PASSED] 29 VFs
[17:11:47] [PASSED] 30 VFs
[17:11:47] [PASSED] 31 VFs
[17:11:47] [PASSED] 32 VFs
[17:11:47] [PASSED] 33 VFs
[17:11:47] [PASSED] 34 VFs
[17:11:47] [PASSED] 35 VFs
[17:11:47] [PASSED] 36 VFs
[17:11:47] [PASSED] 37 VFs
[17:11:47] [PASSED] 38 VFs
[17:11:47] [PASSED] 39 VFs
[17:11:47] [PASSED] 40 VFs
[17:11:47] [PASSED] 41 VFs
[17:11:47] [PASSED] 42 VFs
[17:11:47] [PASSED] 43 VFs
[17:11:47] [PASSED] 44 VFs
[17:11:47] [PASSED] 45 VFs
[17:11:47] [PASSED] 46 VFs
[17:11:47] [PASSED] 47 VFs
[17:11:47] [PASSED] 48 VFs
[17:11:47] [PASSED] 49 VFs
[17:11:47] [PASSED] 50 VFs
[17:11:47] [PASSED] 51 VFs
[17:11:47] [PASSED] 52 VFs
[17:11:47] [PASSED] 53 VFs
[17:11:47] [PASSED] 54 VFs
[17:11:47] [PASSED] 55 VFs
[17:11:47] [PASSED] 56 VFs
[17:11:47] [PASSED] 57 VFs
[17:11:47] [PASSED] 58 VFs
[17:11:47] [PASSED] 59 VFs
[17:11:47] [PASSED] 60 VFs
[17:11:47] [PASSED] 61 VFs
[17:11:47] [PASSED] 62 VFs
[17:11:47] [PASSED] 63 VFs
[17:11:47] ================== [PASSED] fair_contexts ==================
[17:11:47] ===================== fair_doorbells ======================
[17:11:47] [PASSED] 1 VF
[17:11:47] [PASSED] 2 VFs
[17:11:47] [PASSED] 3 VFs
[17:11:47] [PASSED] 4 VFs
[17:11:47] [PASSED] 5 VFs
[17:11:47] [PASSED] 6 VFs
[17:11:47] [PASSED] 7 VFs
[17:11:47] [PASSED] 8 VFs
[17:11:47] [PASSED] 9 VFs
[17:11:47] [PASSED] 10 VFs
[17:11:47] [PASSED] 11 VFs
[17:11:47] [PASSED] 12 VFs
[17:11:47] [PASSED] 13 VFs
[17:11:47] [PASSED] 14 VFs
[17:11:47] [PASSED] 15 VFs
[17:11:47] [PASSED] 16 VFs
[17:11:47] [PASSED] 17 VFs
[17:11:47] [PASSED] 18 VFs
[17:11:47] [PASSED] 19 VFs
[17:11:47] [PASSED] 20 VFs
[17:11:47] [PASSED] 21 VFs
[17:11:47] [PASSED] 22 VFs
[17:11:47] [PASSED] 23 VFs
[17:11:47] [PASSED] 24 VFs
[17:11:47] [PASSED] 25 VFs
[17:11:47] [PASSED] 26 VFs
[17:11:47] [PASSED] 27 VFs
[17:11:47] [PASSED] 28 VFs
[17:11:47] [PASSED] 29 VFs
[17:11:47] [PASSED] 30 VFs
[17:11:47] [PASSED] 31 VFs
[17:11:47] [PASSED] 32 VFs
[17:11:47] [PASSED] 33 VFs
[17:11:47] [PASSED] 34 VFs
[17:11:47] [PASSED] 35 VFs
[17:11:47] [PASSED] 36 VFs
[17:11:47] [PASSED] 37 VFs
[17:11:47] [PASSED] 38 VFs
[17:11:47] [PASSED] 39 VFs
[17:11:47] [PASSED] 40 VFs
[17:11:47] [PASSED] 41 VFs
[17:11:47] [PASSED] 42 VFs
[17:11:47] [PASSED] 43 VFs
[17:11:47] [PASSED] 44 VFs
[17:11:47] [PASSED] 45 VFs
[17:11:47] [PASSED] 46 VFs
[17:11:47] [PASSED] 47 VFs
[17:11:47] [PASSED] 48 VFs
[17:11:47] [PASSED] 49 VFs
[17:11:47] [PASSED] 50 VFs
[17:11:47] [PASSED] 51 VFs
[17:11:47] [PASSED] 52 VFs
[17:11:47] [PASSED] 53 VFs
[17:11:47] [PASSED] 54 VFs
[17:11:47] [PASSED] 55 VFs
[17:11:47] [PASSED] 56 VFs
[17:11:47] [PASSED] 57 VFs
[17:11:47] [PASSED] 58 VFs
[17:11:47] [PASSED] 59 VFs
[17:11:47] [PASSED] 60 VFs
[17:11:47] [PASSED] 61 VFs
[17:11:47] [PASSED] 62 VFs
[17:11:47] [PASSED] 63 VFs
[17:11:47] ================= [PASSED] fair_doorbells ==================
[17:11:47] ================== [PASSED] pf_gt_config ===================
[17:11:47] ===================== lmtt (1 subtest) =====================
[17:11:47] ======================== test_ops =========================
[17:11:47] [PASSED] 2-level
[17:11:47] [PASSED] multi-level
[17:11:47] ==================== [PASSED] test_ops =====================
[17:11:47] ====================== [PASSED] lmtt =======================
[17:11:47] ================= pf_service (11 subtests) =================
[17:11:47] [PASSED] pf_negotiate_any
[17:11:47] [PASSED] pf_negotiate_base_match
[17:11:47] [PASSED] pf_negotiate_base_newer
[17:11:47] [PASSED] pf_negotiate_base_next
[17:11:47] [SKIPPED] pf_negotiate_base_older
[17:11:47] [PASSED] pf_negotiate_base_prev
[17:11:47] [PASSED] pf_negotiate_latest_match
[17:11:47] [PASSED] pf_negotiate_latest_newer
[17:11:47] [PASSED] pf_negotiate_latest_next
[17:11:47] [SKIPPED] pf_negotiate_latest_older
[17:11:47] [SKIPPED] pf_negotiate_latest_prev
[17:11:47] =================== [PASSED] pf_service ====================
[17:11:47] ================= xe_guc_g2g (2 subtests) ==================
[17:11:47] ============== xe_live_guc_g2g_kunit_default ==============
[17:11:47] ========= [SKIPPED] xe_live_guc_g2g_kunit_default ==========
[17:11:47] ============== xe_live_guc_g2g_kunit_allmem ===============
[17:11:47] ========== [SKIPPED] xe_live_guc_g2g_kunit_allmem ==========
[17:11:47] =================== [SKIPPED] xe_guc_g2g ===================
[17:11:47] =================== xe_mocs (2 subtests) ===================
[17:11:47] ================ xe_live_mocs_kernel_kunit ================
[17:11:47] =========== [SKIPPED] xe_live_mocs_kernel_kunit ============
[17:11:47] ================ xe_live_mocs_reset_kunit =================
[17:11:47] ============ [SKIPPED] xe_live_mocs_reset_kunit ============
[17:11:47] ==================== [SKIPPED] xe_mocs =====================
[17:11:47] ================= xe_migrate (2 subtests) ==================
[17:11:47] ================= xe_migrate_sanity_kunit =================
[17:11:47] ============ [SKIPPED] xe_migrate_sanity_kunit =============
[17:11:47] ================== xe_validate_ccs_kunit ==================
[17:11:47] ============= [SKIPPED] xe_validate_ccs_kunit ==============
[17:11:47] =================== [SKIPPED] xe_migrate ===================
[17:11:47] ================== xe_dma_buf (1 subtest) ==================
[17:11:47] ==================== xe_dma_buf_kunit =====================
[17:11:47] ================ [SKIPPED] xe_dma_buf_kunit ================
[17:11:47] =================== [SKIPPED] xe_dma_buf ===================
[17:11:47] ================= xe_bo_shrink (1 subtest) =================
[17:11:47] =================== xe_bo_shrink_kunit ====================
[17:11:47] =============== [SKIPPED] xe_bo_shrink_kunit ===============
[17:11:47] ================== [SKIPPED] xe_bo_shrink ==================
[17:11:47] ==================== xe_bo (2 subtests) ====================
[17:11:47] ================== xe_ccs_migrate_kunit ===================
[17:11:47] ============== [SKIPPED] xe_ccs_migrate_kunit ==============
[17:11:47] ==================== xe_bo_evict_kunit ====================
[17:11:47] =============== [SKIPPED] xe_bo_evict_kunit ================
[17:11:47] ===================== [SKIPPED] xe_bo ======================
[17:11:47] ==================== args (11 subtests) ====================
[17:11:47] [PASSED] count_args_test
[17:11:47] [PASSED] call_args_example
[17:11:47] [PASSED] call_args_test
[17:11:47] [PASSED] drop_first_arg_example
[17:11:47] [PASSED] drop_first_arg_test
[17:11:47] [PASSED] first_arg_example
[17:11:47] [PASSED] first_arg_test
[17:11:47] [PASSED] last_arg_example
[17:11:47] [PASSED] last_arg_test
[17:11:47] [PASSED] pick_arg_example
[17:11:47] [PASSED] sep_comma_example
[17:11:47] ====================== [PASSED] args =======================
[17:11:47] =================== xe_pci (3 subtests) ====================
[17:11:47] ==================== check_graphics_ip ====================
[17:11:47] [PASSED] 12.00 Xe_LP
[17:11:47] [PASSED] 12.10 Xe_LP+
[17:11:47] [PASSED] 12.55 Xe_HPG
[17:11:47] [PASSED] 12.60 Xe_HPC
[17:11:47] [PASSED] 12.70 Xe_LPG
[17:11:47] [PASSED] 12.71 Xe_LPG
[17:11:47] [PASSED] 12.74 Xe_LPG+
[17:11:47] [PASSED] 20.01 Xe2_HPG
[17:11:47] [PASSED] 20.02 Xe2_HPG
[17:11:47] [PASSED] 20.04 Xe2_LPG
[17:11:47] [PASSED] 30.00 Xe3_LPG
[17:11:47] [PASSED] 30.01 Xe3_LPG
[17:11:47] [PASSED] 30.03 Xe3_LPG
[17:11:47] [PASSED] 30.04 Xe3_LPG
[17:11:47] [PASSED] 30.05 Xe3_LPG
[17:11:47] [PASSED] 35.11 Xe3p_XPC
[17:11:47] ================ [PASSED] check_graphics_ip ================
[17:11:47] ===================== check_media_ip ======================
[17:11:47] [PASSED] 12.00 Xe_M
[17:11:47] [PASSED] 12.55 Xe_HPM
[17:11:47] [PASSED] 13.00 Xe_LPM+
[17:11:47] [PASSED] 13.01 Xe2_HPM
[17:11:47] [PASSED] 20.00 Xe2_LPM
[17:11:47] [PASSED] 30.00 Xe3_LPM
[17:11:47] [PASSED] 30.02 Xe3_LPM
[17:11:47] [PASSED] 35.00 Xe3p_LPM
[17:11:47] [PASSED] 35.03 Xe3p_HPM
[17:11:47] ================= [PASSED] check_media_ip ==================
[17:11:47] =================== check_platform_desc ===================
[17:11:47] [PASSED] 0x9A60 (TIGERLAKE)
[17:11:47] [PASSED] 0x9A68 (TIGERLAKE)
[17:11:47] [PASSED] 0x9A70 (TIGERLAKE)
[17:11:47] [PASSED] 0x9A40 (TIGERLAKE)
[17:11:47] [PASSED] 0x9A49 (TIGERLAKE)
[17:11:47] [PASSED] 0x9A59 (TIGERLAKE)
[17:11:47] [PASSED] 0x9A78 (TIGERLAKE)
[17:11:47] [PASSED] 0x9AC0 (TIGERLAKE)
[17:11:47] [PASSED] 0x9AC9 (TIGERLAKE)
[17:11:47] [PASSED] 0x9AD9 (TIGERLAKE)
[17:11:47] [PASSED] 0x9AF8 (TIGERLAKE)
[17:11:47] [PASSED] 0x4C80 (ROCKETLAKE)
[17:11:47] [PASSED] 0x4C8A (ROCKETLAKE)
[17:11:47] [PASSED] 0x4C8B (ROCKETLAKE)
[17:11:47] [PASSED] 0x4C8C (ROCKETLAKE)
[17:11:47] [PASSED] 0x4C90 (ROCKETLAKE)
[17:11:47] [PASSED] 0x4C9A (ROCKETLAKE)
[17:11:47] [PASSED] 0x4680 (ALDERLAKE_S)
[17:11:47] [PASSED] 0x4682 (ALDERLAKE_S)
[17:11:47] [PASSED] 0x4688 (ALDERLAKE_S)
[17:11:47] [PASSED] 0x468A (ALDERLAKE_S)
[17:11:47] [PASSED] 0x468B (ALDERLAKE_S)
[17:11:47] [PASSED] 0x4690 (ALDERLAKE_S)
[17:11:47] [PASSED] 0x4692 (ALDERLAKE_S)
[17:11:47] [PASSED] 0x4693 (ALDERLAKE_S)
[17:11:47] [PASSED] 0x46A0 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46A1 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46A2 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46A3 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46A6 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46A8 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46AA (ALDERLAKE_P)
[17:11:47] [PASSED] 0x462A (ALDERLAKE_P)
[17:11:47] [PASSED] 0x4626 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x4628 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46B0 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46B1 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46B2 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46B3 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46C0 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46C1 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46C2 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46C3 (ALDERLAKE_P)
[17:11:47] [PASSED] 0x46D0 (ALDERLAKE_N)
[17:11:47] [PASSED] 0x46D1 (ALDERLAKE_N)
[17:11:47] [PASSED] 0x46D2 (ALDERLAKE_N)
[17:11:47] [PASSED] 0x46D3 (ALDERLAKE_N)
[17:11:47] [PASSED] 0x46D4 (ALDERLAKE_N)
[17:11:47] [PASSED] 0xA721 (ALDERLAKE_P)
[17:11:47] [PASSED] 0xA7A1 (ALDERLAKE_P)
[17:11:47] [PASSED] 0xA7A9 (ALDERLAKE_P)
[17:11:47] [PASSED] 0xA7AC (ALDERLAKE_P)
[17:11:47] [PASSED] 0xA7AD (ALDERLAKE_P)
[17:11:47] [PASSED] 0xA720 (ALDERLAKE_P)
[17:11:47] [PASSED] 0xA7A0 (ALDERLAKE_P)
[17:11:47] [PASSED] 0xA7A8 (ALDERLAKE_P)
[17:11:47] [PASSED] 0xA7AA (ALDERLAKE_P)
[17:11:47] [PASSED] 0xA7AB (ALDERLAKE_P)
[17:11:47] [PASSED] 0xA780 (ALDERLAKE_S)
[17:11:47] [PASSED] 0xA781 (ALDERLAKE_S)
[17:11:47] [PASSED] 0xA782 (ALDERLAKE_S)
[17:11:47] [PASSED] 0xA783 (ALDERLAKE_S)
[17:11:47] [PASSED] 0xA788 (ALDERLAKE_S)
[17:11:47] [PASSED] 0xA789 (ALDERLAKE_S)
[17:11:47] [PASSED] 0xA78A (ALDERLAKE_S)
[17:11:47] [PASSED] 0xA78B (ALDERLAKE_S)
[17:11:47] [PASSED] 0x4905 (DG1)
[17:11:47] [PASSED] 0x4906 (DG1)
[17:11:47] [PASSED] 0x4907 (DG1)
[17:11:47] [PASSED] 0x4908 (DG1)
[17:11:47] [PASSED] 0x4909 (DG1)
[17:11:47] [PASSED] 0x56C0 (DG2)
[17:11:47] [PASSED] 0x56C2 (DG2)
[17:11:47] [PASSED] 0x56C1 (DG2)
[17:11:47] [PASSED] 0x7D51 (METEORLAKE)
[17:11:47] [PASSED] 0x7DD1 (METEORLAKE)
[17:11:47] [PASSED] 0x7D41 (METEORLAKE)
[17:11:47] [PASSED] 0x7D67 (METEORLAKE)
[17:11:47] [PASSED] 0xB640 (METEORLAKE)
[17:11:47] [PASSED] 0x56A0 (DG2)
[17:11:47] [PASSED] 0x56A1 (DG2)
[17:11:47] [PASSED] 0x56A2 (DG2)
[17:11:47] [PASSED] 0x56BE (DG2)
[17:11:47] [PASSED] 0x56BF (DG2)
[17:11:47] [PASSED] 0x5690 (DG2)
stty: 'standard input': Inappropriate ioctl for device
[17:11:47] [PASSED] 0x5691 (DG2)
[17:11:47] [PASSED] 0x5692 (DG2)
[17:11:47] [PASSED] 0x56A5 (DG2)
[17:11:47] [PASSED] 0x56A6 (DG2)
[17:11:47] [PASSED] 0x56B0 (DG2)
[17:11:47] [PASSED] 0x56B1 (DG2)
[17:11:47] [PASSED] 0x56BA (DG2)
[17:11:47] [PASSED] 0x56BB (DG2)
[17:11:47] [PASSED] 0x56BC (DG2)
[17:11:47] [PASSED] 0x56BD (DG2)
[17:11:47] [PASSED] 0x5693 (DG2)
[17:11:47] [PASSED] 0x5694 (DG2)
[17:11:47] [PASSED] 0x5695 (DG2)
[17:11:47] [PASSED] 0x56A3 (DG2)
[17:11:47] [PASSED] 0x56A4 (DG2)
[17:11:47] [PASSED] 0x56B2 (DG2)
[17:11:47] [PASSED] 0x56B3 (DG2)
[17:11:47] [PASSED] 0x5696 (DG2)
[17:11:47] [PASSED] 0x5697 (DG2)
[17:11:47] [PASSED] 0xB69 (PVC)
[17:11:47] [PASSED] 0xB6E (PVC)
[17:11:47] [PASSED] 0xBD4 (PVC)
[17:11:47] [PASSED] 0xBD5 (PVC)
[17:11:47] [PASSED] 0xBD6 (PVC)
[17:11:47] [PASSED] 0xBD7 (PVC)
[17:11:47] [PASSED] 0xBD8 (PVC)
[17:11:47] [PASSED] 0xBD9 (PVC)
[17:11:47] [PASSED] 0xBDA (PVC)
[17:11:47] [PASSED] 0xBDB (PVC)
[17:11:47] [PASSED] 0xBE0 (PVC)
[17:11:47] [PASSED] 0xBE1 (PVC)
[17:11:47] [PASSED] 0xBE5 (PVC)
[17:11:47] [PASSED] 0x7D40 (METEORLAKE)
[17:11:47] [PASSED] 0x7D45 (METEORLAKE)
[17:11:47] [PASSED] 0x7D55 (METEORLAKE)
[17:11:47] [PASSED] 0x7D60 (METEORLAKE)
[17:11:47] [PASSED] 0x7DD5 (METEORLAKE)
[17:11:47] [PASSED] 0x6420 (LUNARLAKE)
[17:11:47] [PASSED] 0x64A0 (LUNARLAKE)
[17:11:47] [PASSED] 0x64B0 (LUNARLAKE)
[17:11:47] [PASSED] 0xE202 (BATTLEMAGE)
[17:11:47] [PASSED] 0xE209 (BATTLEMAGE)
[17:11:47] [PASSED] 0xE20B (BATTLEMAGE)
[17:11:47] [PASSED] 0xE20C (BATTLEMAGE)
[17:11:47] [PASSED] 0xE20D (BATTLEMAGE)
[17:11:47] [PASSED] 0xE210 (BATTLEMAGE)
[17:11:47] [PASSED] 0xE211 (BATTLEMAGE)
[17:11:47] [PASSED] 0xE212 (BATTLEMAGE)
[17:11:47] [PASSED] 0xE216 (BATTLEMAGE)
[17:11:47] [PASSED] 0xE220 (BATTLEMAGE)
[17:11:47] [PASSED] 0xE221 (BATTLEMAGE)
[17:11:47] [PASSED] 0xE222 (BATTLEMAGE)
[17:11:47] [PASSED] 0xE223 (BATTLEMAGE)
[17:11:47] [PASSED] 0xB080 (PANTHERLAKE)
[17:11:47] [PASSED] 0xB081 (PANTHERLAKE)
[17:11:47] [PASSED] 0xB082 (PANTHERLAKE)
[17:11:47] [PASSED] 0xB083 (PANTHERLAKE)
[17:11:47] [PASSED] 0xB084 (PANTHERLAKE)
[17:11:47] [PASSED] 0xB085 (PANTHERLAKE)
[17:11:47] [PASSED] 0xB086 (PANTHERLAKE)
[17:11:47] [PASSED] 0xB087 (PANTHERLAKE)
[17:11:47] [PASSED] 0xB08F (PANTHERLAKE)
[17:11:47] [PASSED] 0xB090 (PANTHERLAKE)
[17:11:47] [PASSED] 0xB0A0 (PANTHERLAKE)
[17:11:47] [PASSED] 0xB0B0 (PANTHERLAKE)
[17:11:47] [PASSED] 0xD740 (NOVALAKE_S)
[17:11:47] [PASSED] 0xD741 (NOVALAKE_S)
[17:11:47] [PASSED] 0xD742 (NOVALAKE_S)
[17:11:47] [PASSED] 0xD743 (NOVALAKE_S)
[17:11:47] [PASSED] 0xD744 (NOVALAKE_S)
[17:11:47] [PASSED] 0xD745 (NOVALAKE_S)
[17:11:47] [PASSED] 0x674C (CRESCENTISLAND)
[17:11:47] [PASSED] 0xFD80 (PANTHERLAKE)
[17:11:47] [PASSED] 0xFD81 (PANTHERLAKE)
[17:11:47] =============== [PASSED] check_platform_desc ===============
[17:11:47] ===================== [PASSED] xe_pci ======================
[17:11:47] =================== xe_rtp (2 subtests) ====================
[17:11:47] =============== xe_rtp_process_to_sr_tests ================
[17:11:47] [PASSED] coalesce-same-reg
[17:11:47] [PASSED] no-match-no-add
[17:11:47] [PASSED] match-or
[17:11:47] [PASSED] match-or-xfail
[17:11:47] [PASSED] no-match-no-add-multiple-rules
[17:11:47] [PASSED] two-regs-two-entries
[17:11:47] [PASSED] clr-one-set-other
[17:11:47] [PASSED] set-field
[17:11:47] [PASSED] conflict-duplicate
[17:11:47] [PASSED] conflict-not-disjoint
[17:11:47] [PASSED] conflict-reg-type
[17:11:47] =========== [PASSED] xe_rtp_process_to_sr_tests ============
[17:11:47] ================== xe_rtp_process_tests ===================
[17:11:47] [PASSED] active1
[17:11:47] [PASSED] active2
[17:11:47] [PASSED] active-inactive
[17:11:47] [PASSED] inactive-active
[17:11:47] [PASSED] inactive-1st_or_active-inactive
[17:11:47] [PASSED] inactive-2nd_or_active-inactive
[17:11:47] [PASSED] inactive-last_or_active-inactive
[17:11:47] [PASSED] inactive-no_or_active-inactive
[17:11:47] ============== [PASSED] xe_rtp_process_tests ===============
[17:11:47] ===================== [PASSED] xe_rtp ======================
[17:11:47] ==================== xe_wa (1 subtest) =====================
[17:11:47] ======================== xe_wa_gt =========================
[17:11:47] [PASSED] TIGERLAKE B0
[17:11:47] [PASSED] DG1 A0
[17:11:47] [PASSED] DG1 B0
[17:11:47] [PASSED] ALDERLAKE_S A0
[17:11:47] [PASSED] ALDERLAKE_S B0
[17:11:47] [PASSED] ALDERLAKE_S C0
[17:11:47] [PASSED] ALDERLAKE_S D0
[17:11:47] [PASSED] ALDERLAKE_P A0
[17:11:47] [PASSED] ALDERLAKE_P B0
[17:11:47] [PASSED] ALDERLAKE_P C0
[17:11:47] [PASSED] ALDERLAKE_S RPLS D0
[17:11:47] [PASSED] ALDERLAKE_P RPLU E0
[17:11:47] [PASSED] DG2 G10 C0
[17:11:47] [PASSED] DG2 G11 B1
[17:11:47] [PASSED] DG2 G12 A1
[17:11:47] [PASSED] METEORLAKE 12.70(Xe_LPG) A0 13.00(Xe_LPM+) A0
[17:11:47] [PASSED] METEORLAKE 12.71(Xe_LPG) A0 13.00(Xe_LPM+) A0
[17:11:47] [PASSED] METEORLAKE 12.74(Xe_LPG+) A0 13.00(Xe_LPM+) A0
[17:11:47] [PASSED] LUNARLAKE 20.04(Xe2_LPG) A0 20.00(Xe2_LPM) A0
[17:11:47] [PASSED] LUNARLAKE 20.04(Xe2_LPG) B0 20.00(Xe2_LPM) A0
[17:11:47] [PASSED] BATTLEMAGE 20.01(Xe2_HPG) A0 13.01(Xe2_HPM) A1
[17:11:47] [PASSED] PANTHERLAKE 30.00(Xe3_LPG) A0 30.00(Xe3_LPM) A0
[17:11:47] ==================== [PASSED] xe_wa_gt =====================
[17:11:47] ====================== [PASSED] xe_wa ======================
[17:11:47] ============================================================
[17:11:47] Testing complete. Ran 446 tests: passed: 428, skipped: 18
[17:11:47] Elapsed time: 35.361s total, 4.290s configuring, 30.604s building, 0.418s running
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/tests/.kunitconfig
stty: 'standard input': Inappropriate ioctl for device
[17:11:47] Configuring KUnit Kernel ...
Regenerating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[17:11:49] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=48
[17:12:14] Starting KUnit Kernel (1/1)...
[17:12:14] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[17:12:14] ============ drm_test_pick_cmdline (2 subtests) ============
[17:12:14] [PASSED] drm_test_pick_cmdline_res_1920_1080_60
[17:12:14] =============== drm_test_pick_cmdline_named ===============
[17:12:14] [PASSED] NTSC
[17:12:14] [PASSED] NTSC-J
[17:12:14] [PASSED] PAL
[17:12:14] [PASSED] PAL-M
[17:12:14] =========== [PASSED] drm_test_pick_cmdline_named ===========
[17:12:14] ============== [PASSED] drm_test_pick_cmdline ==============
[17:12:14] == drm_test_atomic_get_connector_for_encoder (1 subtest) ===
[17:12:14] [ERROR] Test: drm_test_atomic_get_connector_for_encoder: missing expected subtest!
[17:12:14] ------------[ cut here ]------------
[17:12:14] WARNING: CPU: 0 PID: 28 at drivers/gpu/drm/drm_vblank.c:193 drm_crtc_vblank_crtc+0x94/0xa0
[17:12:14] drm-kunit-mock-device drm_test_drm_atomic_get_connector_for_encoder.drm-kunit-mock-device: [drm] drm_WARN_ON(!vblank)
[17:12:14] CPU: 0 UID: 0 PID: 28 Comm: kunit_try_catch Tainted: G W N 6.18.0-rc5-g82292f137e2d #2 NONE
[17:12:14] Tainted: [W]=WARN, [N]=TEST
[17:12:14] Stack:
[17:12:14] 604c25af 00000000 00000000 00000001
[17:12:14] ffffff00 604c25af 602da8d4 00000009
[17:12:14] 000000c1 60046f7a 600237bb ad38bc20
[17:12:14] Call Trace:
[17:12:14] [<602da8d4>] ? drm_crtc_vblank_crtc+0x94/0xa0
[17:12:14] [<60046f7a>] ? dump_stack_lvl+0x5b/0x77
[17:12:14] [<600237bb>] ? _printk+0x0/0x65
[17:12:14] [<6001f07a>] ? __warn.cold+0x71/0x10b
[17:12:14] [<6001f1a8>] ? warn_slowpath_fmt+0x94/0xa1
[17:12:14] [<602a2ad0>] ? drm_atomic_get_connector_state+0x0/0x2f0
[17:12:14] [<60055bf9>] ? um_set_signals+0x59/0x70
[17:12:14] [<602d3e50>] ? __drm_dev_dbg+0x0/0xb0
[17:12:14] [<602da8d4>] ? drm_crtc_vblank_crtc+0x94/0xa0
[17:12:14] [<602da892>] ? drm_crtc_vblank_crtc+0x52/0xa0
[17:12:14] [<602dab07>] ? drm_calc_timestamping_constants+0x27/0x170
[17:12:14] [<60055ba0>] ? um_set_signals+0x0/0x70
[17:12:14] [<602daae0>] ? drm_calc_timestamping_constants+0x0/0x170
[17:12:14] [<602d3e50>] ? __drm_dev_dbg+0x0/0xb0
[17:12:14] [<602eb0fc>] ? drm_atomic_helper_calc_timestamping_constants+0x6c/0x90
[17:12:14] [<602ee25c>] ? drm_atomic_helper_commit_modeset_disables+0x43c/0x7f0
[17:12:14] [<600ced10>] ? ktime_get+0x0/0x150
[17:12:14] [<602ce6f0>] ? drm_modeset_backoff+0x0/0x1d0
[17:12:14] [<602eef23>] ? drm_atomic_helper_commit_tail+0x23/0xa0
[17:12:14] [<602f0164>] ? commit_tail+0xf4/0x180
[17:12:14] [<602ff510>] ? drm_kunit_helper_enable_crtc_connector+0x0/0x140
[17:12:14] [<602f039f>] ? drm_atomic_helper_commit+0x18f/0x1d0
[17:12:14] [<602a4af9>] ? drm_atomic_commit+0xb9/0xe0
[17:12:14] [<6003db45>] ? __drm_printfn_info+0x0/0x23
[17:12:14] [<602ff870>] ? drm_test_drm_atomic_get_connector_for_encoder+0x220/0x590
[17:12:14] [<6008b2c6>] ? finish_task_switch.isra.0+0x76/0x1b0
[17:12:14] [<600cf290>] ? ktime_get_ts64+0x0/0x1a0
[17:12:14] [<60082650>] ? to_kthread+0x0/0x40
[17:12:14] [<60252ecf>] ? kunit_try_run_case+0x7f/0x100
[17:12:14] [<60082650>] ? to_kthread+0x0/0x40
[17:12:14] [<60255220>] ? kunit_generic_run_threadfn_adapter+0x0/0x30
[17:12:14] [<60255236>] ? kunit_generic_run_threadfn_adapter+0x16/0x30
[17:12:14] [<60083035>] ? kthread+0xf5/0x270
[17:12:14] [<60049595>] ? new_thread_handler+0x45/0x60
[17:12:14] ---[ end trace 0000000000000000 ]---
[17:12:14] ------------[ cut here ]------------
[17:12:14] WARNING: CPU: 0 PID: 28 at drivers/gpu/drm/drm_vblank.c:193 drm_crtc_vblank_crtc+0x94/0xa0
[17:12:14] drm-kunit-mock-device drm_test_drm_atomic_get_connector_for_encoder.drm-kunit-mock-device: [drm] drm_WARN_ON(!vblank)
[17:12:14] CPU: 0 UID: 0 PID: 28 Comm: kunit_try_catch Tainted: G W N 6.18.0-rc5-g82292f137e2d #2 NONE
[17:12:14] Tainted: [W]=WARN, [N]=TEST
[17:12:14] Stack:
[17:12:14] 604c25af 00000000 00000000 00000000
[17:12:14] ffffff00 604c25af 602da8d4 00000009
[17:12:14] 000000c1 60046f7a 600237bb ad38bc90
[17:12:14] Call Trace:
[17:12:14] [<602da8d4>] ? drm_crtc_vblank_crtc+0x94/0xa0
[17:12:14] [<60046f7a>] ? dump_stack_lvl+0x5b/0x77
[17:12:14] [<600237bb>] ? _printk+0x0/0x65
[17:12:14] [<6001f07a>] ? __warn.cold+0x71/0x10b
[17:12:14] [<6001f1a8>] ? warn_slowpath_fmt+0x94/0xa1
[17:12:14] [<602dab07>] ? drm_calc_timestamping_constants+0x27/0x170
[17:12:14] [<60055ba0>] ? um_set_signals+0x0/0x70
[17:12:14] [<602da8d4>] ? drm_crtc_vblank_crtc+0x94/0xa0
[17:12:14] [<602da892>] ? drm_crtc_vblank_crtc+0x52/0xa0
[17:12:14] [<602dad7a>] ? drm_crtc_send_vblank_event+0x1a/0x80
[17:12:14] [<60055ba0>] ? um_set_signals+0x0/0x70
[17:12:14] [<602eb74c>] ? drm_atomic_helper_fake_vblank+0x8c/0xd0
[17:12:14] [<600ced10>] ? ktime_get+0x0/0x150
[17:12:14] [<602ce6f0>] ? drm_modeset_backoff+0x0/0x1d0
[17:12:14] [<602eef58>] ? drm_atomic_helper_commit_tail+0x58/0xa0
[17:12:14] [<602f0164>] ? commit_tail+0xf4/0x180
[17:12:14] [<602ff510>] ? drm_kunit_helper_enable_crtc_connector+0x0/0x140
[17:12:14] [<602f039f>] ? drm_atomic_helper_commit+0x18f/0x1d0
[17:12:14] [<602a4af9>] ? drm_atomic_commit+0xb9/0xe0
[17:12:14] [<6003db45>] ? __drm_printfn_info+0x0/0x23
[17:12:14] [<602ff870>] ? drm_test_drm_atomic_get_connector_for_encoder+0x220/0x590
[17:12:14] [<6008b2c6>] ? finish_task_switch.isra.0+0x76/0x1b0
[17:12:14] [<600cf290>] ? ktime_get_ts64+0x0/0x1a0
[17:12:14] [<60082650>] ? to_kthread+0x0/0x40
[17:12:14] [<60252ecf>] ? kunit_try_run_case+0x7f/0x100
[17:12:14] [<60082650>] ? to_kthread+0x0/0x40
[17:12:14] [<60255220>] ? kunit_generic_run_threadfn_adapter+0x0/0x30
[17:12:14] [<60255236>] ? kunit_generic_run_threadfn_adapter+0x16/0x30
[17:12:14] [<60083035>] ? kthread+0xf5/0x270
[17:12:14] [<60049595>] ? new_thread_handler+0x45/0x60
[17:12:14] ---[ end trace 0000000000000000 ]---
[17:12:14]
[17:12:14] Pid: 28, comm: kunit_try_catch Tainted: G W N 6.18.0-rc5-g82292f137e2d
[17:12:14] RIP: 0033:drm_crtc_send_vblank_event+0x3f/0x80
[17:12:14] RSP: 00000000ad38bd30 EFLAGS: 00010246
[17:12:14] RAX: 0000000006041f80 RBX: 0000000000000000 RCX: 0000000006041f80
[17:12:14] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
[17:12:14] RBP: 000000006daecd80 R08: 0000000000000000 R09: 0000000000000000
[17:12:14] R10: 0000000000000000 R11: 0000000000000000 R12: 000000006da48000
[17:12:14] R13: 000000006daece00 R14: 000000006d880828 R15: 0000000000000001
[17:12:14] Kernel panic - not syncing: Segfault with no mm
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: drm_test_atomic_get_connector_for_encoder: missing subtest result line!
[17:12:14] # module: drm_atomic_test
[17:12:14] === [CRASHED] drm_test_atomic_get_connector_for_encoder ====
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] [ERROR] Test: main: missing expected subtest!
[17:12:14] [CRASHED]
[17:12:14] ============================================================
[17:12:14] Testing complete. Ran 40 tests: passed: 5, crashed: 35, errors: 36
The kernel seems to have crashed; you can decode the stack traces with:
$ scripts/decode_stacktrace.sh .kunit/vmlinux .kunit < .kunit/test.log | tee .kunit/decoded.log | /kernel/tools/testing/kunit/kunit.py parse
[17:12:14] Elapsed time: 26.922s total, 1.711s configuring, 24.942s building, 0.269s running
+ cleanup
++ stat -c %u:%g /kernel
+ chown -R 1003:1003 /kernel
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 23/24] drm/vblank: reduce pipe checks
2025-11-10 16:17 ` [PATCH 23/24] drm/vblank: reduce pipe checks Jani Nikula
@ 2025-11-10 17:45 ` Ville Syrjälä
2025-11-11 8:56 ` Jani Nikula
2025-11-12 16:54 ` Thomas Zimmermann
1 sibling, 1 reply; 59+ messages in thread
From: Ville Syrjälä @ 2025-11-10 17:45 UTC (permalink / raw)
To: Jani Nikula; +Cc: dri-devel, intel-gfx, intel-xe, Thomas Zimmermann
On Mon, Nov 10, 2025 at 06:17:41PM +0200, Jani Nikula wrote:
> Now that drm_vblank_crtc() is the only place that indexes dev->vblank[],
> and its usage has reduced considerably, add the primary pipe
> out-of-bounds check there, and return NULL. Expect callers to check it
> and act accordingly.
>
> In drm_crtc_vblank_crtc(), warn and return NULL, and let it go boom. If
> the crtc->pipe is out of bounds, it's a driver error that needs to be
> fixed.
>
> Remove superfluous pipe checks all around.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
> drivers/gpu/drm/drm_vblank.c | 36 +++++++++++++++---------------------
> 1 file changed, 15 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 44fb8d225485..7829e64e42b4 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -177,13 +177,22 @@ MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
> static struct drm_vblank_crtc *
> drm_vblank_crtc(struct drm_device *dev, unsigned int pipe)
> {
> + if (pipe >= dev->num_crtcs)
> + return NULL;
> +
> return &dev->vblank[pipe];
> }
>
> struct drm_vblank_crtc *
> drm_crtc_vblank_crtc(struct drm_crtc *crtc)
> {
> - return drm_vblank_crtc(crtc->dev, drm_crtc_index(crtc));
> + struct drm_vblank_crtc *vblank;
> +
> + vblank = drm_vblank_crtc(crtc->dev, drm_crtc_index(crtc));
> + if (drm_WARN_ON(crtc->dev, !vblank))
> + return NULL;
> +
> + return vblank;
> }
> EXPORT_SYMBOL(drm_crtc_vblank_crtc);
>
> @@ -631,7 +640,6 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
> const struct drm_display_mode *mode)
> {
> struct drm_device *dev = crtc->dev;
> - unsigned int pipe = drm_crtc_index(crtc);
> struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
> int linedur_ns = 0, framedur_ns = 0;
> int dotclock = mode->crtc_clock;
> @@ -639,9 +647,6 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
> if (!drm_dev_has_vblank(dev))
> return;
I belive this at least gets called from the atomic helpers even
for drivers that don't have vblank support. In which case the
drm_crtc_vblank_crtc() call would have to be done after the
drm_dev_has_vblank() check or else you'll get spurious WARNs.
I don't remember if there are other cases like this as well.
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return;
> -
> /* Valid dotclock? */
> if (dotclock > 0) {
> int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
> @@ -724,11 +729,6 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
> int vpos, hpos, i;
> int delta_ns, duration_ns;
>
> - if (pipe >= dev->num_crtcs) {
> - drm_err(dev, "Invalid crtc %u\n", pipe);
> - return false;
> - }
> -
> /* Scanout position query not supported? Should not happen. */
> if (!get_scanout_position) {
> drm_err(dev, "Called from CRTC w/o get_scanout_position()!?\n");
> @@ -1339,9 +1339,6 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
> ktime_t now;
> u64 seq;
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return;
> -
> /*
> * Grab event_lock early to prevent vblank work from being scheduled
> * while we're in the middle of shutting down vblank interrupts
> @@ -1480,9 +1477,6 @@ void drm_crtc_vblank_on_config(struct drm_crtc *crtc,
> unsigned int pipe = drm_crtc_index(crtc);
> struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return;
> -
> spin_lock_irq(&dev->vbl_lock);
> drm_dbg_vbl(dev, "crtc %d, vblank enabled %d, inmodeset %d\n",
> pipe, vblank->enabled, vblank->inmodeset);
> @@ -1764,10 +1758,9 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> pipe = pipe_index;
> }
>
> - if (pipe >= dev->num_crtcs)
> - return -EINVAL;
> -
> vblank = drm_vblank_crtc(dev, pipe);
> + if (!vblank)
> + return -EINVAL;
>
> /* If the counter is currently enabled and accurate, short-circuit
> * queries to return the cached timestamp of the last vblank.
> @@ -1902,14 +1895,15 @@ static void drm_handle_vblank_events(struct drm_vblank_crtc *vblank)
> */
> bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
> {
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> + struct drm_vblank_crtc *vblank;
> unsigned long irqflags;
> bool disable_irq;
>
> if (drm_WARN_ON_ONCE(dev, !drm_dev_has_vblank(dev)))
> return false;
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> + vblank = drm_vblank_crtc(dev, pipe);
> + if (drm_WARN_ON(dev, !vblank))
> return false;
>
> spin_lock_irqsave(&dev->event_lock, irqflags);
> --
> 2.47.3
--
Ville Syrjälä
Intel
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 13/24] drm/vblank: pass vblank to drm_vblank_count_and_time()
2025-11-10 16:17 ` [PATCH 13/24] drm/vblank: pass vblank to drm_vblank_count_and_time() Jani Nikula
@ 2025-11-11 6:52 ` kernel test robot
2025-11-12 16:03 ` Thomas Zimmermann
1 sibling, 0 replies; 59+ messages in thread
From: kernel test robot @ 2025-11-11 6:52 UTC (permalink / raw)
To: Jani Nikula, dri-devel
Cc: oe-kbuild-all, intel-gfx, intel-xe, jani.nikula, ville.syrjala,
Thomas Zimmermann
Hi Jani,
kernel test robot noticed the following build warnings:
[auto build test WARNING on next-20251110]
[cannot apply to drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip drm-misc/drm-misc-next linus/master v6.18-rc5 v6.18-rc4 v6.18-rc3 v6.18-rc5]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Jani-Nikula/drm-vblank-Unexport-drm_wait_one_vblank/20251111-024823
base: next-20251110
patch link: https://lore.kernel.org/r/39a203dcc71aa4bfcf349d9c85672a6b9db4201f.1762791343.git.jani.nikula%40intel.com
patch subject: [PATCH 13/24] drm/vblank: pass vblank to drm_vblank_count_and_time()
config: openrisc-randconfig-r071-20251111 (https://download.01.org/0day-ci/archive/20251111/202511111453.UaceJIMy-lkp@intel.com/config)
compiler: or1k-linux-gcc (GCC) 9.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251111/202511111453.UaceJIMy-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202511111453.UaceJIMy-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> Warning: drivers/gpu/drm/drm_vblank.c:954 function parameter 'vblank' not described in 'drm_vblank_count_and_time'
>> Warning: drivers/gpu/drm/drm_vblank.c:954 function parameter 'vblank' not described in 'drm_vblank_count_and_time'
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 01/24] drm/vblank: Unexport drm_wait_one_vblank()
2025-11-10 16:17 ` [PATCH 01/24] drm/vblank: Unexport drm_wait_one_vblank() Jani Nikula
@ 2025-11-11 8:14 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-11 8:14 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> From: Thomas Zimmermann <tzimmermann@suse.de>
>
> Make drm_wait_on_vblank() static. The function is an internal interface
> and not invoked directly by drivers.
I forgot about that patch. Thanks for picking it up.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
> drivers/gpu/drm/drm_vblank.c | 14 +-------------
> include/drm/drm_vblank.h | 1 -
> 2 files changed, 1 insertion(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 32d013c5c8fc..c15d6d9d0082 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -1286,18 +1286,7 @@ void drm_crtc_vblank_put(struct drm_crtc *crtc)
> }
> EXPORT_SYMBOL(drm_crtc_vblank_put);
>
> -/**
> - * drm_wait_one_vblank - wait for one vblank
> - * @dev: DRM device
> - * @pipe: CRTC index
> - *
> - * This waits for one vblank to pass on @pipe, using the irq driver interfaces.
> - * It is a failure to call this when the vblank irq for @pipe is disabled, e.g.
> - * due to lack of driver support or because the crtc is off.
> - *
> - * This is the legacy version of drm_crtc_wait_one_vblank().
> - */
> -void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
> +static void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
> {
> struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> int ret;
> @@ -1321,7 +1310,6 @@ void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
>
> drm_vblank_put(dev, pipe);
> }
> -EXPORT_SYMBOL(drm_wait_one_vblank);
>
> /**
> * drm_crtc_wait_one_vblank - wait for one vblank
> diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
> index ffa564d79638..94ee09b48895 100644
> --- a/include/drm/drm_vblank.h
> +++ b/include/drm/drm_vblank.h
> @@ -302,7 +302,6 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe);
> bool drm_crtc_handle_vblank(struct drm_crtc *crtc);
> int drm_crtc_vblank_get(struct drm_crtc *crtc);
> void drm_crtc_vblank_put(struct drm_crtc *crtc);
> -void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe);
> void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
> void drm_crtc_vblank_off(struct drm_crtc *crtc);
> void drm_crtc_vblank_reset(struct drm_crtc *crtc);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 02/24] drm/vblank: remove drm_wait_one_vblank() completely
2025-11-10 16:17 ` [PATCH 02/24] drm/vblank: remove drm_wait_one_vblank() completely Jani Nikula
@ 2025-11-11 8:17 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-11 8:17 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> There's really no need for the extra static function at all.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_vblank.c | 25 +++++++++++--------------
> 1 file changed, 11 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index c15d6d9d0082..1d12836e3d80 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -1286,8 +1286,18 @@ void drm_crtc_vblank_put(struct drm_crtc *crtc)
> }
> EXPORT_SYMBOL(drm_crtc_vblank_put);
>
> -static void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
> +/**
> + * drm_crtc_wait_one_vblank - wait for one vblank
> + * @crtc: DRM crtc
> + *
> + * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
> + * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
> + * due to lack of driver support or because the crtc is off.
> + */
> +void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
> {
> + struct drm_device *dev = crtc->dev;
> + int pipe = drm_crtc_index(crtc);
> struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> int ret;
> u64 last;
> @@ -1310,19 +1320,6 @@ static void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
>
> drm_vblank_put(dev, pipe);
> }
> -
> -/**
> - * drm_crtc_wait_one_vblank - wait for one vblank
> - * @crtc: DRM crtc
> - *
> - * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
> - * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
> - * due to lack of driver support or because the crtc is off.
> - */
> -void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
> -{
> - drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc));
> -}
> EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
>
> /**
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 03/24] drm/vblank: remove superfluous pipe check
2025-11-10 16:17 ` [PATCH 03/24] drm/vblank: remove superfluous pipe check Jani Nikula
@ 2025-11-11 8:18 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-11 8:18 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Now that the pipe is crtc->pipe, there's no need to check it's within
> range.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_vblank.c | 3 ---
> 1 file changed, 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 1d12836e3d80..f4d1fe182a4d 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -1302,9 +1302,6 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
> int ret;
> u64 last;
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return;
> -
> ret = drm_vblank_get(dev, pipe);
> if (drm_WARN(dev, ret, "vblank not available on crtc %i, ret=%i\n",
> pipe, ret))
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 05/24] drm/vblank: use the drm_vblank_crtc() and drm_crtc_vblank_crtc() helpers more
2025-11-10 16:17 ` [PATCH 05/24] drm/vblank: use the drm_vblank_crtc() and drm_crtc_vblank_crtc() helpers more Jani Nikula
@ 2025-11-11 8:23 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-11 8:23 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> We have the helpers to avoid open coding dev->vblank[pipe] access.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_vblank.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 503eb23d38d2..e3a5a783686f 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -551,7 +551,7 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs)
> dev->num_crtcs = num_crtcs;
>
> for (i = 0; i < num_crtcs; i++) {
> - struct drm_vblank_crtc *vblank = &dev->vblank[i];
> + struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, i);
>
> vblank->dev = dev;
> vblank->pipe = i;
> @@ -605,7 +605,9 @@ EXPORT_SYMBOL(drm_dev_has_vblank);
> */
> wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc)
> {
> - return &crtc->dev->vblank[drm_crtc_index(crtc)].queue;
> + struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
> +
> + return &vblank->queue;
> }
> EXPORT_SYMBOL(drm_crtc_vblank_waitqueue);
>
> @@ -710,7 +712,7 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
> {
> struct drm_device *dev = crtc->dev;
> unsigned int pipe = crtc->index;
> - struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
> + struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> struct timespec64 ts_etime, ts_vblank_time;
> ktime_t stime, etime;
> bool vbl_status;
> @@ -1782,7 +1784,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> if (pipe >= dev->num_crtcs)
> return -EINVAL;
>
> - vblank = &dev->vblank[pipe];
> + vblank = drm_vblank_crtc(dev, pipe);
>
> /* If the counter is currently enabled and accurate, short-circuit
> * queries to return the cached timestamp of the last vblank.
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 06/24] drm/vblank: prefer drm_crtc_vblank_crtc() over drm_vblank_crtc()
2025-11-10 16:17 ` [PATCH 06/24] drm/vblank: prefer drm_crtc_vblank_crtc() over drm_vblank_crtc() Jani Nikula
@ 2025-11-11 8:26 ` Thomas Zimmermann
2025-11-11 8:43 ` Jani Nikula
0 siblings, 1 reply; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-11 8:26 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the higher level function where crtc is available.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Is there a long-term plan to replace drm_vblank_crtc() entirely?
Otherwise this looks a bit pointless.
> ---
> drivers/gpu/drm/drm_vblank.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index e3a5a783686f..96dbff63f52d 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -712,7 +712,7 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
> {
> struct drm_device *dev = crtc->dev;
> unsigned int pipe = crtc->index;
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> + struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
> struct timespec64 ts_etime, ts_vblank_time;
> ktime_t stime, etime;
> bool vbl_status;
> @@ -1302,7 +1302,7 @@ int drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
> {
> struct drm_device *dev = crtc->dev;
> int pipe = drm_crtc_index(crtc);
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> + struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
> int ret;
> u64 last;
>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 07/24] drm/vblank: pass vlank to drm_vblank_get()/_put()/_count()
2025-11-10 16:17 ` [PATCH 07/24] drm/vblank: pass vlank to drm_vblank_get()/_put()/_count() Jani Nikula
@ 2025-11-11 8:32 ` Thomas Zimmermann
2025-11-11 8:53 ` Jani Nikula
0 siblings, 1 reply; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-11 8:32 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
s/vlank/vblank in the commit headline
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Pass struct drm_vblank_crtc * to drm_vblank_get(), drm_vblank_put(), and
> drm_vblank_count(). They'll figure out the vblank pointer as the first
> thing anyway, so it's handy to pass it when available. We can also rely
> on vblank having a valid pipe, and can reduce the number of checks we
> do.
I do agree that drm_vblank_crtc should be out go-to structure for these
interfaces with wrappers around that do the lookup if necessary.
>
> Add underscore prefixed helpers for using dev/pipe until we've converted
> all users to pass in the vblank. Directly convert the call sites that
> already have the vblank pointer available.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
> drivers/gpu/drm/drm_internal.h | 6 +--
> drivers/gpu/drm/drm_vblank.c | 77 ++++++++++++++++++-------------
> drivers/gpu/drm/drm_vblank_work.c | 12 ++---
> 3 files changed, 55 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index 5a3bed48ab1f..e9c85c3681f1 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -101,9 +101,9 @@ static inline bool drm_vblank_passed(u64 seq, u64 ref)
> }
>
> void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
> -int drm_vblank_get(struct drm_device *dev, unsigned int pipe);
> -void drm_vblank_put(struct drm_device *dev, unsigned int pipe);
> -u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe);
> +int drm_vblank_get(struct drm_vblank_crtc *vblank);
> +void drm_vblank_put(struct drm_vblank_crtc *vblank);
> +u64 drm_vblank_count(struct drm_vblank_crtc *vblank);
Why no call these helpers drm_vblank_crtc_<func>() ? That would avoid
the underscored helper and have clear naming guidelines for later such
functions.
>
> /* drm_vblank_work.c */
> static inline void drm_vblank_flush_worker(struct drm_vblank_crtc *vblank)
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 96dbff63f52d..0ae34f848660 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -384,14 +384,10 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
> store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
> }
>
> -u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
> +u64 drm_vblank_count(struct drm_vblank_crtc *vblank)
> {
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> u64 count;
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return 0;
> -
> count = atomic64_read(&vblank->count);
>
> /*
> @@ -406,6 +402,14 @@ u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
> return count;
> }
>
> +static u64 _drm_vblank_count(struct drm_device *dev, unsigned int pipe)
> +{
> + if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> + return 0;
> +
> + return drm_vblank_count(drm_vblank_crtc(dev, pipe));
> +}
> +
> /**
> * drm_crtc_accurate_vblank_count - retrieve the master vblank counter
> * @crtc: which counter to retrieve
> @@ -431,7 +435,7 @@ u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
> spin_lock_irqsave(&dev->vblank_time_lock, flags);
>
> drm_update_vblank_count(dev, pipe, false);
> - vblank = drm_vblank_count(dev, pipe);
> + vblank = _drm_vblank_count(dev, pipe);
>
> spin_unlock_irqrestore(&dev->vblank_time_lock, flags);
>
> @@ -935,7 +939,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
> */
> u64 drm_crtc_vblank_count(struct drm_crtc *crtc)
> {
> - return drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
> + return _drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
> }
> EXPORT_SYMBOL(drm_crtc_vblank_count);
>
> @@ -1208,18 +1212,16 @@ static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
> return ret;
> }
>
> -int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
> +int drm_vblank_get(struct drm_vblank_crtc *vblank)
> {
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> + struct drm_device *dev = vblank->dev;
> + int pipe = vblank->pipe;
> unsigned long irqflags;
> int ret = 0;
>
> if (!drm_dev_has_vblank(dev))
> return -EINVAL;
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return -EINVAL;
> -
> spin_lock_irqsave(&dev->vbl_lock, irqflags);
> /* Going from 0->1 means we have to enable interrupts again */
> if (atomic_add_return(1, &vblank->refcount) == 1) {
> @@ -1235,6 +1237,14 @@ int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
> return ret;
> }
>
> +static int _drm_vblank_get(struct drm_device *dev, unsigned int pipe)
> +{
> + if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> + return -EINVAL;
> +
> + return drm_vblank_get(drm_vblank_crtc(dev, pipe));
> +}
> +
> /**
> * drm_crtc_vblank_get - get a reference count on vblank events
> * @crtc: which CRTC to own
> @@ -1247,18 +1257,15 @@ int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
> */
> int drm_crtc_vblank_get(struct drm_crtc *crtc)
> {
> - return drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
> + return _drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
> }
> EXPORT_SYMBOL(drm_crtc_vblank_get);
>
> -void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
> +void drm_vblank_put(struct drm_vblank_crtc *vblank)
> {
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> + struct drm_device *dev = vblank->dev;
> int vblank_offdelay = vblank->config.offdelay_ms;
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return;
> -
> if (drm_WARN_ON(dev, atomic_read(&vblank->refcount) == 0))
> return;
>
> @@ -1274,6 +1281,14 @@ void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
> }
> }
>
> +static void _drm_vblank_put(struct drm_device *dev, unsigned int pipe)
> +{
> + if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> + return;
> +
> + drm_vblank_put(drm_vblank_crtc(dev, pipe));
> +}
> +
> /**
> * drm_crtc_vblank_put - give up ownership of vblank events
> * @crtc: which counter to give up
> @@ -1284,7 +1299,7 @@ void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
> */
> void drm_crtc_vblank_put(struct drm_crtc *crtc)
> {
> - drm_vblank_put(crtc->dev, drm_crtc_index(crtc));
> + _drm_vblank_put(crtc->dev, drm_crtc_index(crtc));
> }
> EXPORT_SYMBOL(drm_crtc_vblank_put);
>
> @@ -1306,20 +1321,20 @@ int drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
> int ret;
> u64 last;
>
> - ret = drm_vblank_get(dev, pipe);
> + ret = drm_vblank_get(vblank);
> if (drm_WARN(dev, ret, "vblank not available on crtc %i, ret=%i\n",
> pipe, ret))
> return ret;
>
> - last = drm_vblank_count(dev, pipe);
> + last = drm_vblank_count(vblank);
>
> ret = wait_event_timeout(vblank->queue,
> - last != drm_vblank_count(dev, pipe),
> + last != drm_vblank_count(vblank),
> msecs_to_jiffies(1000));
>
> drm_WARN(dev, ret == 0, "vblank wait timed out on crtc %i\n", pipe);
>
> - drm_vblank_put(dev, pipe);
> + drm_vblank_put(vblank);
>
> return ret ? 0 : -ETIMEDOUT;
> }
> @@ -1385,7 +1400,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
> "wanted %llu, current %llu\n",
> e->sequence, seq);
> list_del(&e->base.link);
> - drm_vblank_put(dev, pipe);
> + _drm_vblank_put(dev, pipe);
> send_vblank_event(dev, e, seq, now);
> }
>
> @@ -1661,7 +1676,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
>
> e->sequence = req_seq;
> if (drm_vblank_passed(seq, req_seq)) {
> - drm_vblank_put(dev, pipe);
> + _drm_vblank_put(dev, pipe);
> send_vblank_event(dev, e, seq, now);
> vblwait->reply.sequence = seq;
> } else {
> @@ -1678,7 +1693,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
> spin_unlock_irq(&dev->event_lock);
> kfree(e);
> err_put:
> - drm_vblank_put(dev, pipe);
> + _drm_vblank_put(dev, pipe);
> return ret;
> }
>
> @@ -1796,14 +1811,14 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> return 0;
> }
>
> - ret = drm_vblank_get(dev, pipe);
> + ret = _drm_vblank_get(dev, pipe);
> if (ret) {
> drm_dbg_core(dev,
> "crtc %d failed to acquire vblank counter, %d\n",
> pipe, ret);
> return ret;
> }
> - seq = drm_vblank_count(dev, pipe);
> + seq = _drm_vblank_count(dev, pipe);
>
> switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
> case _DRM_VBLANK_RELATIVE:
> @@ -1839,7 +1854,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> drm_dbg_core(dev, "waiting on vblank count %llu, crtc %u\n",
> req_seq, pipe);
> wait = wait_event_interruptible_timeout(vblank->queue,
> - drm_vblank_passed(drm_vblank_count(dev, pipe), req_seq) ||
> + drm_vblank_passed(_drm_vblank_count(dev, pipe), req_seq) ||
> !READ_ONCE(vblank->enabled),
> msecs_to_jiffies(3000));
>
> @@ -1869,7 +1884,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> }
>
> done:
> - drm_vblank_put(dev, pipe);
> + _drm_vblank_put(dev, pipe);
> return ret;
> }
>
> @@ -1895,7 +1910,7 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe)
> e->sequence, seq);
>
> list_del(&e->base.link);
> - drm_vblank_put(dev, pipe);
> + _drm_vblank_put(dev, pipe);
> send_vblank_event(dev, e, seq, now);
> }
>
> diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c
> index 70f0199251ea..2ef006626d50 100644
> --- a/drivers/gpu/drm/drm_vblank_work.c
> +++ b/drivers/gpu/drm/drm_vblank_work.c
> @@ -58,7 +58,7 @@ void drm_handle_vblank_works(struct drm_vblank_crtc *vblank)
> continue;
>
> list_del_init(&work->node);
> - drm_vblank_put(vblank->dev, vblank->pipe);
> + drm_vblank_put(vblank);
> kthread_queue_work(vblank->worker, &work->base);
> wake = true;
> }
> @@ -80,7 +80,7 @@ void drm_vblank_cancel_pending_works(struct drm_vblank_crtc *vblank)
>
> list_for_each_entry_safe(work, next, &vblank->pending_work, node) {
> list_del_init(&work->node);
> - drm_vblank_put(vblank->dev, vblank->pipe);
> + drm_vblank_put(vblank);
> }
>
> wake_up_all(&vblank->work_wait_queue);
> @@ -129,7 +129,7 @@ int drm_vblank_work_schedule(struct drm_vblank_work *work,
> goto out;
>
> if (list_empty(&work->node)) {
> - ret = drm_vblank_get(dev, vblank->pipe);
> + ret = drm_vblank_get(vblank);
> if (ret < 0)
> goto out;
> } else if (work->count == count) {
> @@ -140,7 +140,7 @@ int drm_vblank_work_schedule(struct drm_vblank_work *work,
> }
>
> work->count = count;
> - cur_vbl = drm_vblank_count(dev, vblank->pipe);
> + cur_vbl = drm_vblank_count(vblank);
> passed = drm_vblank_passed(cur_vbl, count);
> if (passed)
> drm_dbg_core(dev,
> @@ -148,7 +148,7 @@ int drm_vblank_work_schedule(struct drm_vblank_work *work,
> vblank->pipe, count, cur_vbl);
>
> if (!nextonmiss && passed) {
> - drm_vblank_put(dev, vblank->pipe);
> + drm_vblank_put(vblank);
> ret = kthread_queue_work(vblank->worker, &work->base);
>
> if (rescheduling) {
> @@ -193,7 +193,7 @@ bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work)
> spin_lock_irq(&dev->event_lock);
> if (!list_empty(&work->node)) {
> list_del_init(&work->node);
> - drm_vblank_put(vblank->dev, vblank->pipe);
> + drm_vblank_put(vblank);
> ret = true;
> }
>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 06/24] drm/vblank: prefer drm_crtc_vblank_crtc() over drm_vblank_crtc()
2025-11-11 8:26 ` Thomas Zimmermann
@ 2025-11-11 8:43 ` Jani Nikula
2025-11-11 16:00 ` Ville Syrjälä
0 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-11 8:43 UTC (permalink / raw)
To: Thomas Zimmermann, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
On Tue, 11 Nov 2025, Thomas Zimmermann <tzimmermann@suse.de> wrote:
> Am 10.11.25 um 17:17 schrieb Jani Nikula:
>> Use the higher level function where crtc is available.
>>
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>
> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
>
> Is there a long-term plan to replace drm_vblank_crtc() entirely?
> Otherwise this looks a bit pointless.
Well, almost entirely. There are a few cases (plus the one that Ville
mentioned later in the series) that need to operate on dev + pipe
alone. The main point is that when you have a crtc and use that for the
source of pipe, you don't have to do range checks on the pipe. This
becomes gradually more evident in the series.
BR,
Jani.
>
>> ---
>> drivers/gpu/drm/drm_vblank.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
>> index e3a5a783686f..96dbff63f52d 100644
>> --- a/drivers/gpu/drm/drm_vblank.c
>> +++ b/drivers/gpu/drm/drm_vblank.c
>> @@ -712,7 +712,7 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
>> {
>> struct drm_device *dev = crtc->dev;
>> unsigned int pipe = crtc->index;
>> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
>> + struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
>> struct timespec64 ts_etime, ts_vblank_time;
>> ktime_t stime, etime;
>> bool vbl_status;
>> @@ -1302,7 +1302,7 @@ int drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
>> {
>> struct drm_device *dev = crtc->dev;
>> int pipe = drm_crtc_index(crtc);
>> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
>> + struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
>> int ret;
>> u64 last;
>>
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 07/24] drm/vblank: pass vlank to drm_vblank_get()/_put()/_count()
2025-11-11 8:32 ` Thomas Zimmermann
@ 2025-11-11 8:53 ` Jani Nikula
2025-11-11 9:04 ` Thomas Zimmermann
0 siblings, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-11 8:53 UTC (permalink / raw)
To: Thomas Zimmermann, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
On Tue, 11 Nov 2025, Thomas Zimmermann <tzimmermann@suse.de> wrote:
> s/vlank/vblank in the commit headline
>
> Am 10.11.25 um 17:17 schrieb Jani Nikula:
>> Pass struct drm_vblank_crtc * to drm_vblank_get(), drm_vblank_put(), and
>> drm_vblank_count(). They'll figure out the vblank pointer as the first
>> thing anyway, so it's handy to pass it when available. We can also rely
>> on vblank having a valid pipe, and can reduce the number of checks we
>> do.
>
> I do agree that drm_vblank_crtc should be out go-to structure for these
> interfaces with wrappers around that do the lookup if necessary.
>
>>
>> Add underscore prefixed helpers for using dev/pipe until we've converted
>> all users to pass in the vblank. Directly convert the call sites that
>> already have the vblank pointer available.
>>
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>> drivers/gpu/drm/drm_internal.h | 6 +--
>> drivers/gpu/drm/drm_vblank.c | 77 ++++++++++++++++++-------------
>> drivers/gpu/drm/drm_vblank_work.c | 12 ++---
>> 3 files changed, 55 insertions(+), 40 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
>> index 5a3bed48ab1f..e9c85c3681f1 100644
>> --- a/drivers/gpu/drm/drm_internal.h
>> +++ b/drivers/gpu/drm/drm_internal.h
>> @@ -101,9 +101,9 @@ static inline bool drm_vblank_passed(u64 seq, u64 ref)
>> }
>>
>> void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
>> -int drm_vblank_get(struct drm_device *dev, unsigned int pipe);
>> -void drm_vblank_put(struct drm_device *dev, unsigned int pipe);
>> -u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe);
>> +int drm_vblank_get(struct drm_vblank_crtc *vblank);
>> +void drm_vblank_put(struct drm_vblank_crtc *vblank);
>> +u64 drm_vblank_count(struct drm_vblank_crtc *vblank);
>
> Why no call these helpers drm_vblank_crtc_<func>() ? That would avoid
> the underscored helper and have clear naming guidelines for later such
> functions.
I didn't really pay much attention to it. There's a lot of crtc in the
names already, so I guess the convention would then be:
drm_crtc_vblank_*(struct drm_crtc *crtc, ...)
drm_vblank_crtc_*(struct drm_vblank_crtc *vblank, ...)
No big deal for me to rename if you think that's a good convention.
The underscored helpers are temporary, and will get removed later in the
series. IMO the series is easier to review that way. Of course cleaner
if we don't have to add them in the first place.
BR,
Jani.
>
>>
>> /* drm_vblank_work.c */
>> static inline void drm_vblank_flush_worker(struct drm_vblank_crtc *vblank)
>> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
>> index 96dbff63f52d..0ae34f848660 100644
>> --- a/drivers/gpu/drm/drm_vblank.c
>> +++ b/drivers/gpu/drm/drm_vblank.c
>> @@ -384,14 +384,10 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
>> store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
>> }
>>
>> -u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
>> +u64 drm_vblank_count(struct drm_vblank_crtc *vblank)
>> {
>> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
>> u64 count;
>>
>> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>> - return 0;
>> -
>> count = atomic64_read(&vblank->count);
>>
>> /*
>> @@ -406,6 +402,14 @@ u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
>> return count;
>> }
>>
>> +static u64 _drm_vblank_count(struct drm_device *dev, unsigned int pipe)
>> +{
>> + if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>> + return 0;
>> +
>> + return drm_vblank_count(drm_vblank_crtc(dev, pipe));
>> +}
>> +
>> /**
>> * drm_crtc_accurate_vblank_count - retrieve the master vblank counter
>> * @crtc: which counter to retrieve
>> @@ -431,7 +435,7 @@ u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
>> spin_lock_irqsave(&dev->vblank_time_lock, flags);
>>
>> drm_update_vblank_count(dev, pipe, false);
>> - vblank = drm_vblank_count(dev, pipe);
>> + vblank = _drm_vblank_count(dev, pipe);
>>
>> spin_unlock_irqrestore(&dev->vblank_time_lock, flags);
>>
>> @@ -935,7 +939,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
>> */
>> u64 drm_crtc_vblank_count(struct drm_crtc *crtc)
>> {
>> - return drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
>> + return _drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
>> }
>> EXPORT_SYMBOL(drm_crtc_vblank_count);
>>
>> @@ -1208,18 +1212,16 @@ static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
>> return ret;
>> }
>>
>> -int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
>> +int drm_vblank_get(struct drm_vblank_crtc *vblank)
>> {
>> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
>> + struct drm_device *dev = vblank->dev;
>> + int pipe = vblank->pipe;
>> unsigned long irqflags;
>> int ret = 0;
>>
>> if (!drm_dev_has_vblank(dev))
>> return -EINVAL;
>>
>> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>> - return -EINVAL;
>> -
>> spin_lock_irqsave(&dev->vbl_lock, irqflags);
>> /* Going from 0->1 means we have to enable interrupts again */
>> if (atomic_add_return(1, &vblank->refcount) == 1) {
>> @@ -1235,6 +1237,14 @@ int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
>> return ret;
>> }
>>
>> +static int _drm_vblank_get(struct drm_device *dev, unsigned int pipe)
>> +{
>> + if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>> + return -EINVAL;
>> +
>> + return drm_vblank_get(drm_vblank_crtc(dev, pipe));
>> +}
>> +
>> /**
>> * drm_crtc_vblank_get - get a reference count on vblank events
>> * @crtc: which CRTC to own
>> @@ -1247,18 +1257,15 @@ int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
>> */
>> int drm_crtc_vblank_get(struct drm_crtc *crtc)
>> {
>> - return drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
>> + return _drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
>> }
>> EXPORT_SYMBOL(drm_crtc_vblank_get);
>>
>> -void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
>> +void drm_vblank_put(struct drm_vblank_crtc *vblank)
>> {
>> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
>> + struct drm_device *dev = vblank->dev;
>> int vblank_offdelay = vblank->config.offdelay_ms;
>>
>> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>> - return;
>> -
>> if (drm_WARN_ON(dev, atomic_read(&vblank->refcount) == 0))
>> return;
>>
>> @@ -1274,6 +1281,14 @@ void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
>> }
>> }
>>
>> +static void _drm_vblank_put(struct drm_device *dev, unsigned int pipe)
>> +{
>> + if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>> + return;
>> +
>> + drm_vblank_put(drm_vblank_crtc(dev, pipe));
>> +}
>> +
>> /**
>> * drm_crtc_vblank_put - give up ownership of vblank events
>> * @crtc: which counter to give up
>> @@ -1284,7 +1299,7 @@ void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
>> */
>> void drm_crtc_vblank_put(struct drm_crtc *crtc)
>> {
>> - drm_vblank_put(crtc->dev, drm_crtc_index(crtc));
>> + _drm_vblank_put(crtc->dev, drm_crtc_index(crtc));
>> }
>> EXPORT_SYMBOL(drm_crtc_vblank_put);
>>
>> @@ -1306,20 +1321,20 @@ int drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
>> int ret;
>> u64 last;
>>
>> - ret = drm_vblank_get(dev, pipe);
>> + ret = drm_vblank_get(vblank);
>> if (drm_WARN(dev, ret, "vblank not available on crtc %i, ret=%i\n",
>> pipe, ret))
>> return ret;
>>
>> - last = drm_vblank_count(dev, pipe);
>> + last = drm_vblank_count(vblank);
>>
>> ret = wait_event_timeout(vblank->queue,
>> - last != drm_vblank_count(dev, pipe),
>> + last != drm_vblank_count(vblank),
>> msecs_to_jiffies(1000));
>>
>> drm_WARN(dev, ret == 0, "vblank wait timed out on crtc %i\n", pipe);
>>
>> - drm_vblank_put(dev, pipe);
>> + drm_vblank_put(vblank);
>>
>> return ret ? 0 : -ETIMEDOUT;
>> }
>> @@ -1385,7 +1400,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
>> "wanted %llu, current %llu\n",
>> e->sequence, seq);
>> list_del(&e->base.link);
>> - drm_vblank_put(dev, pipe);
>> + _drm_vblank_put(dev, pipe);
>> send_vblank_event(dev, e, seq, now);
>> }
>>
>> @@ -1661,7 +1676,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
>>
>> e->sequence = req_seq;
>> if (drm_vblank_passed(seq, req_seq)) {
>> - drm_vblank_put(dev, pipe);
>> + _drm_vblank_put(dev, pipe);
>> send_vblank_event(dev, e, seq, now);
>> vblwait->reply.sequence = seq;
>> } else {
>> @@ -1678,7 +1693,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
>> spin_unlock_irq(&dev->event_lock);
>> kfree(e);
>> err_put:
>> - drm_vblank_put(dev, pipe);
>> + _drm_vblank_put(dev, pipe);
>> return ret;
>> }
>>
>> @@ -1796,14 +1811,14 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
>> return 0;
>> }
>>
>> - ret = drm_vblank_get(dev, pipe);
>> + ret = _drm_vblank_get(dev, pipe);
>> if (ret) {
>> drm_dbg_core(dev,
>> "crtc %d failed to acquire vblank counter, %d\n",
>> pipe, ret);
>> return ret;
>> }
>> - seq = drm_vblank_count(dev, pipe);
>> + seq = _drm_vblank_count(dev, pipe);
>>
>> switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
>> case _DRM_VBLANK_RELATIVE:
>> @@ -1839,7 +1854,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
>> drm_dbg_core(dev, "waiting on vblank count %llu, crtc %u\n",
>> req_seq, pipe);
>> wait = wait_event_interruptible_timeout(vblank->queue,
>> - drm_vblank_passed(drm_vblank_count(dev, pipe), req_seq) ||
>> + drm_vblank_passed(_drm_vblank_count(dev, pipe), req_seq) ||
>> !READ_ONCE(vblank->enabled),
>> msecs_to_jiffies(3000));
>>
>> @@ -1869,7 +1884,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
>> }
>>
>> done:
>> - drm_vblank_put(dev, pipe);
>> + _drm_vblank_put(dev, pipe);
>> return ret;
>> }
>>
>> @@ -1895,7 +1910,7 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe)
>> e->sequence, seq);
>>
>> list_del(&e->base.link);
>> - drm_vblank_put(dev, pipe);
>> + _drm_vblank_put(dev, pipe);
>> send_vblank_event(dev, e, seq, now);
>> }
>>
>> diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c
>> index 70f0199251ea..2ef006626d50 100644
>> --- a/drivers/gpu/drm/drm_vblank_work.c
>> +++ b/drivers/gpu/drm/drm_vblank_work.c
>> @@ -58,7 +58,7 @@ void drm_handle_vblank_works(struct drm_vblank_crtc *vblank)
>> continue;
>>
>> list_del_init(&work->node);
>> - drm_vblank_put(vblank->dev, vblank->pipe);
>> + drm_vblank_put(vblank);
>> kthread_queue_work(vblank->worker, &work->base);
>> wake = true;
>> }
>> @@ -80,7 +80,7 @@ void drm_vblank_cancel_pending_works(struct drm_vblank_crtc *vblank)
>>
>> list_for_each_entry_safe(work, next, &vblank->pending_work, node) {
>> list_del_init(&work->node);
>> - drm_vblank_put(vblank->dev, vblank->pipe);
>> + drm_vblank_put(vblank);
>> }
>>
>> wake_up_all(&vblank->work_wait_queue);
>> @@ -129,7 +129,7 @@ int drm_vblank_work_schedule(struct drm_vblank_work *work,
>> goto out;
>>
>> if (list_empty(&work->node)) {
>> - ret = drm_vblank_get(dev, vblank->pipe);
>> + ret = drm_vblank_get(vblank);
>> if (ret < 0)
>> goto out;
>> } else if (work->count == count) {
>> @@ -140,7 +140,7 @@ int drm_vblank_work_schedule(struct drm_vblank_work *work,
>> }
>>
>> work->count = count;
>> - cur_vbl = drm_vblank_count(dev, vblank->pipe);
>> + cur_vbl = drm_vblank_count(vblank);
>> passed = drm_vblank_passed(cur_vbl, count);
>> if (passed)
>> drm_dbg_core(dev,
>> @@ -148,7 +148,7 @@ int drm_vblank_work_schedule(struct drm_vblank_work *work,
>> vblank->pipe, count, cur_vbl);
>>
>> if (!nextonmiss && passed) {
>> - drm_vblank_put(dev, vblank->pipe);
>> + drm_vblank_put(vblank);
>> ret = kthread_queue_work(vblank->worker, &work->base);
>>
>> if (rescheduling) {
>> @@ -193,7 +193,7 @@ bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work)
>> spin_lock_irq(&dev->event_lock);
>> if (!list_empty(&work->node)) {
>> list_del_init(&work->node);
>> - drm_vblank_put(vblank->dev, vblank->pipe);
>> + drm_vblank_put(vblank);
>> ret = true;
>> }
>>
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 23/24] drm/vblank: reduce pipe checks
2025-11-10 17:45 ` Ville Syrjälä
@ 2025-11-11 8:56 ` Jani Nikula
0 siblings, 0 replies; 59+ messages in thread
From: Jani Nikula @ 2025-11-11 8:56 UTC (permalink / raw)
To: Ville Syrjälä; +Cc: dri-devel, intel-gfx, intel-xe, Thomas Zimmermann
On Mon, 10 Nov 2025, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Mon, Nov 10, 2025 at 06:17:41PM +0200, Jani Nikula wrote:
>> Now that drm_vblank_crtc() is the only place that indexes dev->vblank[],
>> and its usage has reduced considerably, add the primary pipe
>> out-of-bounds check there, and return NULL. Expect callers to check it
>> and act accordingly.
>>
>> In drm_crtc_vblank_crtc(), warn and return NULL, and let it go boom. If
>> the crtc->pipe is out of bounds, it's a driver error that needs to be
>> fixed.
>>
>> Remove superfluous pipe checks all around.
>>
>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> ---
>> drivers/gpu/drm/drm_vblank.c | 36 +++++++++++++++---------------------
>> 1 file changed, 15 insertions(+), 21 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
>> index 44fb8d225485..7829e64e42b4 100644
>> --- a/drivers/gpu/drm/drm_vblank.c
>> +++ b/drivers/gpu/drm/drm_vblank.c
>> @@ -177,13 +177,22 @@ MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
>> static struct drm_vblank_crtc *
>> drm_vblank_crtc(struct drm_device *dev, unsigned int pipe)
>> {
>> + if (pipe >= dev->num_crtcs)
>> + return NULL;
>> +
>> return &dev->vblank[pipe];
>> }
>>
>> struct drm_vblank_crtc *
>> drm_crtc_vblank_crtc(struct drm_crtc *crtc)
>> {
>> - return drm_vblank_crtc(crtc->dev, drm_crtc_index(crtc));
>> + struct drm_vblank_crtc *vblank;
>> +
>> + vblank = drm_vblank_crtc(crtc->dev, drm_crtc_index(crtc));
>> + if (drm_WARN_ON(crtc->dev, !vblank))
>> + return NULL;
>> +
>> + return vblank;
>> }
>> EXPORT_SYMBOL(drm_crtc_vblank_crtc);
>>
>> @@ -631,7 +640,6 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
>> const struct drm_display_mode *mode)
>> {
>> struct drm_device *dev = crtc->dev;
>> - unsigned int pipe = drm_crtc_index(crtc);
>> struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
>> int linedur_ns = 0, framedur_ns = 0;
>> int dotclock = mode->crtc_clock;
>> @@ -639,9 +647,6 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
>> if (!drm_dev_has_vblank(dev))
>> return;
>
> I belive this at least gets called from the atomic helpers even
> for drivers that don't have vblank support. In which case the
> drm_crtc_vblank_crtc() call would have to be done after the
> drm_dev_has_vblank() check or else you'll get spurious WARNs.
>
> I don't remember if there are other cases like this as well.
Good catch! Yeah, not all places can be converted to struct
drm_vblank_crtc. I need to go through these.
There are a handful of places now that grab the vblank pointer (even
with NULL dev->vblank) and check has vblank afterwards, which is a bit
iffy. And actually mislead me here.
BR,
Jani.
>
>>
>> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>> - return;
>> -
>> /* Valid dotclock? */
>> if (dotclock > 0) {
>> int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
>> @@ -724,11 +729,6 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
>> int vpos, hpos, i;
>> int delta_ns, duration_ns;
>>
>> - if (pipe >= dev->num_crtcs) {
>> - drm_err(dev, "Invalid crtc %u\n", pipe);
>> - return false;
>> - }
>> -
>> /* Scanout position query not supported? Should not happen. */
>> if (!get_scanout_position) {
>> drm_err(dev, "Called from CRTC w/o get_scanout_position()!?\n");
>> @@ -1339,9 +1339,6 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
>> ktime_t now;
>> u64 seq;
>>
>> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>> - return;
>> -
>> /*
>> * Grab event_lock early to prevent vblank work from being scheduled
>> * while we're in the middle of shutting down vblank interrupts
>> @@ -1480,9 +1477,6 @@ void drm_crtc_vblank_on_config(struct drm_crtc *crtc,
>> unsigned int pipe = drm_crtc_index(crtc);
>> struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
>>
>> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>> - return;
>> -
>> spin_lock_irq(&dev->vbl_lock);
>> drm_dbg_vbl(dev, "crtc %d, vblank enabled %d, inmodeset %d\n",
>> pipe, vblank->enabled, vblank->inmodeset);
>> @@ -1764,10 +1758,9 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
>> pipe = pipe_index;
>> }
>>
>> - if (pipe >= dev->num_crtcs)
>> - return -EINVAL;
>> -
>> vblank = drm_vblank_crtc(dev, pipe);
>> + if (!vblank)
>> + return -EINVAL;
>>
>> /* If the counter is currently enabled and accurate, short-circuit
>> * queries to return the cached timestamp of the last vblank.
>> @@ -1902,14 +1895,15 @@ static void drm_handle_vblank_events(struct drm_vblank_crtc *vblank)
>> */
>> bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
>> {
>> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
>> + struct drm_vblank_crtc *vblank;
>> unsigned long irqflags;
>> bool disable_irq;
>>
>> if (drm_WARN_ON_ONCE(dev, !drm_dev_has_vblank(dev)))
>> return false;
>>
>> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>> + vblank = drm_vblank_crtc(dev, pipe);
>> + if (drm_WARN_ON(dev, !vblank))
>> return false;
>>
>> spin_lock_irqsave(&dev->event_lock, irqflags);
>> --
>> 2.47.3
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 07/24] drm/vblank: pass vlank to drm_vblank_get()/_put()/_count()
2025-11-11 8:53 ` Jani Nikula
@ 2025-11-11 9:04 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-11 9:04 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Hi
Am 11.11.25 um 09:53 schrieb Jani Nikula:
> On Tue, 11 Nov 2025, Thomas Zimmermann <tzimmermann@suse.de> wrote:
>> s/vlank/vblank in the commit headline
>>
>> Am 10.11.25 um 17:17 schrieb Jani Nikula:
>>> Pass struct drm_vblank_crtc * to drm_vblank_get(), drm_vblank_put(), and
>>> drm_vblank_count(). They'll figure out the vblank pointer as the first
>>> thing anyway, so it's handy to pass it when available. We can also rely
>>> on vblank having a valid pipe, and can reduce the number of checks we
>>> do.
>> I do agree that drm_vblank_crtc should be out go-to structure for these
>> interfaces with wrappers around that do the lookup if necessary.
>>
>>> Add underscore prefixed helpers for using dev/pipe until we've converted
>>> all users to pass in the vblank. Directly convert the call sites that
>>> already have the vblank pointer available.
>>>
>>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>>> ---
>>> drivers/gpu/drm/drm_internal.h | 6 +--
>>> drivers/gpu/drm/drm_vblank.c | 77 ++++++++++++++++++-------------
>>> drivers/gpu/drm/drm_vblank_work.c | 12 ++---
>>> 3 files changed, 55 insertions(+), 40 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
>>> index 5a3bed48ab1f..e9c85c3681f1 100644
>>> --- a/drivers/gpu/drm/drm_internal.h
>>> +++ b/drivers/gpu/drm/drm_internal.h
>>> @@ -101,9 +101,9 @@ static inline bool drm_vblank_passed(u64 seq, u64 ref)
>>> }
>>>
>>> void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
>>> -int drm_vblank_get(struct drm_device *dev, unsigned int pipe);
>>> -void drm_vblank_put(struct drm_device *dev, unsigned int pipe);
>>> -u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe);
>>> +int drm_vblank_get(struct drm_vblank_crtc *vblank);
>>> +void drm_vblank_put(struct drm_vblank_crtc *vblank);
>>> +u64 drm_vblank_count(struct drm_vblank_crtc *vblank);
>> Why no call these helpers drm_vblank_crtc_<func>() ? That would avoid
>> the underscored helper and have clear naming guidelines for later such
>> functions.
> I didn't really pay much attention to it. There's a lot of crtc in the
> names already, so I guess the convention would then be:
>
> drm_crtc_vblank_*(struct drm_crtc *crtc, ...)
>
> drm_vblank_crtc_*(struct drm_vblank_crtc *vblank, ...)
>
> No big deal for me to rename if you think that's a good convention.
Right. The third pattern would be
drm_vblank_*(struct drm_device, int pipe, ...)
The implementation would then gradually move towards using
drm_vblank_crtc_ where possible. Makes sense to me and would avoid any
intermediate helpers.
Best regards
Thomas
>
> The underscored helpers are temporary, and will get removed later in the
> series. IMO the series is easier to review that way. Of course cleaner
> if we don't have to add them in the first place.
>
> BR,
> Jani.
>
>>>
>>> /* drm_vblank_work.c */
>>> static inline void drm_vblank_flush_worker(struct drm_vblank_crtc *vblank)
>>> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
>>> index 96dbff63f52d..0ae34f848660 100644
>>> --- a/drivers/gpu/drm/drm_vblank.c
>>> +++ b/drivers/gpu/drm/drm_vblank.c
>>> @@ -384,14 +384,10 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
>>> store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
>>> }
>>>
>>> -u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
>>> +u64 drm_vblank_count(struct drm_vblank_crtc *vblank)
>>> {
>>> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
>>> u64 count;
>>>
>>> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>>> - return 0;
>>> -
>>> count = atomic64_read(&vblank->count);
>>>
>>> /*
>>> @@ -406,6 +402,14 @@ u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
>>> return count;
>>> }
>>>
>>> +static u64 _drm_vblank_count(struct drm_device *dev, unsigned int pipe)
>>> +{
>>> + if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>>> + return 0;
>>> +
>>> + return drm_vblank_count(drm_vblank_crtc(dev, pipe));
>>> +}
>>> +
>>> /**
>>> * drm_crtc_accurate_vblank_count - retrieve the master vblank counter
>>> * @crtc: which counter to retrieve
>>> @@ -431,7 +435,7 @@ u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
>>> spin_lock_irqsave(&dev->vblank_time_lock, flags);
>>>
>>> drm_update_vblank_count(dev, pipe, false);
>>> - vblank = drm_vblank_count(dev, pipe);
>>> + vblank = _drm_vblank_count(dev, pipe);
>>>
>>> spin_unlock_irqrestore(&dev->vblank_time_lock, flags);
>>>
>>> @@ -935,7 +939,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
>>> */
>>> u64 drm_crtc_vblank_count(struct drm_crtc *crtc)
>>> {
>>> - return drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
>>> + return _drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
>>> }
>>> EXPORT_SYMBOL(drm_crtc_vblank_count);
>>>
>>> @@ -1208,18 +1212,16 @@ static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
>>> return ret;
>>> }
>>>
>>> -int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
>>> +int drm_vblank_get(struct drm_vblank_crtc *vblank)
>>> {
>>> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
>>> + struct drm_device *dev = vblank->dev;
>>> + int pipe = vblank->pipe;
>>> unsigned long irqflags;
>>> int ret = 0;
>>>
>>> if (!drm_dev_has_vblank(dev))
>>> return -EINVAL;
>>>
>>> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>>> - return -EINVAL;
>>> -
>>> spin_lock_irqsave(&dev->vbl_lock, irqflags);
>>> /* Going from 0->1 means we have to enable interrupts again */
>>> if (atomic_add_return(1, &vblank->refcount) == 1) {
>>> @@ -1235,6 +1237,14 @@ int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
>>> return ret;
>>> }
>>>
>>> +static int _drm_vblank_get(struct drm_device *dev, unsigned int pipe)
>>> +{
>>> + if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>>> + return -EINVAL;
>>> +
>>> + return drm_vblank_get(drm_vblank_crtc(dev, pipe));
>>> +}
>>> +
>>> /**
>>> * drm_crtc_vblank_get - get a reference count on vblank events
>>> * @crtc: which CRTC to own
>>> @@ -1247,18 +1257,15 @@ int drm_vblank_get(struct drm_device *dev, unsigned int pipe)
>>> */
>>> int drm_crtc_vblank_get(struct drm_crtc *crtc)
>>> {
>>> - return drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
>>> + return _drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
>>> }
>>> EXPORT_SYMBOL(drm_crtc_vblank_get);
>>>
>>> -void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
>>> +void drm_vblank_put(struct drm_vblank_crtc *vblank)
>>> {
>>> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
>>> + struct drm_device *dev = vblank->dev;
>>> int vblank_offdelay = vblank->config.offdelay_ms;
>>>
>>> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>>> - return;
>>> -
>>> if (drm_WARN_ON(dev, atomic_read(&vblank->refcount) == 0))
>>> return;
>>>
>>> @@ -1274,6 +1281,14 @@ void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
>>> }
>>> }
>>>
>>> +static void _drm_vblank_put(struct drm_device *dev, unsigned int pipe)
>>> +{
>>> + if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
>>> + return;
>>> +
>>> + drm_vblank_put(drm_vblank_crtc(dev, pipe));
>>> +}
>>> +
>>> /**
>>> * drm_crtc_vblank_put - give up ownership of vblank events
>>> * @crtc: which counter to give up
>>> @@ -1284,7 +1299,7 @@ void drm_vblank_put(struct drm_device *dev, unsigned int pipe)
>>> */
>>> void drm_crtc_vblank_put(struct drm_crtc *crtc)
>>> {
>>> - drm_vblank_put(crtc->dev, drm_crtc_index(crtc));
>>> + _drm_vblank_put(crtc->dev, drm_crtc_index(crtc));
>>> }
>>> EXPORT_SYMBOL(drm_crtc_vblank_put);
>>>
>>> @@ -1306,20 +1321,20 @@ int drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
>>> int ret;
>>> u64 last;
>>>
>>> - ret = drm_vblank_get(dev, pipe);
>>> + ret = drm_vblank_get(vblank);
>>> if (drm_WARN(dev, ret, "vblank not available on crtc %i, ret=%i\n",
>>> pipe, ret))
>>> return ret;
>>>
>>> - last = drm_vblank_count(dev, pipe);
>>> + last = drm_vblank_count(vblank);
>>>
>>> ret = wait_event_timeout(vblank->queue,
>>> - last != drm_vblank_count(dev, pipe),
>>> + last != drm_vblank_count(vblank),
>>> msecs_to_jiffies(1000));
>>>
>>> drm_WARN(dev, ret == 0, "vblank wait timed out on crtc %i\n", pipe);
>>>
>>> - drm_vblank_put(dev, pipe);
>>> + drm_vblank_put(vblank);
>>>
>>> return ret ? 0 : -ETIMEDOUT;
>>> }
>>> @@ -1385,7 +1400,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
>>> "wanted %llu, current %llu\n",
>>> e->sequence, seq);
>>> list_del(&e->base.link);
>>> - drm_vblank_put(dev, pipe);
>>> + _drm_vblank_put(dev, pipe);
>>> send_vblank_event(dev, e, seq, now);
>>> }
>>>
>>> @@ -1661,7 +1676,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
>>>
>>> e->sequence = req_seq;
>>> if (drm_vblank_passed(seq, req_seq)) {
>>> - drm_vblank_put(dev, pipe);
>>> + _drm_vblank_put(dev, pipe);
>>> send_vblank_event(dev, e, seq, now);
>>> vblwait->reply.sequence = seq;
>>> } else {
>>> @@ -1678,7 +1693,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
>>> spin_unlock_irq(&dev->event_lock);
>>> kfree(e);
>>> err_put:
>>> - drm_vblank_put(dev, pipe);
>>> + _drm_vblank_put(dev, pipe);
>>> return ret;
>>> }
>>>
>>> @@ -1796,14 +1811,14 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
>>> return 0;
>>> }
>>>
>>> - ret = drm_vblank_get(dev, pipe);
>>> + ret = _drm_vblank_get(dev, pipe);
>>> if (ret) {
>>> drm_dbg_core(dev,
>>> "crtc %d failed to acquire vblank counter, %d\n",
>>> pipe, ret);
>>> return ret;
>>> }
>>> - seq = drm_vblank_count(dev, pipe);
>>> + seq = _drm_vblank_count(dev, pipe);
>>>
>>> switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
>>> case _DRM_VBLANK_RELATIVE:
>>> @@ -1839,7 +1854,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
>>> drm_dbg_core(dev, "waiting on vblank count %llu, crtc %u\n",
>>> req_seq, pipe);
>>> wait = wait_event_interruptible_timeout(vblank->queue,
>>> - drm_vblank_passed(drm_vblank_count(dev, pipe), req_seq) ||
>>> + drm_vblank_passed(_drm_vblank_count(dev, pipe), req_seq) ||
>>> !READ_ONCE(vblank->enabled),
>>> msecs_to_jiffies(3000));
>>>
>>> @@ -1869,7 +1884,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
>>> }
>>>
>>> done:
>>> - drm_vblank_put(dev, pipe);
>>> + _drm_vblank_put(dev, pipe);
>>> return ret;
>>> }
>>>
>>> @@ -1895,7 +1910,7 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe)
>>> e->sequence, seq);
>>>
>>> list_del(&e->base.link);
>>> - drm_vblank_put(dev, pipe);
>>> + _drm_vblank_put(dev, pipe);
>>> send_vblank_event(dev, e, seq, now);
>>> }
>>>
>>> diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c
>>> index 70f0199251ea..2ef006626d50 100644
>>> --- a/drivers/gpu/drm/drm_vblank_work.c
>>> +++ b/drivers/gpu/drm/drm_vblank_work.c
>>> @@ -58,7 +58,7 @@ void drm_handle_vblank_works(struct drm_vblank_crtc *vblank)
>>> continue;
>>>
>>> list_del_init(&work->node);
>>> - drm_vblank_put(vblank->dev, vblank->pipe);
>>> + drm_vblank_put(vblank);
>>> kthread_queue_work(vblank->worker, &work->base);
>>> wake = true;
>>> }
>>> @@ -80,7 +80,7 @@ void drm_vblank_cancel_pending_works(struct drm_vblank_crtc *vblank)
>>>
>>> list_for_each_entry_safe(work, next, &vblank->pending_work, node) {
>>> list_del_init(&work->node);
>>> - drm_vblank_put(vblank->dev, vblank->pipe);
>>> + drm_vblank_put(vblank);
>>> }
>>>
>>> wake_up_all(&vblank->work_wait_queue);
>>> @@ -129,7 +129,7 @@ int drm_vblank_work_schedule(struct drm_vblank_work *work,
>>> goto out;
>>>
>>> if (list_empty(&work->node)) {
>>> - ret = drm_vblank_get(dev, vblank->pipe);
>>> + ret = drm_vblank_get(vblank);
>>> if (ret < 0)
>>> goto out;
>>> } else if (work->count == count) {
>>> @@ -140,7 +140,7 @@ int drm_vblank_work_schedule(struct drm_vblank_work *work,
>>> }
>>>
>>> work->count = count;
>>> - cur_vbl = drm_vblank_count(dev, vblank->pipe);
>>> + cur_vbl = drm_vblank_count(vblank);
>>> passed = drm_vblank_passed(cur_vbl, count);
>>> if (passed)
>>> drm_dbg_core(dev,
>>> @@ -148,7 +148,7 @@ int drm_vblank_work_schedule(struct drm_vblank_work *work,
>>> vblank->pipe, count, cur_vbl);
>>>
>>> if (!nextonmiss && passed) {
>>> - drm_vblank_put(dev, vblank->pipe);
>>> + drm_vblank_put(vblank);
>>> ret = kthread_queue_work(vblank->worker, &work->base);
>>>
>>> if (rescheduling) {
>>> @@ -193,7 +193,7 @@ bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work)
>>> spin_lock_irq(&dev->event_lock);
>>> if (!list_empty(&work->node)) {
>>> list_del_init(&work->node);
>>> - drm_vblank_put(vblank->dev, vblank->pipe);
>>> + drm_vblank_put(vblank);
>>> ret = true;
>>> }
>>>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 06/24] drm/vblank: prefer drm_crtc_vblank_crtc() over drm_vblank_crtc()
2025-11-11 8:43 ` Jani Nikula
@ 2025-11-11 16:00 ` Ville Syrjälä
2025-11-12 8:26 ` Jani Nikula
2025-11-12 15:50 ` Thomas Zimmermann
0 siblings, 2 replies; 59+ messages in thread
From: Ville Syrjälä @ 2025-11-11 16:00 UTC (permalink / raw)
To: Jani Nikula; +Cc: Thomas Zimmermann, dri-devel, intel-gfx, intel-xe
On Tue, Nov 11, 2025 at 10:43:15AM +0200, Jani Nikula wrote:
> On Tue, 11 Nov 2025, Thomas Zimmermann <tzimmermann@suse.de> wrote:
> > Am 10.11.25 um 17:17 schrieb Jani Nikula:
> >> Use the higher level function where crtc is available.
> >>
> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >
> > Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> >
> > Is there a long-term plan to replace drm_vblank_crtc() entirely?
> > Otherwise this looks a bit pointless.
>
> Well, almost entirely. There are a few cases (plus the one that Ville
> mentioned later in the series) that need to operate on dev + pipe
> alone. The main point is that when you have a crtc and use that for the
> source of pipe, you don't have to do range checks on the pipe. This
> becomes gradually more evident in the series.
I've actaully been thinking about doing the exact opposite.
Ie. switch drm_vblank.c over to drm_vblank_crtc completely.
That is one of those things that might help with implementing
pipe/crtc virtualization in i915. We basically want all interrupt
stuff (including vblanks) to be tied to our hardware pipes and
not the uapi drm_crtc. So we'd make drm_vblank_crtc==pipe, and
introduce some kind of dynamic drm_crtc<->drm_vblank_crtc mapping
for the uapi facing parts of drm_vblank.c...
--
Ville Syrjälä
Intel
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 06/24] drm/vblank: prefer drm_crtc_vblank_crtc() over drm_vblank_crtc()
2025-11-11 16:00 ` Ville Syrjälä
@ 2025-11-12 8:26 ` Jani Nikula
2025-11-12 11:56 ` Ville Syrjälä
2025-11-12 15:50 ` Thomas Zimmermann
1 sibling, 1 reply; 59+ messages in thread
From: Jani Nikula @ 2025-11-12 8:26 UTC (permalink / raw)
To: Ville Syrjälä; +Cc: Thomas Zimmermann, dri-devel, intel-gfx, intel-xe
On Tue, 11 Nov 2025, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> On Tue, Nov 11, 2025 at 10:43:15AM +0200, Jani Nikula wrote:
>> On Tue, 11 Nov 2025, Thomas Zimmermann <tzimmermann@suse.de> wrote:
>> > Am 10.11.25 um 17:17 schrieb Jani Nikula:
>> >> Use the higher level function where crtc is available.
>> >>
>> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> >
>> > Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
>> >
>> > Is there a long-term plan to replace drm_vblank_crtc() entirely?
>> > Otherwise this looks a bit pointless.
>>
>> Well, almost entirely. There are a few cases (plus the one that Ville
>> mentioned later in the series) that need to operate on dev + pipe
>> alone. The main point is that when you have a crtc and use that for the
>> source of pipe, you don't have to do range checks on the pipe. This
>> becomes gradually more evident in the series.
>
> I've actaully been thinking about doing the exact opposite.
> Ie. switch drm_vblank.c over to drm_vblank_crtc completely.
>
> That is one of those things that might help with implementing
> pipe/crtc virtualization in i915. We basically want all interrupt
> stuff (including vblanks) to be tied to our hardware pipes and
> not the uapi drm_crtc. So we'd make drm_vblank_crtc==pipe, and
> introduce some kind of dynamic drm_crtc<->drm_vblank_crtc mapping
> for the uapi facing parts of drm_vblank.c...
Ugh, so you're saying the series at hand is counter-productive?
BR,
Jani.
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 06/24] drm/vblank: prefer drm_crtc_vblank_crtc() over drm_vblank_crtc()
2025-11-12 8:26 ` Jani Nikula
@ 2025-11-12 11:56 ` Ville Syrjälä
0 siblings, 0 replies; 59+ messages in thread
From: Ville Syrjälä @ 2025-11-12 11:56 UTC (permalink / raw)
To: Jani Nikula; +Cc: Thomas Zimmermann, dri-devel, intel-gfx, intel-xe
On Wed, Nov 12, 2025 at 10:26:15AM +0200, Jani Nikula wrote:
> On Tue, 11 Nov 2025, Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:
> > On Tue, Nov 11, 2025 at 10:43:15AM +0200, Jani Nikula wrote:
> >> On Tue, 11 Nov 2025, Thomas Zimmermann <tzimmermann@suse.de> wrote:
> >> > Am 10.11.25 um 17:17 schrieb Jani Nikula:
> >> >> Use the higher level function where crtc is available.
> >> >>
> >> >> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >> >
> >> > Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> >> >
> >> > Is there a long-term plan to replace drm_vblank_crtc() entirely?
> >> > Otherwise this looks a bit pointless.
> >>
> >> Well, almost entirely. There are a few cases (plus the one that Ville
> >> mentioned later in the series) that need to operate on dev + pipe
> >> alone. The main point is that when you have a crtc and use that for the
> >> source of pipe, you don't have to do range checks on the pipe. This
> >> becomes gradually more evident in the series.
> >
> > I've actaully been thinking about doing the exact opposite.
> > Ie. switch drm_vblank.c over to drm_vblank_crtc completely.
> >
> > That is one of those things that might help with implementing
> > pipe/crtc virtualization in i915. We basically want all interrupt
> > stuff (including vblanks) to be tied to our hardware pipes and
> > not the uapi drm_crtc. So we'd make drm_vblank_crtc==pipe, and
> > introduce some kind of dynamic drm_crtc<->drm_vblank_crtc mapping
> > for the uapi facing parts of drm_vblank.c...
>
> Ugh, so you're saying the series at hand is counter-productive?
No, I think it's fine for the most part. The only worry would be
anything that starts to depend on drm_crtc rather than drm_vblank_crtc,
but I don't think you had a lot of that.
--
Ville Syrjälä
Intel
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 06/24] drm/vblank: prefer drm_crtc_vblank_crtc() over drm_vblank_crtc()
2025-11-11 16:00 ` Ville Syrjälä
2025-11-12 8:26 ` Jani Nikula
@ 2025-11-12 15:50 ` Thomas Zimmermann
1 sibling, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 15:50 UTC (permalink / raw)
To: Ville Syrjälä, Jani Nikula; +Cc: dri-devel, intel-gfx, intel-xe
Hi
Am 11.11.25 um 17:00 schrieb Ville Syrjälä:
> On Tue, Nov 11, 2025 at 10:43:15AM +0200, Jani Nikula wrote:
>> On Tue, 11 Nov 2025, Thomas Zimmermann <tzimmermann@suse.de> wrote:
>>> Am 10.11.25 um 17:17 schrieb Jani Nikula:
>>>> Use the higher level function where crtc is available.
>>>>
>>>> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>>> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
>>>
>>> Is there a long-term plan to replace drm_vblank_crtc() entirely?
>>> Otherwise this looks a bit pointless.
>> Well, almost entirely. There are a few cases (plus the one that Ville
>> mentioned later in the series) that need to operate on dev + pipe
>> alone. The main point is that when you have a crtc and use that for the
>> source of pipe, you don't have to do range checks on the pipe. This
>> becomes gradually more evident in the series.
> I've actaully been thinking about doing the exact opposite.
> Ie. switch drm_vblank.c over to drm_vblank_crtc completely.
>
> That is one of those things that might help with implementing
> pipe/crtc virtualization in i915. We basically want all interrupt
> stuff (including vblanks) to be tied to our hardware pipes and
> not the uapi drm_crtc. So we'd make drm_vblank_crtc==pipe, and
> introduce some kind of dynamic drm_crtc<->drm_vblank_crtc mapping
> for the uapi facing parts of drm_vblank.c...
IMHO there needs to be clear documentation what exactly a pipe is and
how it relates to a CRTC. And it's got to remain simple for simple hardware.
Best regards
Thomas
>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 08/24] drm/vblank: pass vblank to drm_update_vblank_count()
2025-11-10 16:17 ` [PATCH 08/24] drm/vblank: pass vblank to drm_update_vblank_count() Jani Nikula
@ 2025-11-12 15:54 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 15:54 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Hi
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the vblank pointer instead of a dev, pipe pair to simplify code.
I always thought the code could benefit from this change. Great to see
it happen.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
For this patch and the others, I assume that some interfaces might
change there names as we discussed.
> ---
> drivers/gpu/drm/drm_vblank.c | 21 +++++++++++----------
> 1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 0ae34f848660..d2748ed01c34 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -292,10 +292,11 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe
> * Note: caller must hold &drm_device.vbl_lock since this reads & writes
> * device vblank fields.
> */
> -static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
> +static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
> bool in_vblank_irq)
> {
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> + struct drm_device *dev = vblank->dev;
> + unsigned int pipe = vblank->pipe;
> u32 cur_vblank, diff;
> bool rc;
> ktime_t t_vblank;
> @@ -424,8 +425,8 @@ static u64 _drm_vblank_count(struct drm_device *dev, unsigned int pipe)
> u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
> {
> struct drm_device *dev = crtc->dev;
> - unsigned int pipe = drm_crtc_index(crtc);
> - u64 vblank;
> + struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
> + u64 vblank_count;
> unsigned long flags;
>
> drm_WARN_ONCE(dev, drm_debug_enabled(DRM_UT_VBL) &&
> @@ -434,12 +435,12 @@ u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
>
> spin_lock_irqsave(&dev->vblank_time_lock, flags);
>
> - drm_update_vblank_count(dev, pipe, false);
> - vblank = _drm_vblank_count(dev, pipe);
> + drm_update_vblank_count(vblank, false);
> + vblank_count = drm_vblank_count(vblank);
>
> spin_unlock_irqrestore(&dev->vblank_time_lock, flags);
>
> - return vblank;
> + return vblank_count;
> }
> EXPORT_SYMBOL(drm_crtc_accurate_vblank_count);
>
> @@ -490,7 +491,7 @@ void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
> * this time. This makes the count account for the entire time
> * between drm_crtc_vblank_on() and drm_crtc_vblank_off().
> */
> - drm_update_vblank_count(dev, pipe, false);
> + drm_update_vblank_count(vblank, false);
> __disable_vblank(dev, pipe);
> vblank->enabled = false;
>
> @@ -1197,7 +1198,7 @@ static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
> if (ret) {
> atomic_dec(&vblank->refcount);
> } else {
> - drm_update_vblank_count(dev, pipe, 0);
> + drm_update_vblank_count(vblank, 0);
> /* drm_update_vblank_count() includes a wmb so we just
> * need to ensure that the compiler emits the write
> * to mark the vblank as enabled after the call
> @@ -1957,7 +1958,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
> return false;
> }
>
> - drm_update_vblank_count(dev, pipe, true);
> + drm_update_vblank_count(vblank, true);
>
> spin_unlock(&dev->vblank_time_lock);
>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 09/24] drm/vblank: pass vblank to drm_handle_vblank_events()
2025-11-10 16:17 ` [PATCH 09/24] drm/vblank: pass vblank to drm_handle_vblank_events() Jani Nikula
@ 2025-11-12 15:56 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 15:56 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the vblank pointer instead of a dev, pipe pair to simplify code.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_vblank.c | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index d2748ed01c34..91bedf8e6ea8 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -1889,8 +1889,10 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> return ret;
> }
>
> -static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe)
> +static void drm_handle_vblank_events(struct drm_vblank_crtc *vblank)
> {
> + struct drm_device *dev = vblank->dev;
> + unsigned int pipe = vblank->pipe;
> struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
> bool high_prec = false;
> struct drm_pending_vblank_event *e, *t;
> @@ -1911,7 +1913,7 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe)
> e->sequence, seq);
>
> list_del(&e->base.link);
> - _drm_vblank_put(dev, pipe);
> + drm_vblank_put(vblank);
> send_vblank_event(dev, e, seq, now);
> }
>
> @@ -1973,7 +1975,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
> vblank->config.offdelay_ms > 0 &&
> !atomic_read(&vblank->refcount));
>
> - drm_handle_vblank_events(dev, pipe);
> + drm_handle_vblank_events(vblank);
> drm_handle_vblank_works(vblank);
>
> spin_unlock_irqrestore(&dev->event_lock, irqflags);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 10/24] drm/vblank: use the vblank based interfaces more
2025-11-10 16:17 ` [PATCH 10/24] drm/vblank: use the vblank based interfaces more Jani Nikula
@ 2025-11-12 15:56 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 15:56 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> With the prep work in place, we can get rid of _drm_vblank_get(),
> _drm_vblank_put(), and _drm_vblank_count().
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_vblank.c | 44 ++++++++----------------------------
> 1 file changed, 10 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 91bedf8e6ea8..1c0ade41a57f 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -403,14 +403,6 @@ u64 drm_vblank_count(struct drm_vblank_crtc *vblank)
> return count;
> }
>
> -static u64 _drm_vblank_count(struct drm_device *dev, unsigned int pipe)
> -{
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return 0;
> -
> - return drm_vblank_count(drm_vblank_crtc(dev, pipe));
> -}
> -
> /**
> * drm_crtc_accurate_vblank_count - retrieve the master vblank counter
> * @crtc: which counter to retrieve
> @@ -940,7 +932,7 @@ drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
> */
> u64 drm_crtc_vblank_count(struct drm_crtc *crtc)
> {
> - return _drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
> + return drm_vblank_count(drm_crtc_vblank_crtc(crtc));
> }
> EXPORT_SYMBOL(drm_crtc_vblank_count);
>
> @@ -1238,14 +1230,6 @@ int drm_vblank_get(struct drm_vblank_crtc *vblank)
> return ret;
> }
>
> -static int _drm_vblank_get(struct drm_device *dev, unsigned int pipe)
> -{
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return -EINVAL;
> -
> - return drm_vblank_get(drm_vblank_crtc(dev, pipe));
> -}
> -
> /**
> * drm_crtc_vblank_get - get a reference count on vblank events
> * @crtc: which CRTC to own
> @@ -1258,7 +1242,7 @@ static int _drm_vblank_get(struct drm_device *dev, unsigned int pipe)
> */
> int drm_crtc_vblank_get(struct drm_crtc *crtc)
> {
> - return _drm_vblank_get(crtc->dev, drm_crtc_index(crtc));
> + return drm_vblank_get(drm_crtc_vblank_crtc(crtc));
> }
> EXPORT_SYMBOL(drm_crtc_vblank_get);
>
> @@ -1282,14 +1266,6 @@ void drm_vblank_put(struct drm_vblank_crtc *vblank)
> }
> }
>
> -static void _drm_vblank_put(struct drm_device *dev, unsigned int pipe)
> -{
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return;
> -
> - drm_vblank_put(drm_vblank_crtc(dev, pipe));
> -}
> -
> /**
> * drm_crtc_vblank_put - give up ownership of vblank events
> * @crtc: which counter to give up
> @@ -1300,7 +1276,7 @@ static void _drm_vblank_put(struct drm_device *dev, unsigned int pipe)
> */
> void drm_crtc_vblank_put(struct drm_crtc *crtc)
> {
> - _drm_vblank_put(crtc->dev, drm_crtc_index(crtc));
> + drm_vblank_put(drm_crtc_vblank_crtc(crtc));
> }
> EXPORT_SYMBOL(drm_crtc_vblank_put);
>
> @@ -1401,7 +1377,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
> "wanted %llu, current %llu\n",
> e->sequence, seq);
> list_del(&e->base.link);
> - _drm_vblank_put(dev, pipe);
> + drm_vblank_put(vblank);
> send_vblank_event(dev, e, seq, now);
> }
>
> @@ -1677,7 +1653,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
>
> e->sequence = req_seq;
> if (drm_vblank_passed(seq, req_seq)) {
> - _drm_vblank_put(dev, pipe);
> + drm_vblank_put(vblank);
> send_vblank_event(dev, e, seq, now);
> vblwait->reply.sequence = seq;
> } else {
> @@ -1694,7 +1670,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
> spin_unlock_irq(&dev->event_lock);
> kfree(e);
> err_put:
> - _drm_vblank_put(dev, pipe);
> + drm_vblank_put(vblank);
> return ret;
> }
>
> @@ -1812,14 +1788,14 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> return 0;
> }
>
> - ret = _drm_vblank_get(dev, pipe);
> + ret = drm_vblank_get(vblank);
> if (ret) {
> drm_dbg_core(dev,
> "crtc %d failed to acquire vblank counter, %d\n",
> pipe, ret);
> return ret;
> }
> - seq = _drm_vblank_count(dev, pipe);
> + seq = drm_vblank_count(vblank);
>
> switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
> case _DRM_VBLANK_RELATIVE:
> @@ -1855,7 +1831,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> drm_dbg_core(dev, "waiting on vblank count %llu, crtc %u\n",
> req_seq, pipe);
> wait = wait_event_interruptible_timeout(vblank->queue,
> - drm_vblank_passed(_drm_vblank_count(dev, pipe), req_seq) ||
> + drm_vblank_passed(drm_vblank_count(vblank), req_seq) ||
> !READ_ONCE(vblank->enabled),
> msecs_to_jiffies(3000));
>
> @@ -1885,7 +1861,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> }
>
> done:
> - _drm_vblank_put(dev, pipe);
> + drm_vblank_put(vblank);
> return ret;
> }
>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 11/24] drm/vblank: pass vblank to drm_queue_vblank_event()
2025-11-10 16:17 ` [PATCH 11/24] drm/vblank: pass vblank to drm_queue_vblank_event() Jani Nikula
@ 2025-11-12 15:57 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 15:57 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the vblank pointer instead of a dev, pipe pair to simplify code.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_vblank.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 1c0ade41a57f..5880c43e19a0 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -1596,12 +1596,13 @@ void drm_crtc_vblank_restore(struct drm_crtc *crtc)
> }
> EXPORT_SYMBOL(drm_crtc_vblank_restore);
>
> -static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
> +static int drm_queue_vblank_event(struct drm_vblank_crtc *vblank,
> u64 req_seq,
> union drm_wait_vblank *vblwait,
> struct drm_file *file_priv)
> {
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> + struct drm_device *dev = vblank->dev;
> + unsigned int pipe = vblank->pipe;
> struct drm_pending_vblank_event *e;
> ktime_t now;
> u64 seq;
> @@ -1822,7 +1823,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> /* must hold on to the vblank ref until the event fires
> * drm_vblank_put will be called asynchronously
> */
> - return drm_queue_vblank_event(dev, pipe, req_seq, vblwait, file_priv);
> + return drm_queue_vblank_event(vblank, req_seq, vblwait, file_priv);
> }
>
> if (req_seq != seq) {
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 12/24] drm/vblank: pass vblank to drm_wait_vblank_reply()
2025-11-10 16:17 ` [PATCH 12/24] drm/vblank: pass vblank to drm_wait_vblank_reply() Jani Nikula
@ 2025-11-12 16:01 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 16:01 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the vblank pointer instead of a dev, pipe pair to simplify code.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
See my comment below.
> ---
> drivers/gpu/drm/drm_vblank.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 5880c43e19a0..e33b7fa6f19a 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -1702,7 +1702,7 @@ static u64 widen_32_to_64(u32 narrow, u64 near)
> return near + (s32) (narrow - near);
> }
>
> -static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe,
> +static void drm_wait_vblank_reply(struct drm_vblank_crtc *vblank,
> struct drm_wait_vblank_reply *reply)
> {
> ktime_t now;
> @@ -1713,7 +1713,7 @@ static void drm_wait_vblank_reply(struct drm_device *dev, unsigned int pipe,
> * to store the seconds. This is safe as we always use monotonic
> * timestamps since linux-4.15.
> */
> - reply->sequence = drm_vblank_count_and_time(dev, pipe, &now);
> + reply->sequence = drm_vblank_count_and_time(vblank->dev, vblank->pipe, &now);
Did you intentionally miss converting drm_vblank_count_and_time()?
> ts = ktime_to_timespec64(now);
> reply->tval_sec = (u32)ts.tv_sec;
> reply->tval_usec = ts.tv_nsec / 1000;
> @@ -1785,7 +1785,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> if (vblank->config.disable_immediate &&
> drm_wait_vblank_is_query(vblwait) &&
> READ_ONCE(vblank->enabled)) {
> - drm_wait_vblank_reply(dev, pipe, &vblwait->reply);
> + drm_wait_vblank_reply(vblank, &vblwait->reply);
> return 0;
> }
>
> @@ -1852,7 +1852,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> }
>
> if (ret != -EINTR) {
> - drm_wait_vblank_reply(dev, pipe, &vblwait->reply);
> + drm_wait_vblank_reply(vblank, &vblwait->reply);
>
> drm_dbg_core(dev, "crtc %d returning %u to client\n",
> pipe, vblwait->reply.sequence);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 13/24] drm/vblank: pass vblank to drm_vblank_count_and_time()
2025-11-10 16:17 ` [PATCH 13/24] drm/vblank: pass vblank to drm_vblank_count_and_time() Jani Nikula
2025-11-11 6:52 ` kernel test robot
@ 2025-11-12 16:03 ` Thomas Zimmermann
1 sibling, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 16:03 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the vblank pointer instead of a dev, pipe pair to simplify code.
>
> Drop the pipe check warning, as we can be sure vblank->pipe is within
> limits.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
OK, this is what I was looking for in the previous patch. Would it make
sense to change order of the patches?
> ---
> drivers/gpu/drm/drm_vblank.c | 28 +++++++++++-----------------
> 1 file changed, 11 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index e33b7fa6f19a..0a2e372dd549 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -950,18 +950,12 @@ EXPORT_SYMBOL(drm_crtc_vblank_count);
> *
> * This is the legacy version of drm_crtc_vblank_count_and_time().
> */
> -static u64 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe,
> +static u64 drm_vblank_count_and_time(struct drm_vblank_crtc *vblank,
> ktime_t *vblanktime)
> {
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> u64 vblank_count;
> unsigned int seq;
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs)) {
> - *vblanktime = 0;
> - return 0;
> - }
> -
> do {
> seq = read_seqbegin(&vblank->seqlock);
> vblank_count = atomic64_read(&vblank->count);
> @@ -993,7 +987,7 @@ static u64 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe,
> u64 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc,
> ktime_t *vblanktime)
> {
> - return drm_vblank_count_and_time(crtc->dev, drm_crtc_index(crtc),
> + return drm_vblank_count_and_time(drm_crtc_vblank_crtc(crtc),
> vblanktime);
> }
> EXPORT_SYMBOL(drm_crtc_vblank_count_and_time);
> @@ -1136,18 +1130,18 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
> struct drm_pending_vblank_event *e)
> {
> struct drm_device *dev = crtc->dev;
> + struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
> u64 seq;
> - unsigned int pipe = drm_crtc_index(crtc);
> ktime_t now;
>
> if (drm_dev_has_vblank(dev)) {
> - seq = drm_vblank_count_and_time(dev, pipe, &now);
> + seq = drm_vblank_count_and_time(vblank, &now);
> } else {
> seq = 0;
>
> now = ktime_get();
> }
> - e->pipe = pipe;
> + e->pipe = vblank->pipe;
> send_vblank_event(dev, e, seq, now);
> }
> EXPORT_SYMBOL(drm_crtc_send_vblank_event);
> @@ -1368,7 +1362,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
> spin_unlock(&dev->vbl_lock);
>
> /* Send any queued vblank events, lest the natives grow disquiet */
> - seq = drm_vblank_count_and_time(dev, pipe, &now);
> + seq = drm_vblank_count_and_time(vblank, &now);
>
> list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
> if (e->pipe != pipe)
> @@ -1645,7 +1639,7 @@ static int drm_queue_vblank_event(struct drm_vblank_crtc *vblank,
> if (ret)
> goto err_unlock;
>
> - seq = drm_vblank_count_and_time(dev, pipe, &now);
> + seq = drm_vblank_count_and_time(vblank, &now);
>
> drm_dbg_core(dev, "event on vblank count %llu, current %llu, crtc %u\n",
> req_seq, seq, pipe);
> @@ -1713,7 +1707,7 @@ static void drm_wait_vblank_reply(struct drm_vblank_crtc *vblank,
> * to store the seconds. This is safe as we always use monotonic
> * timestamps since linux-4.15.
> */
> - reply->sequence = drm_vblank_count_and_time(vblank->dev, vblank->pipe, &now);
> + reply->sequence = drm_vblank_count_and_time(vblank, &now);
> ts = ktime_to_timespec64(now);
> reply->tval_sec = (u32)ts.tv_sec;
> reply->tval_usec = ts.tv_nsec / 1000;
> @@ -1878,7 +1872,7 @@ static void drm_handle_vblank_events(struct drm_vblank_crtc *vblank)
>
> assert_spin_locked(&dev->event_lock);
>
> - seq = drm_vblank_count_and_time(dev, pipe, &now);
> + seq = drm_vblank_count_and_time(vblank, &now);
>
> list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
> if (e->pipe != pipe)
> @@ -2040,7 +2034,7 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data,
> else
> get_seq->active = crtc->enabled;
> drm_modeset_unlock(&crtc->mutex);
> - get_seq->sequence = drm_vblank_count_and_time(dev, pipe, &now);
> + get_seq->sequence = drm_vblank_count_and_time(vblank, &now);
> get_seq->sequence_ns = ktime_to_ns(now);
> if (!vblank_enabled)
> drm_crtc_vblank_put(crtc);
> @@ -2101,7 +2095,7 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data,
> goto err_free;
> }
>
> - seq = drm_vblank_count_and_time(dev, pipe, &now);
> + seq = drm_vblank_count_and_time(vblank, &now);
> req_seq = queue_seq->sequence;
>
> if (flags & DRM_CRTC_SEQUENCE_RELATIVE)
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 14/24] drm/vblank: pass vblank to drm_reset_vblank_timestamp()
2025-11-10 16:17 ` [PATCH 14/24] drm/vblank: pass vblank to drm_reset_vblank_timestamp() Jani Nikula
@ 2025-11-12 16:07 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 16:07 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the vblank pointer instead of a dev, pipe pair to simplify code.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_vblank.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 0a2e372dd549..93ad785cbc32 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -245,8 +245,10 @@ static u32 __get_vblank_counter(struct drm_device *dev, unsigned int pipe)
> * Note: caller must hold &drm_device.vbl_lock since this reads & writes
> * device vblank fields.
> */
> -static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe)
> +static void drm_reset_vblank_timestamp(struct drm_vblank_crtc *vblank)
> {
> + struct drm_device *dev = vblank->dev;
> + unsigned int pipe = vblank->pipe;
> u32 cur_vblank;
> bool rc;
> ktime_t t_vblank;
> @@ -1487,7 +1489,7 @@ void drm_crtc_vblank_on_config(struct drm_crtc *crtc,
> vblank->inmodeset = 0;
> }
>
> - drm_reset_vblank_timestamp(dev, pipe);
> + drm_reset_vblank_timestamp(vblank);
>
> /*
> * re-enable interrupts if there are users left, or the
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 15/24] drm/vblank: pass vblank to store_vblank()
2025-11-10 16:17 ` [PATCH 15/24] drm/vblank: pass vblank to store_vblank() Jani Nikula
@ 2025-11-12 16:08 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 16:08 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the vblank pointer instead of a dev, pipe pair to simplify code.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_vblank.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 93ad785cbc32..86919b1c0c2c 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -188,11 +188,11 @@ drm_crtc_vblank_crtc(struct drm_crtc *crtc)
> }
> EXPORT_SYMBOL(drm_crtc_vblank_crtc);
>
> -static void store_vblank(struct drm_device *dev, unsigned int pipe,
> +static void store_vblank(struct drm_vblank_crtc *vblank,
> u32 vblank_count_inc,
> ktime_t t_vblank, u32 last)
> {
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> + struct drm_device *dev = vblank->dev;
>
> assert_spin_locked(&dev->vblank_time_lock);
>
> @@ -277,7 +277,7 @@ static void drm_reset_vblank_timestamp(struct drm_vblank_crtc *vblank)
> * +1 to make sure user will never see the same
> * vblank counter value before and after a modeset
> */
> - store_vblank(dev, pipe, 1, t_vblank, cur_vblank);
> + store_vblank(vblank, 1, t_vblank, cur_vblank);
>
> spin_unlock(&dev->vblank_time_lock);
> }
> @@ -384,7 +384,7 @@ static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
> if (!rc && !in_vblank_irq)
> t_vblank = 0;
>
> - store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
> + store_vblank(vblank, diff, t_vblank, cur_vblank);
> }
>
> u64 drm_vblank_count(struct drm_vblank_crtc *vblank)
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 16/24] drm/vblank: pass vblank to drm_vblank_enable()
2025-11-10 16:17 ` [PATCH 16/24] drm/vblank: pass vblank to drm_vblank_enable() Jani Nikula
@ 2025-11-12 16:08 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 16:08 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the vblank pointer instead of a dev, pipe pair to simplify code.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_vblank.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 86919b1c0c2c..0ff69b06b2bd 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -1163,9 +1163,10 @@ static int __enable_vblank(struct drm_device *dev, unsigned int pipe)
> return -EINVAL;
> }
>
> -static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
> +static int drm_vblank_enable(struct drm_vblank_crtc *vblank)
> {
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> + struct drm_device *dev = vblank->dev;
> + unsigned int pipe = vblank->pipe;
> int ret = 0;
>
> assert_spin_locked(&dev->vbl_lock);
> @@ -1204,7 +1205,6 @@ static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
> int drm_vblank_get(struct drm_vblank_crtc *vblank)
> {
> struct drm_device *dev = vblank->dev;
> - int pipe = vblank->pipe;
> unsigned long irqflags;
> int ret = 0;
>
> @@ -1214,7 +1214,7 @@ int drm_vblank_get(struct drm_vblank_crtc *vblank)
> spin_lock_irqsave(&dev->vbl_lock, irqflags);
> /* Going from 0->1 means we have to enable interrupts again */
> if (atomic_add_return(1, &vblank->refcount) == 1) {
> - ret = drm_vblank_enable(dev, pipe);
> + ret = drm_vblank_enable(vblank);
> } else {
> if (!vblank->enabled) {
> atomic_dec(&vblank->refcount);
> @@ -1496,7 +1496,7 @@ void drm_crtc_vblank_on_config(struct drm_crtc *crtc,
> * user wishes vblank interrupts to be enabled all the time.
> */
> if (atomic_read(&vblank->refcount) != 0 || !vblank->config.offdelay_ms)
> - drm_WARN_ON(dev, drm_vblank_enable(dev, pipe));
> + drm_WARN_ON(dev, drm_vblank_enable(vblank));
> spin_unlock_irq(&dev->vbl_lock);
> }
> EXPORT_SYMBOL(drm_crtc_vblank_on_config);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 17/24] drm/vblank: merge drm_vblank_restore() into drm_crtc_vblank_restore()
2025-11-10 16:17 ` [PATCH 17/24] drm/vblank: merge drm_vblank_restore() into drm_crtc_vblank_restore() Jani Nikula
@ 2025-11-12 16:10 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 16:10 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> The extra function serves no useful purpose.
>
> This allows us to drop another superfluous pipe check warning.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_vblank.c | 57 +++++++++++++++---------------------
> 1 file changed, 23 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 0ff69b06b2bd..64cd96207ad5 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -1524,23 +1524,41 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc)
> }
> EXPORT_SYMBOL(drm_crtc_vblank_on);
>
> -static void drm_vblank_restore(struct drm_device *dev, unsigned int pipe)
> +/**
> + * drm_crtc_vblank_restore - estimate missed vblanks and update vblank count.
> + * @crtc: CRTC in question
> + *
> + * Power manamement features can cause frame counter resets between vblank
> + * disable and enable. Drivers can use this function in their
> + * &drm_crtc_funcs.enable_vblank implementation to estimate missed vblanks since
> + * the last &drm_crtc_funcs.disable_vblank using timestamps and update the
> + * vblank counter.
> + *
> + * Note that drivers must have race-free high-precision timestamping support,
> + * i.e. &drm_crtc_funcs.get_vblank_timestamp must be hooked up and
> + * &drm_vblank_crtc_config.disable_immediate must be set to indicate the
> + * time-stamping functions are race-free against vblank hardware counter
> + * increments.
> + */
> +void drm_crtc_vblank_restore(struct drm_crtc *crtc)
> {
> + struct drm_device *dev = crtc->dev;
> + unsigned int pipe = drm_crtc_index(crtc);
> + struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
> ktime_t t_vblank;
> - struct drm_vblank_crtc *vblank;
> int framedur_ns;
> u64 diff_ns;
> u32 cur_vblank, diff = 1;
> int count = DRM_TIMESTAMP_MAXRETRIES;
> u32 max_vblank_count = drm_max_vblank_count(dev, pipe);
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return;
> + drm_WARN_ON_ONCE(dev, !crtc->funcs->get_vblank_timestamp);
> + drm_WARN_ON_ONCE(dev, vblank->inmodeset);
> + drm_WARN_ON_ONCE(dev, !vblank->config.disable_immediate);
>
> assert_spin_locked(&dev->vbl_lock);
> assert_spin_locked(&dev->vblank_time_lock);
>
> - vblank = drm_vblank_crtc(dev, pipe);
> drm_WARN_ONCE(dev,
> drm_debug_enabled(DRM_UT_VBL) && !vblank->framedur_ns,
> "Cannot compute missed vblanks without frame duration\n");
> @@ -1561,35 +1579,6 @@ static void drm_vblank_restore(struct drm_device *dev, unsigned int pipe)
> diff, diff_ns, framedur_ns, cur_vblank - vblank->last);
> vblank->last = (cur_vblank - diff) & max_vblank_count;
> }
> -
> -/**
> - * drm_crtc_vblank_restore - estimate missed vblanks and update vblank count.
> - * @crtc: CRTC in question
> - *
> - * Power manamement features can cause frame counter resets between vblank
> - * disable and enable. Drivers can use this function in their
> - * &drm_crtc_funcs.enable_vblank implementation to estimate missed vblanks since
> - * the last &drm_crtc_funcs.disable_vblank using timestamps and update the
> - * vblank counter.
> - *
> - * Note that drivers must have race-free high-precision timestamping support,
> - * i.e. &drm_crtc_funcs.get_vblank_timestamp must be hooked up and
> - * &drm_vblank_crtc_config.disable_immediate must be set to indicate the
> - * time-stamping functions are race-free against vblank hardware counter
> - * increments.
> - */
> -void drm_crtc_vblank_restore(struct drm_crtc *crtc)
> -{
> - struct drm_device *dev = crtc->dev;
> - unsigned int pipe = drm_crtc_index(crtc);
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> -
> - drm_WARN_ON_ONCE(dev, !crtc->funcs->get_vblank_timestamp);
> - drm_WARN_ON_ONCE(dev, vblank->inmodeset);
> - drm_WARN_ON_ONCE(dev, !vblank->config.disable_immediate);
> -
> - drm_vblank_restore(dev, pipe);
> -}
> EXPORT_SYMBOL(drm_crtc_vblank_restore);
>
> static int drm_queue_vblank_event(struct drm_vblank_crtc *vblank,
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 18/24] drm/vblank: add drm_crtc_from_vblank() helper
2025-11-10 16:17 ` [PATCH 18/24] drm/vblank: add drm_crtc_from_vblank() helper Jani Nikula
@ 2025-11-12 16:38 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 16:38 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> We have a handful of places where we need to get the crtc from the
> vblank. Add a small helper for it.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Maybe not strictly necessary.
> ---
> drivers/gpu/drm/drm_vblank.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 64cd96207ad5..34d0b6939d52 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -188,6 +188,11 @@ drm_crtc_vblank_crtc(struct drm_crtc *crtc)
> }
> EXPORT_SYMBOL(drm_crtc_vblank_crtc);
>
> +static struct drm_crtc *drm_crtc_from_vblank(struct drm_vblank_crtc *vblank)
> +{
> + return drm_crtc_from_index(vblank->dev, vblank->pipe);
> +}
> +
> static void store_vblank(struct drm_vblank_crtc *vblank,
> u32 vblank_count_inc,
> ktime_t t_vblank, u32 last)
> @@ -1605,7 +1610,7 @@ static int drm_queue_vblank_event(struct drm_vblank_crtc *vblank,
> e->event.vbl.user_data = vblwait->request.signal;
> e->event.vbl.crtc_id = 0;
> if (drm_core_check_feature(dev, DRIVER_MODESET)) {
> - struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
> + struct drm_crtc *crtc = drm_crtc_from_vblank(vblank);
>
> if (crtc)
> e->event.vbl.crtc_id = crtc->base.id;
> @@ -1855,7 +1860,7 @@ static void drm_handle_vblank_events(struct drm_vblank_crtc *vblank)
> {
> struct drm_device *dev = vblank->dev;
> unsigned int pipe = vblank->pipe;
> - struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
> + struct drm_crtc *crtc = drm_crtc_from_vblank(vblank);
> bool high_prec = false;
> struct drm_pending_vblank_event *e, *t;
> ktime_t now;
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 19/24] drm/vblank: pass vblank to __get_vblank_counter() and drm_max_vblank_count()
2025-11-10 16:17 ` [PATCH 19/24] drm/vblank: pass vblank to __get_vblank_counter() and drm_max_vblank_count() Jani Nikula
@ 2025-11-12 16:40 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 16:40 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the vblank pointer instead of a dev, pipe pair to simplify code.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_vblank.c | 34 +++++++++++++++++-----------------
> 1 file changed, 17 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 34d0b6939d52..955cea949d3d 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -209,27 +209,27 @@ static void store_vblank(struct drm_vblank_crtc *vblank,
> write_sequnlock(&vblank->seqlock);
> }
>
> -static u32 drm_max_vblank_count(struct drm_device *dev, unsigned int pipe)
> +static u32 drm_max_vblank_count(struct drm_vblank_crtc *vblank)
> {
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> -
> - return vblank->max_vblank_count ?: dev->max_vblank_count;
> + return vblank->max_vblank_count ?: vblank->dev->max_vblank_count;
> }
>
> /*
> * "No hw counter" fallback implementation of .get_vblank_counter() hook,
> * if there is no usable hardware frame counter available.
> */
> -static u32 drm_vblank_no_hw_counter(struct drm_device *dev, unsigned int pipe)
> +static u32 drm_vblank_no_hw_counter(struct drm_vblank_crtc *vblank)
> {
> - drm_WARN_ON_ONCE(dev, drm_max_vblank_count(dev, pipe) != 0);
> + drm_WARN_ON_ONCE(vblank->dev, drm_max_vblank_count(vblank) != 0);
> return 0;
> }
>
> -static u32 __get_vblank_counter(struct drm_device *dev, unsigned int pipe)
> +static u32 __get_vblank_counter(struct drm_vblank_crtc *vblank)
> {
> + struct drm_device *dev = vblank->dev;
> +
> if (drm_core_check_feature(dev, DRIVER_MODESET)) {
> - struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
> + struct drm_crtc *crtc = drm_crtc_from_vblank(vblank);
>
> if (drm_WARN_ON(dev, !crtc))
> return 0;
> @@ -238,7 +238,7 @@ static u32 __get_vblank_counter(struct drm_device *dev, unsigned int pipe)
> return crtc->funcs->get_vblank_counter(crtc);
> }
>
> - return drm_vblank_no_hw_counter(dev, pipe);
> + return drm_vblank_no_hw_counter(vblank);
> }
>
> /*
> @@ -266,9 +266,9 @@ static void drm_reset_vblank_timestamp(struct drm_vblank_crtc *vblank)
> * when drm_vblank_enable() applies the diff
> */
> do {
> - cur_vblank = __get_vblank_counter(dev, pipe);
> + cur_vblank = __get_vblank_counter(vblank);
> rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false);
> - } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
> + } while (cur_vblank != __get_vblank_counter(vblank) && --count > 0);
>
> /*
> * Only reinitialize corresponding vblank timestamp if high-precision query
> @@ -309,7 +309,7 @@ static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
> ktime_t t_vblank;
> int count = DRM_TIMESTAMP_MAXRETRIES;
> int framedur_ns = vblank->framedur_ns;
> - u32 max_vblank_count = drm_max_vblank_count(dev, pipe);
> + u32 max_vblank_count = drm_max_vblank_count(vblank);
>
> /*
> * Interrupts were disabled prior to this call, so deal with counter
> @@ -324,9 +324,9 @@ static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
> * corresponding vblank timestamp.
> */
> do {
> - cur_vblank = __get_vblank_counter(dev, pipe);
> + cur_vblank = __get_vblank_counter(vblank);
> rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, in_vblank_irq);
> - } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
> + } while (cur_vblank != __get_vblank_counter(vblank) && --count > 0);
>
> if (max_vblank_count) {
> /* trust the hw counter when it's around */
> @@ -1555,7 +1555,7 @@ void drm_crtc_vblank_restore(struct drm_crtc *crtc)
> u64 diff_ns;
> u32 cur_vblank, diff = 1;
> int count = DRM_TIMESTAMP_MAXRETRIES;
> - u32 max_vblank_count = drm_max_vblank_count(dev, pipe);
> + u32 max_vblank_count = drm_max_vblank_count(vblank);
>
> drm_WARN_ON_ONCE(dev, !crtc->funcs->get_vblank_timestamp);
> drm_WARN_ON_ONCE(dev, vblank->inmodeset);
> @@ -1570,9 +1570,9 @@ void drm_crtc_vblank_restore(struct drm_crtc *crtc)
> framedur_ns = vblank->framedur_ns;
>
> do {
> - cur_vblank = __get_vblank_counter(dev, pipe);
> + cur_vblank = __get_vblank_counter(vblank);
> drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false);
> - } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
> + } while (cur_vblank != __get_vblank_counter(vblank) && --count > 0);
>
> diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
> if (framedur_ns)
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 20/24] drm/vblank: pass vblank to __{enable,disable}_vblank()
2025-11-10 16:17 ` [PATCH 20/24] drm/vblank: pass vblank to __{enable,disable}_vblank() Jani Nikula
@ 2025-11-12 16:41 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 16:41 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the vblank pointer instead of a dev, pipe pair to simplify code.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_vblank.c | 16 ++++++++++------
> 1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 955cea949d3d..a274b4a7b1c2 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -443,10 +443,12 @@ u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
> }
> EXPORT_SYMBOL(drm_crtc_accurate_vblank_count);
>
> -static void __disable_vblank(struct drm_device *dev, unsigned int pipe)
> +static void __disable_vblank(struct drm_vblank_crtc *vblank)
> {
> + struct drm_device *dev = vblank->dev;
> +
> if (drm_core_check_feature(dev, DRIVER_MODESET)) {
> - struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
> + struct drm_crtc *crtc = drm_crtc_from_vblank(vblank);
>
> if (drm_WARN_ON(dev, !crtc))
> return;
> @@ -491,7 +493,7 @@ void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
> * between drm_crtc_vblank_on() and drm_crtc_vblank_off().
> */
> drm_update_vblank_count(vblank, false);
> - __disable_vblank(dev, pipe);
> + __disable_vblank(vblank);
> vblank->enabled = false;
>
> out:
> @@ -1153,10 +1155,12 @@ void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
> }
> EXPORT_SYMBOL(drm_crtc_send_vblank_event);
>
> -static int __enable_vblank(struct drm_device *dev, unsigned int pipe)
> +static int __enable_vblank(struct drm_vblank_crtc *vblank)
> {
> + struct drm_device *dev = vblank->dev;
> +
> if (drm_core_check_feature(dev, DRIVER_MODESET)) {
> - struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
> + struct drm_crtc *crtc = drm_crtc_from_vblank(vblank);
>
> if (drm_WARN_ON(dev, !crtc))
> return 0;
> @@ -1186,7 +1190,7 @@ static int drm_vblank_enable(struct drm_vblank_crtc *vblank)
> * timestamps. Filtercode in drm_handle_vblank() will
> * prevent double-accounting of same vblank interval.
> */
> - ret = __enable_vblank(dev, pipe);
> + ret = __enable_vblank(vblank);
> drm_dbg_core(dev, "enabling vblank on crtc %u, ret: %d\n",
> pipe, ret);
> if (ret) {
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 21/24] drm/vblank: pass vblank to drm_get_last_vbltimestamp()
2025-11-10 16:17 ` [PATCH 21/24] drm/vblank: pass vblank to drm_get_last_vbltimestamp() Jani Nikula
@ 2025-11-12 16:44 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 16:44 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the vblank pointer instead of a dev, pipe pair to simplify code.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_vblank.c | 20 ++++++++------------
> 1 file changed, 8 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index a274b4a7b1c2..ee9355d5069b 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -162,9 +162,8 @@
> */
> #define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
>
> -static bool
> -drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
> - ktime_t *tvblank, bool in_vblank_irq);
> +static bool drm_get_last_vbltimestamp(struct drm_vblank_crtc *vblank,
> + ktime_t *tvblank, bool in_vblank_irq);
>
> static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */
>
> @@ -253,7 +252,6 @@ static u32 __get_vblank_counter(struct drm_vblank_crtc *vblank)
> static void drm_reset_vblank_timestamp(struct drm_vblank_crtc *vblank)
> {
> struct drm_device *dev = vblank->dev;
> - unsigned int pipe = vblank->pipe;
> u32 cur_vblank;
> bool rc;
> ktime_t t_vblank;
> @@ -267,7 +265,7 @@ static void drm_reset_vblank_timestamp(struct drm_vblank_crtc *vblank)
> */
> do {
> cur_vblank = __get_vblank_counter(vblank);
> - rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false);
> + rc = drm_get_last_vbltimestamp(vblank, &t_vblank, false);
> } while (cur_vblank != __get_vblank_counter(vblank) && --count > 0);
>
> /*
> @@ -325,7 +323,7 @@ static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
> */
> do {
> cur_vblank = __get_vblank_counter(vblank);
> - rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, in_vblank_irq);
> + rc = drm_get_last_vbltimestamp(vblank, &t_vblank, in_vblank_irq);
> } while (cur_vblank != __get_vblank_counter(vblank) && --count > 0);
>
> if (max_vblank_count) {
> @@ -909,11 +907,10 @@ drm_crtc_get_last_vbltimestamp(struct drm_crtc *crtc, ktime_t *tvblank,
> return ret;
> }
>
> -static bool
> -drm_get_last_vbltimestamp(struct drm_device *dev, unsigned int pipe,
> - ktime_t *tvblank, bool in_vblank_irq)
> +static bool drm_get_last_vbltimestamp(struct drm_vblank_crtc *vblank,
> + ktime_t *tvblank, bool in_vblank_irq)
> {
> - struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe);
> + struct drm_crtc *crtc = drm_crtc_from_vblank(vblank);
>
> return drm_crtc_get_last_vbltimestamp(crtc, tvblank, in_vblank_irq);
> }
> @@ -1552,7 +1549,6 @@ EXPORT_SYMBOL(drm_crtc_vblank_on);
> void drm_crtc_vblank_restore(struct drm_crtc *crtc)
> {
> struct drm_device *dev = crtc->dev;
> - unsigned int pipe = drm_crtc_index(crtc);
> struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
> ktime_t t_vblank;
> int framedur_ns;
> @@ -1575,7 +1571,7 @@ void drm_crtc_vblank_restore(struct drm_crtc *crtc)
>
> do {
> cur_vblank = __get_vblank_counter(vblank);
> - drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false);
> + drm_get_last_vbltimestamp(vblank, &t_vblank, false);
> } while (cur_vblank != __get_vblank_counter(vblank) && --count > 0);
>
> diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 22/24] drm/vblank: pass vblank to drm_vblank_disable_and_save(), make static
2025-11-10 16:17 ` [PATCH 22/24] drm/vblank: pass vblank to drm_vblank_disable_and_save(), make static Jani Nikula
@ 2025-11-12 16:46 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 16:46 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the vblank pointer instead of a dev, pipe pair to simplify code.
>
> drm_vblank_disable_and_save() is also no longer used outside of
> drm_vblank.c; make it static while at it.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/gpu/drm/drm_internal.h | 1 -
> drivers/gpu/drm/drm_vblank.c | 8 ++++----
> 2 files changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index e9c85c3681f1..6a7b53de03a8 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -100,7 +100,6 @@ static inline bool drm_vblank_passed(u64 seq, u64 ref)
> return (seq - ref) <= (1 << 23);
> }
>
> -void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe);
> int drm_vblank_get(struct drm_vblank_crtc *vblank);
> void drm_vblank_put(struct drm_vblank_crtc *vblank);
> u64 drm_vblank_count(struct drm_vblank_crtc *vblank);
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index ee9355d5069b..44fb8d225485 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -462,9 +462,9 @@ static void __disable_vblank(struct drm_vblank_crtc *vblank)
> * are preserved, even if there are any spurious vblank irq's after
> * disable.
> */
> -void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
> +static void drm_vblank_disable_and_save(struct drm_vblank_crtc *vblank)
> {
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> + struct drm_device *dev = vblank->dev;
> unsigned long irqflags;
>
> assert_spin_locked(&dev->vbl_lock);
> @@ -509,7 +509,7 @@ static void vblank_disable_fn(struct timer_list *t)
> spin_lock_irqsave(&dev->vbl_lock, irqflags);
> if (atomic_read(&vblank->refcount) == 0 && vblank->enabled) {
> drm_dbg_core(dev, "disabling vblank on crtc %u\n", pipe);
> - drm_vblank_disable_and_save(dev, pipe);
> + drm_vblank_disable_and_save(vblank);
> }
> spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
> }
> @@ -1355,7 +1355,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
> /* Avoid redundant vblank disables without previous
> * drm_crtc_vblank_on(). */
> if (drm_core_check_feature(dev, DRIVER_ATOMIC) || !vblank->inmodeset)
> - drm_vblank_disable_and_save(dev, pipe);
> + drm_vblank_disable_and_save(vblank);
>
> wake_up(&vblank->queue);
>
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 23/24] drm/vblank: reduce pipe checks
2025-11-10 16:17 ` [PATCH 23/24] drm/vblank: reduce pipe checks Jani Nikula
2025-11-10 17:45 ` Ville Syrjälä
@ 2025-11-12 16:54 ` Thomas Zimmermann
1 sibling, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-12 16:54 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Now that drm_vblank_crtc() is the only place that indexes dev->vblank[],
> and its usage has reduced considerably, add the primary pipe
> out-of-bounds check there, and return NULL. Expect callers to check it
> and act accordingly.
>
> In drm_crtc_vblank_crtc(), warn and return NULL, and let it go boom. If
> the crtc->pipe is out of bounds, it's a driver error that needs to be
> fixed.
>
> Remove superfluous pipe checks all around.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
See my comment below.
> ---
> drivers/gpu/drm/drm_vblank.c | 36 +++++++++++++++---------------------
> 1 file changed, 15 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 44fb8d225485..7829e64e42b4 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -177,13 +177,22 @@ MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
> static struct drm_vblank_crtc *
> drm_vblank_crtc(struct drm_device *dev, unsigned int pipe)
> {
> + if (pipe >= dev->num_crtcs)
> + return NULL;
> +
> return &dev->vblank[pipe];
> }
>
> struct drm_vblank_crtc *
> drm_crtc_vblank_crtc(struct drm_crtc *crtc)
> {
> - return drm_vblank_crtc(crtc->dev, drm_crtc_index(crtc));
> + struct drm_vblank_crtc *vblank;
> +
> + vblank = drm_vblank_crtc(crtc->dev, drm_crtc_index(crtc));
> + if (drm_WARN_ON(crtc->dev, !vblank))
> + return NULL;
> +
> + return vblank;
> }
> EXPORT_SYMBOL(drm_crtc_vblank_crtc);
>
> @@ -631,7 +640,6 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
> const struct drm_display_mode *mode)
> {
> struct drm_device *dev = crtc->dev;
> - unsigned int pipe = drm_crtc_index(crtc);
> struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
> int linedur_ns = 0, framedur_ns = 0;
> int dotclock = mode->crtc_clock;
> @@ -639,9 +647,6 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
> if (!drm_dev_has_vblank(dev))
> return;
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return;
> -
> /* Valid dotclock? */
> if (dotclock > 0) {
> int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
> @@ -724,11 +729,6 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
> int vpos, hpos, i;
> int delta_ns, duration_ns;
>
> - if (pipe >= dev->num_crtcs) {
> - drm_err(dev, "Invalid crtc %u\n", pipe);
> - return false;
> - }
> -
> /* Scanout position query not supported? Should not happen. */
> if (!get_scanout_position) {
> drm_err(dev, "Called from CRTC w/o get_scanout_position()!?\n");
> @@ -1339,9 +1339,6 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
> ktime_t now;
> u64 seq;
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return;
> -
> /*
> * Grab event_lock early to prevent vblank work from being scheduled
> * while we're in the middle of shutting down vblank interrupts
> @@ -1480,9 +1477,6 @@ void drm_crtc_vblank_on_config(struct drm_crtc *crtc,
> unsigned int pipe = drm_crtc_index(crtc);
> struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> - return;
> -
> spin_lock_irq(&dev->vbl_lock);
> drm_dbg_vbl(dev, "crtc %d, vblank enabled %d, inmodeset %d\n",
> pipe, vblank->enabled, vblank->inmodeset);
> @@ -1764,10 +1758,9 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> pipe = pipe_index;
> }
>
> - if (pipe >= dev->num_crtcs)
> - return -EINVAL;
> -
> vblank = drm_vblank_crtc(dev, pipe);
> + if (!vblank)
> + return -EINVAL;
>
> /* If the counter is currently enabled and accurate, short-circuit
> * queries to return the cached timestamp of the last vblank.
> @@ -1902,14 +1895,15 @@ static void drm_handle_vblank_events(struct drm_vblank_crtc *vblank)
> */
> bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
> {
> - struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
> + struct drm_vblank_crtc *vblank;
> unsigned long irqflags;
> bool disable_irq;
>
> if (drm_WARN_ON_ONCE(dev, !drm_dev_has_vblank(dev)))
> return false;
>
> - if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
> + vblank = drm_vblank_crtc(dev, pipe);
> + if (drm_WARN_ON(dev, !vblank))
> return false;
This can happen on each interrupt. Rather use drm_WARN_ON_ONCE here.
>
> spin_lock_irqsave(&dev->event_lock, irqflags);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 24/24] drm/vblank: clean up debug logging
2025-11-10 16:17 ` [PATCH 24/24] drm/vblank: clean up debug logging Jani Nikula
@ 2025-11-13 14:05 ` Thomas Zimmermann
0 siblings, 0 replies; 59+ messages in thread
From: Thomas Zimmermann @ 2025-11-13 14:05 UTC (permalink / raw)
To: Jani Nikula, dri-devel; +Cc: intel-gfx, intel-xe, ville.syrjala
Hi
Am 10.11.25 um 17:17 schrieb Jani Nikula:
> Use the usual [CRTC:%d:%s] when crtc is available. Start using a new
> uniform [VBLANK:%u] prefix with the pipe when crtc is not
> available. Remove extra line breaks. Use string choice helpers here and
> there. Use %pe to decode error returns.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Given Ville's comment on decoupling pipes and CRTCs, would it make sense
to prefer [VBLANK] over [CRTC]? This seems to be possible with some of
these changes.
Best regards
Thomas
> ---
> drivers/gpu/drm/drm_vblank.c | 109 ++++++++++++++++-------------------
> 1 file changed, 50 insertions(+), 59 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
> index 7829e64e42b4..5ee132b3a6b5 100644
> --- a/drivers/gpu/drm/drm_vblank.c
> +++ b/drivers/gpu/drm/drm_vblank.c
> @@ -27,6 +27,7 @@
> #include <linux/export.h>
> #include <linux/kthread.h>
> #include <linux/moduleparam.h>
> +#include <linux/string_choices.h>
>
> #include <drm/drm_crtc.h>
> #include <drm/drm_drv.h>
> @@ -347,14 +348,13 @@ static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
> * frame/field duration.
> */
>
> - drm_dbg_vbl(dev, "crtc %u: Calculating number of vblanks."
> - " diff_ns = %lld, framedur_ns = %d)\n",
> + drm_dbg_vbl(dev, "[VBLANK:%u] Calculating number of vblanks. diff_ns = %lld, framedur_ns = %d)\n",
> pipe, (long long)diff_ns, framedur_ns);
>
> diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
>
> if (diff == 0 && in_vblank_irq)
> - drm_dbg_vbl(dev, "crtc %u: Redundant vblirq ignored\n",
> + drm_dbg_vbl(dev, "[VBLANK:%u] Redundant vblirq ignored\n",
> pipe);
> } else {
> /* some kind of default for drivers w/o accurate vbl timestamping */
> @@ -372,13 +372,12 @@ static void drm_update_vblank_count(struct drm_vblank_crtc *vblank,
> */
> if (diff > 1 && (vblank->inmodeset & 0x2)) {
> drm_dbg_vbl(dev,
> - "clamping vblank bump to 1 on crtc %u: diffr=%u"
> - " due to pre-modeset.\n", pipe, diff);
> + "[VBLANK:%u] clamping vblank bump to 1: diffr=%u due to pre-modeset.\n",
> + pipe, diff);
> diff = 1;
> }
>
> - drm_dbg_vbl(dev, "updating vblank count on crtc %u:"
> - " current=%llu, diff=%u, hw=%u hw_last=%u\n",
> + drm_dbg_vbl(dev, "[VBLANK:%u] updating vblank count: current=%llu, diff=%u, hw=%u hw_last=%u\n",
> pipe, (unsigned long long)atomic64_read(&vblank->count),
> diff, cur_vblank, vblank->last);
>
> @@ -517,7 +516,7 @@ static void vblank_disable_fn(struct timer_list *t)
>
> spin_lock_irqsave(&dev->vbl_lock, irqflags);
> if (atomic_read(&vblank->refcount) == 0 && vblank->enabled) {
> - drm_dbg_core(dev, "disabling vblank on crtc %u\n", pipe);
> + drm_dbg_core(dev, "[VBLANK:%u] disabling vblank\n", pipe);
> drm_vblank_disable_and_save(vblank);
> }
> spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
> @@ -665,8 +664,8 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
> if (mode->flags & DRM_MODE_FLAG_INTERLACE)
> framedur_ns /= 2;
> } else {
> - drm_err(dev, "crtc %u: Can't calculate constants, dotclock = 0!\n",
> - crtc->base.id);
> + drm_err(dev, "[CRTC:%d:%s] Can't calculate constants, dotclock = 0!\n",
> + crtc->base.id, crtc->name);
> }
>
> vblank->linedur_ns = linedur_ns;
> @@ -674,11 +673,11 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
> drm_mode_copy(&vblank->hwmode, mode);
>
> drm_dbg_core(dev,
> - "crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
> - crtc->base.id, mode->crtc_htotal,
> + "[CRTC:%d:%s] hwmode: htotal %d, vtotal %d, vdisplay %d\n",
> + crtc->base.id, crtc->name, mode->crtc_htotal,
> mode->crtc_vtotal, mode->crtc_vdisplay);
> - drm_dbg_core(dev, "crtc %u: clock %d kHz framedur %d linedur %d\n",
> - crtc->base.id, dotclock, framedur_ns, linedur_ns);
> + drm_dbg_core(dev, "[CRTC:%d:%s] clock %d kHz framedur %d linedur %d\n",
> + crtc->base.id, crtc->name, dotclock, framedur_ns, linedur_ns);
> }
> EXPORT_SYMBOL(drm_calc_timestamping_constants);
>
> @@ -731,7 +730,8 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
>
> /* Scanout position query not supported? Should not happen. */
> if (!get_scanout_position) {
> - drm_err(dev, "Called from CRTC w/o get_scanout_position()!?\n");
> + drm_err(dev, "[CRTC:%d:%s] Called from CRTC w/o get_scanout_position()!?\n",
> + crtc->base.id, crtc->name);
> return false;
> }
>
> @@ -744,7 +744,7 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
> * Happens during initial modesetting of a crtc.
> */
> if (mode->crtc_clock == 0) {
> - drm_dbg_core(dev, "crtc %u: Noop due to uninitialized mode.\n",
> + drm_dbg_core(dev, "[VBLANK:%u] Noop due to uninitialized mode.\n",
> pipe);
> drm_WARN_ON_ONCE(dev, drm_drv_uses_atomic_modeset(dev));
> return false;
> @@ -769,9 +769,8 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
>
> /* Return as no-op if scanout query unsupported or failed. */
> if (!vbl_status) {
> - drm_dbg_core(dev,
> - "crtc %u : scanoutpos query failed.\n",
> - pipe);
> + drm_dbg_core(dev, "[CRTC:%d:%s] scanoutpos query failed.\n",
> + crtc->base.id, crtc->name);
> return false;
> }
>
> @@ -785,9 +784,8 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
>
> /* Noisy system timing? */
> if (i == DRM_TIMESTAMP_MAXRETRIES) {
> - drm_dbg_core(dev,
> - "crtc %u: Noisy timestamp %d us > %d us [%d reps].\n",
> - pipe, duration_ns / 1000, *max_error / 1000, i);
> + drm_dbg_core(dev, "[CRTC:%d:%s] Noisy timestamp %d us > %d us [%d reps].\n",
> + crtc->base.id, crtc->name, duration_ns / 1000, *max_error / 1000, i);
> }
>
> /* Return upper bound of timestamp precision error. */
> @@ -811,9 +809,8 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal(
> ts_etime = ktime_to_timespec64(etime);
> ts_vblank_time = ktime_to_timespec64(*vblank_time);
>
> - drm_dbg_vbl(dev,
> - "crtc %u : v p(%d,%d)@ %lld.%06ld -> %lld.%06ld [e %d us, %d rep]\n",
> - pipe, hpos, vpos,
> + drm_dbg_vbl(dev, "[CRTC:%d:%s] v p(%d,%d)@ %lld.%06ld -> %lld.%06ld [e %d us, %d rep]\n",
> + crtc->base.id, crtc->name, hpos, vpos,
> (u64)ts_etime.tv_sec, ts_etime.tv_nsec / 1000,
> (u64)ts_vblank_time.tv_sec, ts_vblank_time.tv_nsec / 1000,
> duration_ns / 1000, i);
> @@ -1188,7 +1185,7 @@ static int drm_vblank_enable(struct drm_vblank_crtc *vblank)
> * prevent double-accounting of same vblank interval.
> */
> ret = __enable_vblank(vblank);
> - drm_dbg_core(dev, "enabling vblank on crtc %u, ret: %d\n",
> + drm_dbg_core(dev, "[VBLANK:%u] enabling vblank, ret: %d\n",
> pipe, ret);
> if (ret) {
> atomic_dec(&vblank->refcount);
> @@ -1346,8 +1343,9 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
> spin_lock_irq(&dev->event_lock);
>
> spin_lock(&dev->vbl_lock);
> - drm_dbg_vbl(dev, "crtc %d, vblank enabled %d, inmodeset %d\n",
> - pipe, vblank->enabled, vblank->inmodeset);
> + drm_dbg_vbl(dev, "[CRTC:%d:%s] vblank %s, inmodeset: %s\n",
> + crtc->base.id, crtc->name, str_enabled_disabled(vblank->enabled),
> + str_yes_no(vblank->inmodeset));
>
> /* Avoid redundant vblank disables without previous
> * drm_crtc_vblank_on(). */
> @@ -1372,9 +1370,8 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
> list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
> if (e->pipe != pipe)
> continue;
> - drm_dbg_core(dev, "Sending premature vblank event on disable: "
> - "wanted %llu, current %llu\n",
> - e->sequence, seq);
> + drm_dbg_core(dev, "[CRTC:%d:%s] Sending premature vblank event on disable: wanted %llu, current %llu\n",
> + crtc->base.id, crtc->name, e->sequence, seq);
> list_del(&e->base.link);
> drm_vblank_put(vblank);
> send_vblank_event(dev, e, seq, now);
> @@ -1474,12 +1471,12 @@ void drm_crtc_vblank_on_config(struct drm_crtc *crtc,
> const struct drm_vblank_crtc_config *config)
> {
> struct drm_device *dev = crtc->dev;
> - unsigned int pipe = drm_crtc_index(crtc);
> struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
>
> spin_lock_irq(&dev->vbl_lock);
> - drm_dbg_vbl(dev, "crtc %d, vblank enabled %d, inmodeset %d\n",
> - pipe, vblank->enabled, vblank->inmodeset);
> + drm_dbg_vbl(dev, "[CRTC:%d:%s] vblank %s, inmodeset: %s\n",
> + crtc->base.id, crtc->name, str_enabled_disabled(vblank->enabled),
> + str_yes_no(vblank->inmodeset));
>
> vblank->config = *config;
>
> @@ -1573,8 +1570,8 @@ void drm_crtc_vblank_restore(struct drm_crtc *crtc)
> diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
>
>
> - drm_dbg_vbl(dev,
> - "missed %d vblanks in %lld ns, frame duration=%d ns, hw_diff=%d\n",
> + drm_dbg_vbl(dev, "[CRTC:%d:%s] missed %d vblanks in %lld ns, frame duration=%d ns, hw_diff=%d\n",
> + crtc->base.id, crtc->name,
> diff, diff_ns, framedur_ns, cur_vblank - vblank->last);
> vblank->last = (cur_vblank - diff) & max_vblank_count;
> }
> @@ -1631,8 +1628,8 @@ static int drm_queue_vblank_event(struct drm_vblank_crtc *vblank,
>
> seq = drm_vblank_count_and_time(vblank, &now);
>
> - drm_dbg_core(dev, "event on vblank count %llu, current %llu, crtc %u\n",
> - req_seq, seq, pipe);
> + drm_dbg_core(dev, "[VBLANK:%u] event on vblank count %llu, current %llu\n",
> + pipe, req_seq, seq);
>
> trace_drm_vblank_event_queued(file_priv, pipe, req_seq);
>
> @@ -1728,8 +1725,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> if (vblwait->request.type &
> ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK |
> _DRM_VBLANK_HIGH_CRTC_MASK)) {
> - drm_dbg_core(dev,
> - "Unsupported type value 0x%x, supported mask 0x%x\n",
> + drm_dbg_core(dev, "Unsupported type value 0x%x, supported mask 0x%x\n",
> vblwait->request.type,
> (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK |
> _DRM_VBLANK_HIGH_CRTC_MASK));
> @@ -1774,9 +1770,8 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
>
> ret = drm_vblank_get(vblank);
> if (ret) {
> - drm_dbg_core(dev,
> - "crtc %d failed to acquire vblank counter, %d\n",
> - pipe, ret);
> + drm_dbg_core(dev, "[VBLANK:%u] failed to acquire vblank counter %pe\n",
> + pipe, ERR_PTR(ret));
> return ret;
> }
> seq = drm_vblank_count(vblank);
> @@ -1812,8 +1807,8 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> if (req_seq != seq) {
> int wait;
>
> - drm_dbg_core(dev, "waiting on vblank count %llu, crtc %u\n",
> - req_seq, pipe);
> + drm_dbg_core(dev, "[VBLANK:%d] waiting on vblank count %llu\n",
> + pipe, req_seq);
> wait = wait_event_interruptible_timeout(vblank->queue,
> drm_vblank_passed(drm_vblank_count(vblank), req_seq) ||
> !READ_ONCE(vblank->enabled),
> @@ -1837,10 +1832,10 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data,
> if (ret != -EINTR) {
> drm_wait_vblank_reply(vblank, &vblwait->reply);
>
> - drm_dbg_core(dev, "crtc %d returning %u to client\n",
> + drm_dbg_core(dev, "[VBLANK:%u] returning %u to client\n",
> pipe, vblwait->reply.sequence);
> } else {
> - drm_dbg_core(dev, "crtc %d vblank wait interrupted by signal\n",
> + drm_dbg_core(dev, "[VBLANK:%u] vblank wait interrupted by signal\n",
> pipe);
> }
>
> @@ -1869,8 +1864,8 @@ static void drm_handle_vblank_events(struct drm_vblank_crtc *vblank)
> if (!drm_vblank_passed(seq, e->sequence))
> continue;
>
> - drm_dbg_core(dev, "vblank event on %llu, current %llu\n",
> - e->sequence, seq);
> + drm_dbg_core(dev, "[VBLANK:%u] vblank event on %llu, current %llu\n",
> + pipe, e->sequence, seq);
>
> list_del(&e->base.link);
> drm_vblank_put(vblank);
> @@ -1987,7 +1982,6 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data,
> {
> struct drm_crtc *crtc;
> struct drm_vblank_crtc *vblank;
> - int pipe;
> struct drm_crtc_get_sequence *get_seq = data;
> ktime_t now;
> bool vblank_enabled;
> @@ -2003,8 +1997,6 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data,
> if (!crtc)
> return -ENOENT;
>
> - pipe = drm_crtc_index(crtc);
> -
> vblank = drm_crtc_vblank_crtc(crtc);
> vblank_enabled = READ_ONCE(vblank->config.disable_immediate) &&
> READ_ONCE(vblank->enabled);
> @@ -2012,9 +2004,8 @@ int drm_crtc_get_sequence_ioctl(struct drm_device *dev, void *data,
> if (!vblank_enabled) {
> ret = drm_crtc_vblank_get(crtc);
> if (ret) {
> - drm_dbg_core(dev,
> - "crtc %d failed to acquire vblank counter, %d\n",
> - pipe, ret);
> + drm_dbg_core(dev, "[CRTC:%d:%s] failed to acquire vblank counter %pe\n",
> + crtc->base.id, crtc->name, ERR_PTR(ret));
> return ret;
> }
> }
> @@ -2079,9 +2070,8 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data,
>
> ret = drm_crtc_vblank_get(crtc);
> if (ret) {
> - drm_dbg_core(dev,
> - "crtc %d failed to acquire vblank counter, %d\n",
> - pipe, ret);
> + drm_dbg_core(dev, "[CRTC:%d:%s] failed to acquire vblank counter %pe\n",
> + crtc->base.id, crtc->name, ERR_PTR(ret));
> goto err_free;
> }
>
> @@ -2166,7 +2156,8 @@ static enum hrtimer_restart drm_vblank_timer_function(struct hrtimer *timer)
>
> ret_overrun = hrtimer_forward_now(&vtimer->timer, interval);
> if (ret_overrun != 1)
> - drm_dbg_vbl(dev, "vblank timer overrun\n");
> + drm_dbg_vbl(dev, "[CRTC:%d:%s] vblank timer overrun\n",
> + crtc->base.id, crtc->name);
>
> if (crtc_funcs->handle_vblank_timeout)
> succ = crtc_funcs->handle_vblank_timeout(crtc);
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply [flat|nested] 59+ messages in thread
end of thread, other threads:[~2025-11-13 14:06 UTC | newest]
Thread overview: 59+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-10 16:17 [PATCH 00/24] drm/vblank: refactoring and cleanups Jani Nikula
2025-11-10 16:17 ` [PATCH 01/24] drm/vblank: Unexport drm_wait_one_vblank() Jani Nikula
2025-11-11 8:14 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 02/24] drm/vblank: remove drm_wait_one_vblank() completely Jani Nikula
2025-11-11 8:17 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 03/24] drm/vblank: remove superfluous pipe check Jani Nikula
2025-11-11 8:18 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 04/24] drm/vblank: add return value to drm_crtc_wait_one_vblank() Jani Nikula
2025-11-10 16:17 ` [PATCH 05/24] drm/vblank: use the drm_vblank_crtc() and drm_crtc_vblank_crtc() helpers more Jani Nikula
2025-11-11 8:23 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 06/24] drm/vblank: prefer drm_crtc_vblank_crtc() over drm_vblank_crtc() Jani Nikula
2025-11-11 8:26 ` Thomas Zimmermann
2025-11-11 8:43 ` Jani Nikula
2025-11-11 16:00 ` Ville Syrjälä
2025-11-12 8:26 ` Jani Nikula
2025-11-12 11:56 ` Ville Syrjälä
2025-11-12 15:50 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 07/24] drm/vblank: pass vlank to drm_vblank_get()/_put()/_count() Jani Nikula
2025-11-11 8:32 ` Thomas Zimmermann
2025-11-11 8:53 ` Jani Nikula
2025-11-11 9:04 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 08/24] drm/vblank: pass vblank to drm_update_vblank_count() Jani Nikula
2025-11-12 15:54 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 09/24] drm/vblank: pass vblank to drm_handle_vblank_events() Jani Nikula
2025-11-12 15:56 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 10/24] drm/vblank: use the vblank based interfaces more Jani Nikula
2025-11-12 15:56 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 11/24] drm/vblank: pass vblank to drm_queue_vblank_event() Jani Nikula
2025-11-12 15:57 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 12/24] drm/vblank: pass vblank to drm_wait_vblank_reply() Jani Nikula
2025-11-12 16:01 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 13/24] drm/vblank: pass vblank to drm_vblank_count_and_time() Jani Nikula
2025-11-11 6:52 ` kernel test robot
2025-11-12 16:03 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 14/24] drm/vblank: pass vblank to drm_reset_vblank_timestamp() Jani Nikula
2025-11-12 16:07 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 15/24] drm/vblank: pass vblank to store_vblank() Jani Nikula
2025-11-12 16:08 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 16/24] drm/vblank: pass vblank to drm_vblank_enable() Jani Nikula
2025-11-12 16:08 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 17/24] drm/vblank: merge drm_vblank_restore() into drm_crtc_vblank_restore() Jani Nikula
2025-11-12 16:10 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 18/24] drm/vblank: add drm_crtc_from_vblank() helper Jani Nikula
2025-11-12 16:38 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 19/24] drm/vblank: pass vblank to __get_vblank_counter() and drm_max_vblank_count() Jani Nikula
2025-11-12 16:40 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 20/24] drm/vblank: pass vblank to __{enable,disable}_vblank() Jani Nikula
2025-11-12 16:41 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 21/24] drm/vblank: pass vblank to drm_get_last_vbltimestamp() Jani Nikula
2025-11-12 16:44 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 22/24] drm/vblank: pass vblank to drm_vblank_disable_and_save(), make static Jani Nikula
2025-11-12 16:46 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 23/24] drm/vblank: reduce pipe checks Jani Nikula
2025-11-10 17:45 ` Ville Syrjälä
2025-11-11 8:56 ` Jani Nikula
2025-11-12 16:54 ` Thomas Zimmermann
2025-11-10 16:17 ` [PATCH 24/24] drm/vblank: clean up debug logging Jani Nikula
2025-11-13 14:05 ` Thomas Zimmermann
2025-11-10 17:12 ` ✗ CI.KUnit: failure for drm/vblank: refactoring and cleanups Patchwork
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).