xf86-video-intel: src/sna/kgem.h src/sna/sna_accel.c src/sna/sna_blt.c src/sna/sna_io.c

Chris Wilson ickle at kemper.freedesktop.org
Mon Sep 8 05:03:55 PDT 2014


 src/sna/kgem.h      |    7 +++
 src/sna/sna_accel.c |   14 ++++---
 src/sna/sna_blt.c   |   92 +++++++++++++++++++++++++++++-----------------------
 src/sna/sna_io.c    |   41 +++++++++++++----------
 4 files changed, 91 insertions(+), 63 deletions(-)

New commits:
commit 30932a7b9d255c2037bee19e01aa3edc37b07386
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Sep 8 12:41:06 2014 +0100

    sna: Avoid u16 underflow when computing reserved batch space
    
    If we filled the batch exactly, then subtract -1 for the reserved
    BATCH_BUFFER_END, it would underflow to a large value - convincing us
    that we had sufficient room to stuff many, many more commands in.
    
    However, all the callsites should be guarded by checking already that
    they had sufficient space to emit at least one operation...
    
    References: https://bugs.freedesktop.org/show_bug.cgi?id=77074
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index c3a9b13..8bd5715 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -428,6 +428,13 @@ static inline void _kgem_set_mode(struct kgem *kgem, enum kgem_mode mode)
 	kgem->mode = mode;
 }
 
+static inline int kgem_batch_space(struct kgem *kgem)
+{
+	int rem = kgem->surface - kgem->nbatch;
+	assert(rem > 0);
+	return rem - KGEM_BATCH_RESERVED;
+}
+
 static inline bool kgem_check_batch(struct kgem *kgem, int num_dwords)
 {
 	assert(num_dwords > 0);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 7df522b..ab2908f 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -12156,7 +12156,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
 				sna->kgem.nbatch += 6;
 			}
 		} else do {
-			int n_this_time;
+			int n_this_time, rem;
 
 			assert(sna->kgem.mode == KGEM_BLT);
 			b = sna->kgem.batch + sna->kgem.nbatch;
@@ -12199,8 +12199,9 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
 			}
 
 			n_this_time = n;
-			if (3*n_this_time > sna->kgem.surface - sna->kgem.nbatch - KGEM_BATCH_RESERVED)
-				n_this_time = (sna->kgem.surface - sna->kgem.nbatch - KGEM_BATCH_RESERVED) / 3;
+			rem = kgem_batch_space(&sna->kgem);
+			if (3*n_this_time > rem)
+				n_this_time = rem / 3;
 			assert(n_this_time);
 			n -= n_this_time;
 
@@ -13061,7 +13062,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
 				sna->kgem.nbatch += 9;
 			}
 		} else do {
-			int n_this_time;
+			int n_this_time, rem;
 
 			assert(sna->kgem.mode == KGEM_BLT);
 			b = sna->kgem.batch + sna->kgem.nbatch;
@@ -13099,8 +13100,9 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
 			}
 
 			n_this_time = n;
-			if (3*n_this_time > sna->kgem.surface - sna->kgem.nbatch - KGEM_BATCH_RESERVED)
-				n_this_time = (sna->kgem.surface - sna->kgem.nbatch - KGEM_BATCH_RESERVED) / 3;
+			rem = kgem_batch_space(&sna->kgem);
+			if (3*n_this_time > rem)
+				n_this_time = rem / 3;
 			assert(n_this_time);
 			n -= n_this_time;
 
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index 4538f98..25b6ef5 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -232,6 +232,7 @@ static bool sna_blt_fill_init(struct sna *sna,
 		sna->blt_state.fill_alu = alu;
 	}
 
+	assert(sna->kgem.mode == KGEM_BLT);
 	return true;
 }
 
