From: Haneen Mohammed <hamohammed.sa@gmail.com>
To: dri-devel@lists.freedesktop.org
Cc: seanpaul@chromium.org, rodrigosiqueiramelo@gmail.com
Subject: [PATCH] drm/vkms: Fix race condition around accessing frame number
Date: Fri, 24 Aug 2018 02:16:34 +0300 [thread overview]
Message-ID: <20180823231634.GA17011@haneenDRM> (raw)
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 atomic_t witth appropriate flags for synchronization between hrtimer
callback and ordered work_struct handle since spinlock can't be used
with work_struct handle and mutex can't be used with hrtimer callback.
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>
---
drivers/gpu/drm/vkms/vkms_crc.c | 33 ++++++++++++++++++++++++++++++--
drivers/gpu/drm/vkms/vkms_crtc.c | 13 +++++++++++--
drivers/gpu/drm/vkms/vkms_drv.h | 6 ++++--
3 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/vkms/vkms_crc.c b/drivers/gpu/drm/vkms/vkms_crc.c
index ed47d67cecd6..4a1ba5b7886a 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;
+ u32 frame_start, frame_end;
+
+ frame_start = atomic_read(&crtc_state->frame_start);
+ frame_end = atomic_read(&crtc_state->frame_end);
+ /* _vblank_handle() hasn't updated frame_start yet */
+ if (!frame_start) {
+ return;
+ } else if (frame_start == frame_end) {
+ atomic_set(&crtc_state->frame_start, 0);
+ return;
+ }
drm_for_each_plane(plane, &vdev->drm) {
struct vkms_plane_state *vplane_state;
@@ -67,7 +86,17 @@ 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);
+
+ /* to avoid using the same value again */
+ atomic_set(&crtc_state->frame_end, frame_end);
+ atomic_set(&crtc_state->frame_start, 0);
}
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..a170677acd46 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -22,8 +22,17 @@ 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);
+ u32 frame = drm_crtc_accurate_vblank_count(crtc);
+
+ /* update frame_start only if a queued vkms_crc_work_handle has
+ * read the data
+ */
+ if (!atomic_read(&state->frame_start))
+ atomic_set(&state->frame_start, frame);
+
+ ret = queue_work(output->crc_workq, &state->crc_work);
+ if (!ret)
+ DRM_WARN("failed to queue vkms_crc_work_handle");
}
spin_unlock(&output->lock);
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index 2017a2ccc43d..4a3956a0549e 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;
+ atomic_t frame_start;
+ atomic_t frame_end;
};
struct vkms_output {
--
2.17.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next reply other threads:[~2018-08-23 23:16 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-23 23:16 Haneen Mohammed [this message]
2018-08-31 8:41 ` [PATCH] drm/vkms: Fix race condition around accessing frame number Daniel Vetter
2018-09-01 17:53 ` Haneen Mohammed
2018-09-03 7:29 ` Daniel Vetter
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=20180823231634.GA17011@haneenDRM \
--to=hamohammed.sa@gmail.com \
--cc=dri-devel@lists.freedesktop.org \
--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.