From: Daniel Vetter <daniel@ffwll.ch>
To: Haneen Mohammed <hamohammed.sa@gmail.com>
Cc: rodrigosiqueiramelo@gmail.com, seanpaul@chromium.org,
dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v2] drm/vkms: Fix race condition around accessing frame number
Date: Wed, 5 Sep 2018 16:03:26 +0200 [thread overview]
Message-ID: <20180905140326.GD4929@phenom.ffwll.local> (raw)
In-Reply-To: <20180903211743.GA2773@haneenDRM>
On Tue, Sep 04, 2018 at 12:18:17AM +0300, Haneen Mohammed wrote:
> crtc_state is accessed by both vblank_handle() and the ordered
> work_struct handle vkms_crc_work_handle() to retrieve and or update
> the frame number for computed CRC.
>
> Since work_struct can fail, add frame_end to account for missing frame
> numbers.
>
> Use (frame_[start/end]) for synchronization between hrtimer callback
> and ordered work_struct handle.
>
> This patch passes the following subtests from igt kms_pipe_crc_basic test:
> bad-source, read-crc-pipe-A, read-crc-pipe-A-frame-sequence,
> nonblocking-crc-pipe-A, nonblocking-crc-pipe-A-frame-sequence
>
> Signed-off-by: Haneen Mohammed <hamohammed.sa@gmail.com>
> ---
> v2:
> - use u64 with spinlock instead of atomic_t
> - add out label for common exit routine @vkms_crc_work_handle()
Yup I think that looks good, thanks for your patch. Applied.
btw, do you still plan to type up a vkms.rst for documentation, so that we
could put a few of the todo items there? Or should I do that? Next
outreachy round starts soon, we need to get this ready.
-Daniel
>
> drivers/gpu/drm/vkms/vkms_crc.c | 36 ++++++++++++++++++++++++++++++--
> drivers/gpu/drm/vkms/vkms_crtc.c | 16 ++++++++++++--
> drivers/gpu/drm/vkms/vkms_drv.h | 8 +++++--
> 3 files changed, 54 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/vkms/vkms_crc.c b/drivers/gpu/drm/vkms/vkms_crc.c
> index ed47d67cecd6..68db42f15086 100644
> --- a/drivers/gpu/drm/vkms/vkms_crc.c
> +++ b/drivers/gpu/drm/vkms/vkms_crc.c
> @@ -34,6 +34,15 @@ static uint32_t _vkms_get_crc(struct vkms_crc_data *crc_data)
> return crc;
> }
>
> +/**
> + * vkms_crc_work_handle - ordered work_struct to compute CRC
> + *
> + * @work: work_struct
> + *
> + * Work handler for computing CRCs. work_struct scheduled in
> + * an ordered workqueue that's periodically scheduled to run by
> + * _vblank_handle() and flushed at vkms_atomic_crtc_destroy_state().
> + */
> void vkms_crc_work_handle(struct work_struct *work)
> {
> struct vkms_crtc_state *crtc_state = container_of(work,
> @@ -45,8 +54,18 @@ void vkms_crc_work_handle(struct work_struct *work)
> output);
> struct vkms_crc_data *primary_crc = NULL;
> struct drm_plane *plane;
> -
> u32 crc32 = 0;
> + u64 frame_start, frame_end;
> + unsigned long flags;
> +
> + spin_lock_irqsave(&out->state_lock, flags);
> + frame_start = crtc_state->frame_start;
> + frame_end = crtc_state->frame_end;
> + spin_unlock_irqrestore(&out->state_lock, flags);
> +
> + /* _vblank_handle() hasn't updated frame_start yet */
> + if (!frame_start || frame_start == frame_end)
> + goto out;
>
> drm_for_each_plane(plane, &vdev->drm) {
> struct vkms_plane_state *vplane_state;
> @@ -67,7 +86,20 @@ void vkms_crc_work_handle(struct work_struct *work)
> if (primary_crc)
> crc32 = _vkms_get_crc(primary_crc);
>
> - drm_crtc_add_crc_entry(crtc, true, crtc_state->n_frame, &crc32);
> + frame_end = drm_crtc_accurate_vblank_count(crtc);
> +
> + /* queue_work can fail to schedule crc_work; add crc for
> + * missing frames
> + */
> + while (frame_start <= frame_end)
> + drm_crtc_add_crc_entry(crtc, true, frame_start++, &crc32);
> +
> +out:
> + /* to avoid using the same value for frame number again */
> + spin_lock_irqsave(&out->state_lock, flags);
> + crtc_state->frame_end = frame_end;
> + crtc_state->frame_start = 0;
> + spin_unlock_irqrestore(&out->state_lock, flags);
> }
>
> static int vkms_crc_parse_source(const char *src_name, bool *enabled)
> diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
> index 9d0b1a325a78..177bbcb38306 100644
> --- a/drivers/gpu/drm/vkms/vkms_crtc.c
> +++ b/drivers/gpu/drm/vkms/vkms_crtc.c
> @@ -22,8 +22,19 @@ static void _vblank_handle(struct vkms_output *output)
> DRM_ERROR("vkms failure on handling vblank");
>
> if (state && output->crc_enabled) {
> - state->n_frame = drm_crtc_accurate_vblank_count(crtc);
> - queue_work(output->crc_workq, &state->crc_work);
> + u64 frame = drm_crtc_accurate_vblank_count(crtc);
> +
> + /* update frame_start only if a queued vkms_crc_work_handle()
> + * has read the data
> + */
> + spin_lock(&output->state_lock);
> + if (!state->frame_start)
> + state->frame_start = frame;
> + spin_unlock(&output->state_lock);
> +
> + ret = queue_work(output->crc_workq, &state->crc_work);
> + if (!ret)
> + DRM_WARN("failed to queue vkms_crc_work_handle");
> }
>
> spin_unlock(&output->lock);
> @@ -211,6 +222,7 @@ int vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
> drm_crtc_helper_add(crtc, &vkms_crtc_helper_funcs);
>
> spin_lock_init(&vkms_out->lock);
> + spin_lock_init(&vkms_out->state_lock);
>
> vkms_out->crc_workq = alloc_ordered_workqueue("vkms_crc_workq", 0);
>
> diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
> index 2017a2ccc43d..80af6d3a65e7 100644
> --- a/drivers/gpu/drm/vkms/vkms_drv.h
> +++ b/drivers/gpu/drm/vkms/vkms_drv.h
> @@ -39,12 +39,14 @@ struct vkms_plane_state {
> * vkms_crtc_state - Driver specific CRTC state
> * @base: base CRTC state
> * @crc_work: work struct to compute and add CRC entries
> - * @n_frame: frame number for computed CRC
> + * @n_frame_start: start frame number for computed CRC
> + * @n_frame_end: end frame number for computed CRC
> */
> struct vkms_crtc_state {
> struct drm_crtc_state base;
> struct work_struct crc_work;
> - unsigned int n_frame;
> + u64 frame_start;
> + u64 frame_end;
> };
>
> struct vkms_output {
> @@ -59,6 +61,8 @@ struct vkms_output {
> struct workqueue_struct *crc_workq;
> /* protects concurrent access to crc_data */
> spinlock_t lock;
> + /* protects concurrent access to crtc_state */
> + spinlock_t state_lock;
> };
>
> struct vkms_device {
> --
> 2.17.1
>
--
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:[~2018-09-05 14:03 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-03 21:18 [PATCH v2] drm/vkms: Fix race condition around accessing frame number Haneen Mohammed
2018-09-05 14:03 ` Daniel Vetter [this message]
2018-09-05 14:24 ` Haneen Mohammed
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=20180905140326.GD4929@phenom.ffwll.local \
--to=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=hamohammed.sa@gmail.com \
--cc=rodrigosiqueiramelo@gmail.com \
--cc=seanpaul@chromium.org \
/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.