@@ -1102,12 +1103,13 @@ inline static void _sna_blt_fill_boxes(struct sna *sna,
 
 	do {
 		uint32_t *b = kgem->batch + kgem->nbatch;
-		int nbox_this_time;
+		int nbox_this_time, rem;
 
 		assert(sna->kgem.mode == KGEM_BLT);
 		nbox_this_time = nbox;
-		if (3*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-			nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 3;
+		rem = kgem_batch_space(kgem);
+		if (3*nbox_this_time > rem)
+			nbox_this_time = rem / 3;
 		assert(nbox_this_time);
 		nbox -= nbox_this_time;
 
@@ -1198,12 +1200,13 @@ static void blt_composite_fill_boxes_no_offset__thread(struct sna *sna,
 
 	do {
 		uint32_t *b = kgem->batch + kgem->nbatch;
-		int nbox_this_time;
+		int nbox_this_time, rem;
 
 		assert(sna->kgem.mode == KGEM_BLT);
 		nbox_this_time = nbox;
-		if (3*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-			nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 3;
+		rem = kgem_batch_space(kgem);
+		if (3*nbox_this_time > rem)
+			nbox_this_time = rem / 3;
 		assert(nbox_this_time);
 		nbox -= nbox_this_time;
 
@@ -1310,12 +1313,13 @@ static void blt_composite_fill_boxes__thread(struct sna *sna,
 
 	do {
 		uint32_t *b = kgem->batch + kgem->nbatch;
-		int nbox_this_time;
+		int nbox_this_time, rem;
 
 		assert(sna->kgem.mode == KGEM_BLT);
 		nbox_this_time = nbox;
-		if (3*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-			nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 3;
+		rem = kgem_batch_space(kgem);
+		if (3*nbox_this_time > rem)
+			nbox_this_time = rem / 3;
 		assert(nbox_this_time);
 		nbox -= nbox_this_time;
 
@@ -1386,6 +1390,7 @@ static bool
 begin_blt(struct sna *sna,
 	  struct sna_composite_op *op)
 {
+	assert(sna->kgem.mode == KGEM_BLT);
 	if (!kgem_check_bo_fenced(&sna->kgem, op->dst.bo)) {
 		kgem_submit(&sna->kgem);
 		if (!kgem_check_bo_fenced(&sna->kgem, op->dst.bo))
@@ -1603,11 +1608,12 @@ static void blt_composite_copy_boxes__thread(struct sna *sna,
 	if ((dst_dx | dst_dy) == 0) {
 		uint64_t hdr = (uint64_t)br13 << 32 | cmd;
 		do {
-			int nbox_this_time;
+			int nbox_this_time, rem;
 
 			nbox_this_time = nbox;
-			if (8*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-				nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+			rem = kgem_batch_space(kgem);
+			if (8*nbox_this_time > rem)
+				nbox_this_time = rem / 8;
 			if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 				nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2;
 			assert(nbox_this_time);
@@ -1656,11 +1662,12 @@ static void blt_composite_copy_boxes__thread(struct sna *sna,
 		} while (1);
 	} else {
 		do {
-			int nbox_this_time;
+			int nbox_this_time, rem;
 
 			nbox_this_time = nbox;
-			if (8*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-				nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+			rem = kgem_batch_space(kgem);
+			if (8*nbox_this_time > rem)
+				nbox_this_time = rem / 8;
 			if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 				nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2;
 			assert(nbox_this_time);
@@ -1733,11 +1740,12 @@ static void blt_composite_copy_boxes__thread64(struct sna *sna,
 	if ((dst_dx | dst_dy) == 0) {
 		uint64_t hdr = (uint64_t)br13 << 32 | cmd;
 		do {
-			int nbox_this_time;
+			int nbox_this_time, rem;
 
 			nbox_this_time = nbox;
-			if (10*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-				nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 10;
+			rem = kgem_batch_space(kgem);
+			if (10*nbox_this_time > rem)
+				nbox_this_time = rem / 10;
 			if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 				nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2;
 			assert(nbox_this_time);
@@ -1788,11 +1796,11 @@ static void blt_composite_copy_boxes__thread64(struct sna *sna,
 		} while (1);
 	} else {
 		do {
-			int nbox_this_time;
+			int nbox_this_time, rem;
 
 			nbox_this_time = nbox;
-			if (10*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-				nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 10;
+			if (10*nbox_this_time > rem)
+				nbox_this_time = rem / 10;
 			if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 				nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2;
 			assert(nbox_this_time);
@@ -3124,12 +3132,13 @@ fastcall static void sna_blt_fill_op_points(struct sna *sna,
 
 	do {
 		uint32_t *b = kgem->batch + kgem->nbatch;
-		int n_this_time;
+		int n_this_time, rem;
 
 		assert(sna->kgem.mode == KGEM_BLT);
 		n_this_time = n;
-		if (2*n_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-			n_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 2;
+		rem = kgem_batch_space(kgem);
+		if (2*n_this_time > rem)
+			n_this_time = rem / 2;
 		assert(n_this_time);
 		n -= n_this_time;
 
@@ -3226,6 +3235,7 @@ bool sna_blt_fill(struct sna *sna, uint8_t alu,
 			       bo, bpp, alu, pixel))
 		return false;
 
+	assert(sna->kgem.mode == KGEM_BLT);
 	fill->blt   = sna_blt_fill_op_blt;
 	fill->box   = sna_blt_fill_op_box;
 	fill->boxes = sna_blt_fill_op_boxes;
@@ -3543,11 +3553,11 @@ bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
 	}
 
 	do {
-		int nbox_this_time;
+		int nbox_this_time, rem;
 
 		nbox_this_time = nbox;
-		if (3*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-			nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 3;
+		if (3*nbox_this_time > rem)
+			nbox_this_time = rem / 3;
 		assert(nbox_this_time);
 		nbox -= nbox_this_time;
 
@@ -3728,11 +3738,12 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 		if (kgem->gen >= 0100) {
 			uint64_t hdr = (uint64_t)br13 << 32 | cmd | 8;
 			do {
-				int nbox_this_time;
+				int nbox_this_time, rem;
 
 				nbox_this_time = nbox;
-				if (10*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-					nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+				rem = kgem_batch_space(kgem);
+				if (10*nbox_this_time > rem)
+					nbox_this_time = rem / 8;
 				if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 					nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2;
 				assert(nbox_this_time);
@@ -3784,11 +3795,12 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 		} else {
 			uint64_t hdr = (uint64_t)br13 << 32 | cmd | 6;
 			do {
-				int nbox_this_time;
+				int nbox_this_time, rem;
 
 				nbox_this_time = nbox;
-				if (8*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-					nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+				rem = kgem_batch_space(kgem);
+				if (8*nbox_this_time > rem)
+					nbox_this_time = rem / 8;
 				if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 					nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2;
 				assert(nbox_this_time);
@@ -3840,11 +3852,12 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 		if (kgem->gen >= 0100) {
 			cmd |= 8;
 			do {
-				int nbox_this_time;
+				int nbox_this_time, rem;
 
 				nbox_this_time = nbox;
-				if (10*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-					nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+				rem = kgem_batch_space(kgem);
+				if (10*nbox_this_time > rem)
+					nbox_this_time = rem / 8;
 				if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 					nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2;
 				assert(nbox_this_time);
@@ -3896,11 +3909,12 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 		} else {
 			cmd |= 6;
 			do {
-				int nbox_this_time;
+				int nbox_this_time, rem;
 
 				nbox_this_time = nbox;
-				if (8*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-					nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+				rem = kgem_batch_space(kgem);
+				if (8*nbox_this_time > rem)
+					nbox_this_time = rem / 8;
 				if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 					nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc)/2;
 				assert(nbox_this_time);
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 51d3af0..6eede4d 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -484,11 +484,12 @@ fallback:
 	if (sna->kgem.gen >= 0100) {
 		cmd |= 8;
 		do {
-			int nbox_this_time;
+			int nbox_this_time, rem;
 
 			nbox_this_time = tmp_nbox;
-			if (10*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-				nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+			rem = kgem_batch_space(kgem);
+			if (10*nbox_this_time > rem)
+				nbox_this_time = rem / 8;
 			if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 				nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
 			assert(nbox_this_time);
@@ -543,11 +544,11 @@ fallback:
 	} else {
 		cmd |= 6;
 		do {
-			int nbox_this_time;
+			int nbox_this_time, rem;
 
 			nbox_this_time = tmp_nbox;
-			if (8*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-				nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+			if (8*nbox_this_time > rem)
+				nbox_this_time = rem / 8;
 			if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 				nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
 			assert(nbox_this_time);
@@ -1029,11 +1030,12 @@ tile:
 	if (kgem->gen >= 0100) {
 		cmd |= 8;
 		do {
-			int nbox_this_time;
+			int nbox_this_time, rem;
 
 			nbox_this_time = nbox;
-			if (10*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-				nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+			rem = kgem_batch_space(kgem);
+			if (10*nbox_this_time > rem)
+				nbox_this_time = rem / 8;
 			if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 				nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
 			assert(nbox_this_time);
@@ -1122,11 +1124,12 @@ tile:
 	} else {
 		cmd |= 6;
 		do {
-			int nbox_this_time;
+			int nbox_this_time, rem;
 
 			nbox_this_time = nbox;
-			if (8*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-				nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+			rem = kgem_batch_space(kgem);
+			if (8*nbox_this_time > rem)
+				nbox_this_time = rem / 8;
 			if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 				nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
 			assert(nbox_this_time);
@@ -1530,11 +1533,12 @@ tile:
 	if (sna->kgem.gen >= 0100) {
 		cmd |= 8;
 		do {
-			int nbox_this_time;
+			int nbox_this_time, rem;
 
 			nbox_this_time = nbox;
-			if (10*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-				nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+			rem = kgem_batch_space(kgem);
+			if (10*nbox_this_time > rem)
+				nbox_this_time = rem / 8;
 			if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 				nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
 			assert(nbox_this_time);
@@ -1627,11 +1631,12 @@ tile:
 	} else {
 		cmd |= 6;
 		do {
-			int nbox_this_time;
+			int nbox_this_time, rem;
 
 			nbox_this_time = nbox;
-			if (8*nbox_this_time > kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED)
-				nbox_this_time = (kgem->surface - kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+			rem = kgem_batch_space(kgem);
+			if (8*nbox_this_time > rem)
+				nbox_this_time = rem / 8;
 			if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) - kgem->nreloc)
 				nbox_this_time = (KGEM_RELOC_SIZE(kgem) - kgem->nreloc) / 2;
 			assert(nbox_this_time);


More information about the xorg-commit mailing list