mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-14 16:46:15 -04:00
msm: kgsl: Update internal timestamp when preemption is toggled
Say preemption is enabled and a context is bound to ringbuffer-1. It's internal timestamp say is 0x4000. Now if we disable preemption, all the contexts are bound to ringbuffer-0. Now, say the context is going away. The context destroy path will check timestamp 0x4000 which is from the stale ringbuffer, against ringbuffer-0, and its very likely that ringbuffer-0's timestamp is less than 0x4000 which will cause a false context-detach fault. Fix this by updating the context's internal timestamp to the last retired timestamp on the new ringbuffer. Also, toggle preemption only if ringbuffers are completely drained. Change-Id: I674978593b11df3998765017c270c3f0dde6c0a5 Signed-off-by: Harshdeep Dhatt <hdhatt@codeaurora.org>
This commit is contained in:
parent
01e5e2f57e
commit
8833b6fd82
1 changed files with 24 additions and 2 deletions
|
|
@ -144,16 +144,38 @@ static void change_preemption(struct adreno_device *adreno_dev, void *priv)
|
|||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct kgsl_context *context;
|
||||
struct adreno_context *drawctxt;
|
||||
int id;
|
||||
struct adreno_ringbuffer *rb;
|
||||
int id, i, ret;
|
||||
|
||||
/* Make sure all ringbuffers are finished */
|
||||
FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
|
||||
ret = adreno_ringbuffer_waittimestamp(rb, rb->timestamp,
|
||||
2 * 1000);
|
||||
if (ret) {
|
||||
dev_err(device->dev,
|
||||
"Cannot disable preemption because couldn't idle ringbuffer[%d] ret: %d\n",
|
||||
rb->id, ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
change_bit(ADRENO_DEVICE_PREEMPTION, &adreno_dev->priv);
|
||||
adreno_dev->cur_rb = &(adreno_dev->ringbuffers[0]);
|
||||
adreno_dev->cur_rb = &adreno_dev->ringbuffers[0];
|
||||
adreno_dev->next_rb = NULL;
|
||||
adreno_dev->prev_rb = NULL;
|
||||
|
||||
/* Update the ringbuffer for each draw context */
|
||||
write_lock(&device->context_lock);
|
||||
idr_for_each_entry(&device->context_idr, context, id) {
|
||||
drawctxt = ADRENO_CONTEXT(context);
|
||||
drawctxt->rb = adreno_ctx_get_rb(adreno_dev, drawctxt);
|
||||
|
||||
/*
|
||||
* Make sure context destroy checks against the correct
|
||||
* ringbuffer's timestamp.
|
||||
*/
|
||||
adreno_rb_readtimestamp(adreno_dev, drawctxt->rb,
|
||||
KGSL_TIMESTAMP_RETIRED, &drawctxt->internal_timestamp);
|
||||
}
|
||||
write_unlock(&device->context_lock);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue