[PATCH 2/5] drm: Keep track of last vblank sequence waited for per-file-descriptor

Michel Dänzer michel at daenzer.net
Fri Jun 10 08:57:10 UTC 2016


From: Michel Dänzer <michel.daenzer at amd.com>

The per-device tracking hasn't been used since commit dafffda0
("drm/info: Remove unused code").

The per-file-descriptor tracking will be used by a following amdgpu
driver change.

Note that last_vblank_wait is only updated when the corresponding wait
completes, and is set to the vblank seqno waited for, not the current
one when the wait completes.

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 drivers/gpu/drm/drm_fops.c |  8 ++++++++
 drivers/gpu/drm/drm_irq.c  | 18 +++++++++++++++++-
 include/drm/drmP.h         |  4 +++-
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 7af7f8b..1f52f02 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -256,6 +256,13 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor)
 	priv->pid = get_pid(task_pid(current));
 	priv->minor = minor;
 
+	if (drm_is_primary_client(priv)) {
+		priv->num_crtcs = dev->num_crtcs;
+		priv->last_vblank_wait = kcalloc(priv->num_crtcs,
+						 sizeof(*priv->last_vblank_wait),
+						 GFP_KERNEL);
+	}
+
 	/* for compatibility root is always authenticated */
 	priv->authenticated = capable(CAP_SYS_ADMIN);
 	priv->lock_count = 0;
@@ -530,6 +537,7 @@ int drm_release(struct inode *inode, struct file *filp)
 	WARN_ON(!list_empty(&file_priv->event_list));
 
 	put_pid(file_priv->pid);
+	kfree(file_priv->last_vblank_wait);
 	kfree(file_priv);
 
 	/* ========================================================
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 39ea4fc..62845f4 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -77,6 +77,15 @@ MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] (0
 MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
 MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps");
 
+/* Keep track of the latest seqno waited for by this file descriptor */
+static void update_last_vblank_wait(struct drm_file *file_priv, unsigned pipe,
+				    u32 seq)
+{
+	if (pipe < file_priv->num_crtcs &&
+	    (int)(seq - file_priv->last_vblank_wait[pipe]) > 0)
+		file_priv->last_vblank_wait[pipe] = seq;
+}
+
 static void store_vblank(struct drm_device *dev, unsigned int pipe,
 			 u32 vblank_count_inc,
 			 struct timeval *t_vblank, u32 last)
@@ -1694,6 +1703,9 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
 	e->event.sequence = vblwait->request.sequence;
 	if ((seq - vblwait->request.sequence) <= (1 << 23)) {
 		drm_vblank_put(dev, pipe);
+
+		update_last_vblank_wait(file_priv, pipe,
+					vblwait->request.sequence);
 		send_vblank_event(dev, e, seq, &now);
 		vblwait->reply.sequence = seq;
 	} else {
@@ -1795,7 +1807,6 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
 
 	DRM_DEBUG("waiting on vblank count %d, crtc %u\n",
 		  vblwait->request.sequence, pipe);
-	vblank->last_wait = vblwait->request.sequence;
 	DRM_WAIT_ON(ret, vblank->queue, 3 * HZ,
 		    (((drm_vblank_count(dev, pipe) -
 		       vblwait->request.sequence) <= (1 << 23)) ||
@@ -1805,6 +1816,9 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
 	if (ret != -EINTR) {
 		struct timeval now;
 
+		update_last_vblank_wait(file_priv, pipe,
+					vblwait->request.sequence);
+
 		vblwait->reply.sequence = drm_vblank_count_and_time(dev, pipe, &now);
 		vblwait->reply.tval_sec = now.tv_sec;
 		vblwait->reply.tval_usec = now.tv_usec;
@@ -1841,6 +1855,8 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe)
 
 		list_del(&e->base.link);
 		drm_vblank_put(dev, pipe);
+		update_last_vblank_wait(e->base.file_priv, pipe,
+					e->event.sequence);
 		send_vblank_event(dev, e, seq, &now);
 	}
 
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 360b2a7..d7c95b6 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -354,6 +354,9 @@ struct drm_file {
 	struct mutex event_read_lock;
 
 	struct drm_prime_file_private prime;
+
+	unsigned num_crtcs;
+	u32 *last_vblank_wait;		/* Last vblank seqno waited per CRTC */
 };
 
 /**
@@ -733,7 +736,6 @@ struct drm_vblank_crtc {
 	atomic_t refcount;		/* number of users of vblank interruptsper crtc */
 	u32 last;			/* protected by dev->vbl_lock, used */
 					/* for wraparound handling */
-	u32 last_wait;			/* Last vblank seqno waited per CRTC */
 	unsigned int inmodeset;		/* Display driver is setting mode */
 	unsigned int pipe;		/* crtc index */
 	int framedur_ns;		/* frame/field duration in ns */
-- 
2.8.1



More information about the dri-devel mailing list