diff --git a/tools/quest/kgsl_compat.c b/tools/quest/kgsl_compat.c index 18fd61b0a..f3afa289a 100644 --- a/tools/quest/kgsl_compat.c +++ b/tools/quest/kgsl_compat.c @@ -29,7 +29,7 @@ static void report(const char *operation, int error) { errno = saved; } -#define TRACKED_CONTEXTS 32 +#define TRACKED_CONTEXTS 128 static struct { unsigned int context, queued, retired; @@ -51,7 +51,11 @@ static int tracked_find(unsigned int context, int create) { if (free_slot < 0 && tracked[i].context == 0) free_slot = i; } if (!create) return -1; - if (free_slot < 0) free_slot = (int)(context % TRACKED_CONTEXTS); + if (free_slot < 0) { + free_slot = (int)(context % TRACKED_CONTEXTS); + for (int i = 0; i < TRACKED_CONTEXTS; i++) + if (tracked[i].queued == tracked[i].retired) { free_slot = i; break; } + } tracked[free_slot].context = context; tracked[free_slot].queued = tracked[free_slot].retired = 0; return free_slot; @@ -81,7 +85,10 @@ static int read_timestamp(quest_ioctl_fn real, int fd, struct kgsl_cmdstream_rea unsigned int queued = slot < 0 ? 0 : tracked[slot].queued; unsigned int retired = slot < 0 ? 0 : tracked[slot].retired; tracked_release(); - if (slot < 0) { errno = EACCES; return -1; } + if (slot < 0 || (query->type != KGSL_TIMESTAMP_RETIRED && query->type != KGSL_TIMESTAMP_QUEUED)) { + errno = EACCES; + return -1; + } if (query->type == KGSL_TIMESTAMP_RETIRED && (int)(queued - retired) > 0) { struct kgsl_device_waittimestamp_ctxtid wait = { diff --git a/tools/quest/test_kgsl_compat.c b/tools/quest/test_kgsl_compat.c index 4c9b84e2a..cc453635b 100644 --- a/tools/quest/test_kgsl_compat.c +++ b/tools/quest/test_kgsl_compat.c @@ -79,6 +79,7 @@ static void timestamp_scenarios(void) { assert(read_ts(5, KGSL_TIMESTAMP_RETIRED, &ts) == -1 && errno == EACCES && ts == 0xdead); submit(5, 10); assert(read_ts(5, KGSL_TIMESTAMP_QUEUED, &ts) == 0 && ts == 10 && waits == 0); + assert(read_ts(5, KGSL_TIMESTAMP_CONSUMED, &ts) == -1 && errno == EACCES && ts == 0xdead); wait_error = ETIMEDOUT; assert(read_ts(5, KGSL_TIMESTAMP_RETIRED, &ts) == 0 && ts == 0 && waits == 1 && waited_for == 10); wait_error = 0; @@ -96,6 +97,9 @@ static void timestamp_scenarios(void) { struct kgsl_drawctxt_destroy gone = {.drawctxt_id = 5}; assert(quest_kgsl_ioctl(timestamp_mock, 42, IOCTL_KGSL_DRAWCTXT_DESTROY, &gone) == 0); assert(read_ts(5, KGSL_TIMESTAMP_QUEUED, &ts) == -1 && errno == EACCES); + for (unsigned int c = 100; c < 100 + 130; c++) submit(c, 7); + submit(200, 9); + assert(read_ts(200, KGSL_TIMESTAMP_QUEUED, &ts) == 0 && ts == 9); read_error = EIO; submit(6, 3); assert(read_ts(6, KGSL_TIMESTAMP_QUEUED, &ts) == -1 && errno == EIO);