summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-09-08 12:41:06 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-09-08 12:50:29 +0100
commit30932a7b9d255c2037bee19e01aa3edc37b07386 (patch)
treec12036797c0dedd3aaea795a073df88cda137406
parent692c14d405bb352697b67f36a034d4963e272b66 (diff)
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@chris-wilson.co.uk>
-rw-r--r--src/sna/kgem.h7
-rw-r--r--src/sna/sna_accel.c14
-rw-r--r--src/sna/sna_blt.c92
-rw-r--r--src/sna/sna_io.c41
4 files changed, 91 insertions, 63 deletions
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index c3a9b13d..8bd57156 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 7df522bd..ab2908f5 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 4538f98f..25b6ef55 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 51d3af0e..6eede4df 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);