xf86-video-intel: 4 commits - src/sna/kgem.c src/sna/sna_display.c src/sna/sna_driver.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Mon Dec 8 03:21:18 PST 2014


 src/sna/kgem.c        |    4 +++
 src/sna/sna.h         |    2 -
 src/sna/sna_display.c |   63 ++++++++++++++++++++++++++------------------------
 src/sna/sna_driver.c  |    5 +++
 4 files changed, 42 insertions(+), 32 deletions(-)

New commits:
commit d247cb7d0cdb73736f31612157e47f166af68ba0
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Dec 8 10:07:25 2014 +0000

    sna/gen6: Poke PSMI control around WAIT_FOR_EVENT to prevent idling
    
    The bspec recommends preventing the hardware from going to sleep around
    a WAIT_FOR_EVENT, and tells us to use disable sleep bit in PSMI control
    to accomplish this.
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=62373
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 52dc438..772c836 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -6284,7 +6284,7 @@ static bool sna_emit_wait_for_scanline_gen6(struct sna *sna,
 	event = 1 << (3*full_height + pipe*8);
 
 	b = kgem_get_batch(&sna->kgem);
-	sna->kgem.nbatch += 10;
+	sna->kgem.nbatch += 16;
 
 	b[0] = MI_LOAD_REGISTER_IMM | 1;
 	b[1] = 0x44050; /* DERRMR */
@@ -6292,10 +6292,16 @@ static bool sna_emit_wait_for_scanline_gen6(struct sna *sna,
 	b[3] = MI_LOAD_REGISTER_IMM | 1;
 	b[4] = 0x4f100; /* magic */
 	b[5] = (1 << 31) | (1 << 30) | pipe << 29 | (y1 << 16) | y2;
-	b[6] = MI_WAIT_FOR_EVENT | event;
-	b[7] = MI_LOAD_REGISTER_IMM | 1;
-	b[8] = 0x44050; /* DERRMR */
-	b[9] = ~0;
+	b[6] = MI_LOAD_REGISTER_IMM | 1;
+	b[7] = 0x2050; /* PSMI_CTL(rcs) */
+	b[8] = 1 << 16 | 1;
+	b[9] = MI_WAIT_FOR_EVENT | event;
+	b[10] = MI_LOAD_REGISTER_IMM | 1;
+	b[11] = 0x2050; /* PSMI_CTL(rcs) */
+	b[12] = 1 << 16;
+	b[13] = MI_LOAD_REGISTER_IMM | 1;
+	b[14] = 0x44050; /* DERRMR */
+	b[15] = ~0;
 
 	sna->kgem.batch_flags |= I915_EXEC_SECURE;
 	return true;
commit d39dc73a80161d290555877942e5990daf0c0411
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Dec 8 08:33:11 2014 +0000

    sna: Inline check for pending events before reading from drm fd
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index 8129eae..db1fdc1 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -433,7 +433,7 @@ extern void sna_mode_check(struct sna *sna);
 extern bool sna_mode_disable(struct sna *sna);
 extern void sna_mode_enable(struct sna *sna);
 extern void sna_mode_reset(struct sna *sna);
-extern void sna_mode_wakeup(struct sna *sna);
+extern int sna_mode_wakeup(struct sna *sna);
 extern void sna_mode_redisplay(struct sna *sna);
 extern void sna_shadow_set_crtc(struct sna *sna, xf86CrtcPtr crtc, struct kgem_bo *bo);
 extern void sna_shadow_unset_crtc(struct sna *sna, xf86CrtcPtr crtc);
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 1633333..52dc438 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -254,15 +254,6 @@ static inline bool event_pending(int fd)
 	return poll(&pfd, 1, 0) == 1;
 }
 
-static bool sna_mode_has_pending_events(struct sna *sna)
-{
-	/* In order to workaround a kernel bug in not honouring O_NONBLOCK,
-	 * check that the fd is readable before attempting to read the next
-	 * event from drm.
-	 */
-	return event_pending(sna->kgem.fd);
-}
-
 static bool sna_mode_wait_for_event(struct sna *sna)
 {
 	struct pollfd pfd;
@@ -1171,8 +1162,8 @@ static bool wait_for_shadow(struct sna *sna,
 		drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_THROTTLE, 0);
 		sna->kgem.need_throttle = false;
 
-		while (sna->mode.flip_active && sna_mode_has_pending_events(sna))
-			sna_mode_wakeup(sna);
+		while (sna->mode.flip_active && sna_mode_wakeup(sna))
+			;
 	}
 
 	bo = sna->mode.shadow;
@@ -4364,9 +4355,7 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
 			sna_crtc_disable(crtc);
 	}
 
