Message ID | 20240522053341.137592-2-maarten.lankhorst@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Fix cursor FB unpinning. | expand |
> -----Original Message----- > From: Intel-xe <intel-xe-bounces@lists.freedesktop.org> On Behalf Of Maarten > Lankhorst > Sent: Wednesday, May 22, 2024 11:04 AM > To: intel-gfx@lists.freedesktop.org > Cc: intel-xe@lists.freedesktop.org; Maarten Lankhorst > <maarten.lankhorst@linux.intel.com>; Borah, Chaitanya Kumar > <chaitanya.kumar.borah@intel.com> > Subject: [v6 1/3] drm: Add drm_vblank_work_flush_all(). Nit: Drop the "." from patch header > In some cases we want to flush all vblank work, right before vblank_off for > example. Add a simple function to make this possible. > > Check that both pending_work and running work are empty when flushing. Have been closely following the developments and approaches. This version looks good to me. Reviewed-by: Uma Shankar <uma.shankar@intel.com> > Co-Developed-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> > --- > drivers/gpu/drm/drm_vblank_work.c | 22 ++++++++++++++++++++++ > include/drm/drm_vblank_work.h | 2 ++ > 2 files changed, 24 insertions(+) > > diff --git a/drivers/gpu/drm/drm_vblank_work.c > b/drivers/gpu/drm/drm_vblank_work.c > index 4fe9b1d3b00f..1752ffb44e1d 100644 > --- a/drivers/gpu/drm/drm_vblank_work.c > +++ b/drivers/gpu/drm/drm_vblank_work.c > @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work > *work) } EXPORT_SYMBOL(drm_vblank_work_flush); > > +/** > + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. > + * @crtc: crtc for which vblank work to flush > + * > + * Wait until all currently queued vblank work on @crtc > + * has finished executing once. > + */ > +void drm_vblank_work_flush_all(struct drm_crtc *crtc) { > + struct drm_device *dev = crtc->dev; > + struct drm_vblank_crtc *vblank = &dev->vblank[drm_crtc_index(crtc)]; > + > + spin_lock_irq(&dev->event_lock); > + wait_event_lock_irq(vblank->work_wait_queue, > + list_empty(&vblank->pending_work), > + dev->event_lock); > + spin_unlock_irq(&dev->event_lock); > + > + kthread_flush_worker(vblank->worker); > +} > +EXPORT_SYMBOL(drm_vblank_work_flush_all); > + > /** > * drm_vblank_work_init - initialize a vblank work item > * @work: vblank work item > diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h > index eb41d0810c4f..e04d436b7297 100644 > --- a/include/drm/drm_vblank_work.h > +++ b/include/drm/drm_vblank_work.h > @@ -17,6 +17,7 @@ struct drm_crtc; > * drm_vblank_work_init() > * drm_vblank_work_cancel_sync() > * drm_vblank_work_flush() > + * drm_vblank_work_flush_all() > */ > struct drm_vblank_work { > /** > @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, > struct drm_crtc *crtc, > void (*func)(struct kthread_work *work)); bool > drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void > drm_vblank_work_flush(struct drm_vblank_work *work); > +void drm_vblank_work_flush_all(struct drm_crtc *crtc); > > #endif /* !_DRM_VBLANK_WORK_H_ */ > -- > 2.43.0
diff --git a/drivers/gpu/drm/drm_vblank_work.c b/drivers/gpu/drm/drm_vblank_work.c index 4fe9b1d3b00f..1752ffb44e1d 100644 --- a/drivers/gpu/drm/drm_vblank_work.c +++ b/drivers/gpu/drm/drm_vblank_work.c @@ -232,6 +232,28 @@ void drm_vblank_work_flush(struct drm_vblank_work *work) } EXPORT_SYMBOL(drm_vblank_work_flush); +/** + * drm_vblank_work_flush_all - flush all currently pending vblank work on crtc. + * @crtc: crtc for which vblank work to flush + * + * Wait until all currently queued vblank work on @crtc + * has finished executing once. + */ +void drm_vblank_work_flush_all(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_vblank_crtc *vblank = &dev->vblank[drm_crtc_index(crtc)]; + + spin_lock_irq(&dev->event_lock); + wait_event_lock_irq(vblank->work_wait_queue, + list_empty(&vblank->pending_work), + dev->event_lock); + spin_unlock_irq(&dev->event_lock); + + kthread_flush_worker(vblank->worker); +} +EXPORT_SYMBOL(drm_vblank_work_flush_all); + /** * drm_vblank_work_init - initialize a vblank work item * @work: vblank work item diff --git a/include/drm/drm_vblank_work.h b/include/drm/drm_vblank_work.h index eb41d0810c4f..e04d436b7297 100644 --- a/include/drm/drm_vblank_work.h +++ b/include/drm/drm_vblank_work.h @@ -17,6 +17,7 @@ struct drm_crtc; * drm_vblank_work_init() * drm_vblank_work_cancel_sync() * drm_vblank_work_flush() + * drm_vblank_work_flush_all() */ struct drm_vblank_work { /** @@ -67,5 +68,6 @@ void drm_vblank_work_init(struct drm_vblank_work *work, struct drm_crtc *crtc, void (*func)(struct kthread_work *work)); bool drm_vblank_work_cancel_sync(struct drm_vblank_work *work); void drm_vblank_work_flush(struct drm_vblank_work *work); +void drm_vblank_work_flush_all(struct drm_crtc *crtc); #endif /* !_DRM_VBLANK_WORK_H_ */
In some cases we want to flush all vblank work, right before vblank_off for example. Add a simple function to make this possible. Check that both pending_work and running work are empty when flushing. Co-Developed-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> --- drivers/gpu/drm/drm_vblank_work.c | 22 ++++++++++++++++++++++ include/drm/drm_vblank_work.h | 2 ++ 2 files changed, 24 insertions(+)