From: Daniel Vetter <daniel@ffwll.ch>
To: "Michel Dänzer" <michel@daenzer.net>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 4/5] drm/amdgpu: Wait for end of last waited-for vblank before programming flip
Date: Fri, 10 Jun 2016 16:43:12 +0200 [thread overview]
Message-ID: <20160610144312.GF3363@phenom.ffwll.local> (raw)
In-Reply-To: <1465549033-16561-5-git-send-email-michel@daenzer.net>
On Fri, Jun 10, 2016 at 05:57:12PM +0900, Michel Dänzer wrote:
> From: Michel Dänzer <michel.daenzer@amd.com>
>
> If userspace wants a page flip to take effect during vblank sequence n,
> it has to wait for vblank seqno n-1 before calling the
> DRM_IOCTL_MODE_PAGE_FLIP ioctl.
>
> This change makes sure that we do not program the flip to the hardware
> before the end of vblank seqno n-1 in this case, to prevent the flip
> from taking effect too early.
>
> On the other hand, if the DRM_IOCTL_MODE_PAGE_FLIP ioctl is called
> during vblank, but userspace didn't wait for the current vblank seqno
> before, this change would still allow the flip to be programmed during
> the current vblank seqno.
This just sounds like you're sending vblank events out a bit too early.
And watching vblank waits that userspace does works, but it's fragile,
add-hoc and I don't really jump in joy about adding that to the vblank
core. Is there no way you can adjust sending out the vblank events
similarly, to make sure userspace can never sneak in a pageflip too early?
That way it would be all nicely contained to amdgpu, and not leaking into
the core.
-Daniel
>
> Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu.h | 3 ++-
> drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 34 +++++++++++++++++++++++++----
> 2 files changed, 32 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 992f00b..7b53967 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -712,10 +712,11 @@ void amdgpu_doorbell_get_kfd_info(struct amdgpu_device *adev,
> */
>
> struct amdgpu_flip_work {
> - struct work_struct flip_work;
> + struct delayed_work flip_work;
> struct work_struct unpin_work;
> struct amdgpu_device *adev;
> int crtc_id;
> + u32 avoid_vblank;
> uint64_t base;
> struct drm_pending_vblank_event *event;
> struct amdgpu_bo *old_rbo;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> index de95ea7..a9f7851 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
> @@ -41,7 +41,7 @@ static void amdgpu_flip_callback(struct fence *f, struct fence_cb *cb)
> container_of(cb, struct amdgpu_flip_work, cb);
>
> fence_put(f);
> - schedule_work(&work->flip_work);
> + schedule_work(&work->flip_work.work);
> }
>
> static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work,
> @@ -63,8 +63,10 @@ static bool amdgpu_flip_handle_fence(struct amdgpu_flip_work *work,
>
> static void amdgpu_flip_work_func(struct work_struct *__work)
> {
> + struct delayed_work *delayed_work =
> + container_of(__work, struct delayed_work, work);
> struct amdgpu_flip_work *work =
> - container_of(__work, struct amdgpu_flip_work, flip_work);
> + container_of(delayed_work, struct amdgpu_flip_work, flip_work);
> struct amdgpu_device *adev = work->adev;
> struct amdgpu_crtc *amdgpuCrtc = adev->mode_info.crtcs[work->crtc_id];
>
> @@ -81,6 +83,19 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
> if (amdgpu_flip_handle_fence(work, &work->shared[i]))
> return;
>
> + /* Wait until we're out of the last waited-for vertical blank
> + * period
> + */
> + if (amdgpuCrtc->enabled &&
> + drm_crtc_vblank_count(crtc) == work->avoid_vblank &&
> + (amdgpu_get_crtc_scanoutpos(adev->ddev, work->crtc_id, 0,
> + &vpos, &hpos, NULL, NULL,
> + &crtc->hwmode)
> + & DRM_SCANOUTPOS_IN_VBLANK)) {
> + schedule_delayed_work(&work->flip_work, usecs_to_jiffies(1000));
> + return;
> + }
> +
> /* We borrow the event spin lock for protecting flip_status */
> spin_lock_irqsave(&crtc->dev->event_lock, flags);
>
> @@ -175,6 +190,7 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
> uint32_t page_flip_flags)
> {
> struct drm_device *dev = crtc->dev;
> + struct drm_file *file_priv = event->base.file_priv;
> struct amdgpu_device *adev = dev->dev_private;
> struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
> struct amdgpu_framebuffer *old_amdgpu_fb;
> @@ -191,7 +207,7 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
> if (work == NULL)
> return -ENOMEM;
>
> - INIT_WORK(&work->flip_work, amdgpu_flip_work_func);
> + INIT_DELAYED_WORK(&work->flip_work, amdgpu_flip_work_func);
> INIT_WORK(&work->unpin_work, amdgpu_unpin_work_func);
>
> work->event = event;
> @@ -244,6 +260,16 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
> goto pflip_cleanup;
> }
>
> + /* If this file descriptor has waited for the current vblank period,
> + * do not program the flip during this vblank period
> + */
> + if (amdgpu_crtc->crtc_id < file_priv->num_crtcs)
> + work->avoid_vblank =
> + file_priv->last_vblank_wait[amdgpu_crtc->crtc_id];
> +
> + if (!work->avoid_vblank)
> + work->avoid_vblank = drm_crtc_vblank_count(crtc) - 1;
> +
> /* we borrow the event spin lock for protecting flip_wrok */
> spin_lock_irqsave(&crtc->dev->event_lock, flags);
> if (amdgpu_crtc->pflip_status != AMDGPU_FLIP_NONE) {
> @@ -262,7 +288,7 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
> /* update crtc fb */
> crtc->primary->fb = fb;
> spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
> - amdgpu_flip_work_func(&work->flip_work);
> + amdgpu_flip_work_func(&work->flip_work.work);
> return 0;
>
> vblank_cleanup:
> --
> 2.8.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2016-06-10 14:43 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-10 8:57 [PATCH 0/5] drm/amdgpu: Page flip improvement and related cleanups Michel Dänzer
2016-06-10 8:57 ` [PATCH 1/5] drm: Only handle _DRM_VBLANK_NEXTONMISS once Michel Dänzer
2016-06-10 8:57 ` [PATCH 2/5] drm: Keep track of last vblank sequence waited for per-file-descriptor Michel Dänzer
2016-06-10 8:57 ` [PATCH 3/5] drm/amdgpu: Unpin BO if we can't get fences in amdgpu_crtc_page_flip Michel Dänzer
2016-06-10 8:57 ` [PATCH 4/5] drm/amdgpu: Wait for end of last waited-for vblank before programming flip Michel Dänzer
2016-06-10 14:43 ` Daniel Vetter [this message]
2016-06-13 1:54 ` Michel Dänzer
2016-06-13 8:06 ` Daniel Vetter
2016-06-13 8:58 ` Michel Dänzer
2016-06-13 14:06 ` Daniel Vetter
2016-06-14 2:09 ` Michel Dänzer
2016-06-14 5:53 ` Daniel Vetter
2016-06-14 7:25 ` Michel Dänzer
2016-06-14 8:06 ` Daniel Vetter
2016-06-15 8:03 ` Michel Dänzer
2016-06-15 9:23 ` Daniel Vetter
2016-06-16 2:15 ` Michel Dänzer
2016-06-16 8:14 ` Daniel Vetter
2016-06-14 8:12 ` Chris Wilson
2016-06-10 8:57 ` [PATCH 5/5] drm/amdgpu: Set MASTER_UPDATE_MODE to 0 again Michel Dänzer
2016-06-10 9:01 ` [PATCH 0/5] drm/amdgpu: Page flip improvement and related cleanups Christian König
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160610144312.GF3363@phenom.ffwll.local \
--to=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=michel@daenzer.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.