-	while (sna_mode_has_pending_events(sna))
-		sna_mode_wakeup(sna);
-
+	sna_mode_wakeup(sna);
 	kgem_clean_scanout_cache(&sna->kgem);
 
 	return TRUE;
@@ -5972,9 +5961,7 @@ sna_mode_disable(struct sna *sna)
 	for (i = 0; i < sna->mode.num_real_crtc; i++)
 		sna_crtc_disable(config->crtc[i]);
 
-	while (sna_mode_has_pending_events(sna))
-		sna_mode_wakeup(sna);
-
+	sna_mode_wakeup(sna);
 	kgem_clean_scanout_cache(&sna->kgem);
 	return true;
 }
@@ -6009,8 +5996,7 @@ sna_mode_enable(struct sna *sna)
 void
 sna_mode_close(struct sna *sna)
 {
-	while (sna_mode_has_pending_events(sna))
-		sna_mode_wakeup(sna);
+	sna_mode_wakeup(sna);
 
 	if (sna->flags & SNA_IS_HOSTED)
 		return;
@@ -6575,8 +6561,7 @@ void sna_mode_reset(struct sna *sna)
 	}
 
 	/* drain the event queue */
-	while (sna_mode_has_pending_events(sna))
-		sna_mode_wakeup(sna);
+	sna_mode_wakeup(sna);
 }
 
 static void transformed_box(BoxRec *box, xf86CrtcPtr crtc)
@@ -6968,8 +6953,8 @@ void sna_mode_redisplay(struct sna *sna)
 		damage = sna->mode.shadow_damage;
 		sna->mode.shadow_damage = NULL;
 
-		while (sna->mode.flip_active && sna_mode_has_pending_events(sna))
-			sna_mode_wakeup(sna);
+		while (sna->mode.flip_active && sna_mode_wakeup(sna))
+			;
 
 		sna->mode.shadow_damage = damage;
 	}
@@ -7387,17 +7372,26 @@ fixup_flip:
 	RegionEmpty(region);
 }
 
-void sna_mode_wakeup(struct sna *sna)
+int sna_mode_wakeup(struct sna *sna)
 {
 	char buffer[1024];
 	int len, i;
+	int ret = 0;
+
+again:
+	/* In order to workaround a kernel bug in not honouring O_NONBLOCK,
+	 * check that the fd is readable before attempting to read the next
+	 * event from drm.
+	 */
+	if (!event_pending(sna->kgem.fd))
+		return ret;
 
 	/* The DRM read semantics guarantees that we always get only
 	 * complete events.
 	 */
 	len = read(sna->kgem.fd, buffer, sizeof (buffer));
 	if (len < (int)sizeof(struct drm_event))
-		return;
+		return ret;
 
 	/* Note that we cannot rely on the passed in struct sna matching
 	 * the struct sna used for the vblank event (in case it was submitted
@@ -7464,5 +7458,8 @@ void sna_mode_wakeup(struct sna *sna)
 			break;
 		}
 		i += e->length;
+		ret++;
 	}
+
+	goto again;
 }
commit f8aecdffada438306dff8923cdfc0df527509672
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Dec 4 11:23:11 2014 +0000

    sna: Clear the read flags for the shared drm fd after use
    
    In ZaphodHeads, we may reuse the same select read flags and attempt to
    read from a blocking drm fd multiple times. However, if we clear the
    read flags after first exhausting the fd, we shouldn't then block on
    subsequent heads.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 79442f4..d4acceb 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -772,8 +772,11 @@ sna_wakeup_handler(WAKEUPHANDLER_ARGS_DECL)
 
 	sna_accel_wakeup_handler(sna);
 
-	if (FD_ISSET(sna->kgem.fd, (fd_set*)read_mask))
+	if (FD_ISSET(sna->kgem.fd, (fd_set*)read_mask)) {
 		sna_mode_wakeup(sna);
+		/* Clear the flag so that subsequent ZaphodHeads don't block  */
+		FD_CLR(sna->kgem.fd, (fd_set*)read_mask);
+	}
 }
 
 #if HAVE_UDEV
commit 594470c809627feab4891bade5ec6d80e1d0a919
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Dec 4 11:16:58 2014 +0000

    sna: Update the fence marker after submitting a new batch
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index bea2295..78ed540 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2967,6 +2967,10 @@ static void kgem_commit(struct kgem *kgem)
 		assert(rq->ring < ARRAY_SIZE(kgem->requests));
 		list_add_tail(&rq->list, &kgem->requests[rq->ring]);
 		kgem->need_throttle = kgem->need_retire = 1;
+
+		if (kgem->fence[rq->ring] == NULL &&
+		    __kgem_busy(kgem, rq->bo->handle))
+			kgem->fence[rq->ring] = rq;
 	}
 
 	kgem->next_request = NULL;


More information about the xorg-commit mailing list