diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2014-05-19 02:13:02 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2014-05-19 02:13:02 -0700 |
commit | e8f31f4b7de56cd09cd87e24f2b40a798351efa7 (patch) | |
tree | 6370fd8cd93aa3e4db3c77618a131d0eee70c155 | |
parent | 78e5ee27d0582e7b004d2a8997e402b4ec1773ce (diff) | |
parent | d3626a519757955214bb1927098675bda839392a (diff) |
Merge "msm: kgsl: Avoid a deadlock with the cmdbatch timer"
-rw-r--r-- | drivers/gpu/msm/adreno_dispatch.c | 3 | ||||
-rw-r--r-- | drivers/gpu/msm/kgsl.c | 19 |
2 files changed, 11 insertions, 11 deletions
diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c index 97a9d39f6a0d..da6e0aa10d0b 100644 --- a/drivers/gpu/msm/adreno_dispatch.c +++ b/drivers/gpu/msm/adreno_dispatch.c @@ -181,14 +181,15 @@ static inline struct kgsl_cmdbatch *adreno_dispatcher_get_cmdbatch( */ if (!timer_pending(&cmdbatch->timer)) mod_timer(&cmdbatch->timer, jiffies + (5 * HZ)); + spin_unlock(&cmdbatch->lock); } else { /* * Otherwise, delete the timer to make sure it is good * and dead before queuing the buffer */ + spin_unlock(&cmdbatch->lock); del_timer_sync(&cmdbatch->timer); } - spin_unlock(&cmdbatch->lock); if (pending) { cmdbatch = ERR_PTR(-EAGAIN); diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index 5a7fadbc1b2b..984bd83b92c7 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -1455,12 +1455,14 @@ static void _kgsl_cmdbatch_timer(unsigned long data) if (cmdbatch == NULL || cmdbatch->context == NULL) return; + spin_lock(&cmdbatch->lock); + if (list_empty(&cmdbatch->synclist)) + goto done; + pr_err("kgsl: possible gpu syncpoint deadlock for context %d timestamp %d\n", cmdbatch->context->id, cmdbatch->timestamp); pr_err(" Active sync points:\n"); - spin_lock(&cmdbatch->lock); - /* Print all the pending sync objects */ list_for_each_entry(event, &cmdbatch->synclist, node) { @@ -1485,6 +1487,7 @@ static void _kgsl_cmdbatch_timer(unsigned long data) } } +done: spin_unlock(&cmdbatch->lock); } @@ -1560,16 +1563,12 @@ static void kgsl_cmdbatch_sync_expire(struct kgsl_device *device, } sched = list_empty(&event->cmdbatch->synclist) ? 1 : 0; + spin_unlock(&event->cmdbatch->lock); - /* - * If the list is empty delete the canary timer while - * still holding the lock - */ + /* If the list is empty delete the canary timer */ if (sched) del_timer_sync(&event->cmdbatch->timer); - spin_unlock(&event->cmdbatch->lock); - /* * if this is the last event in the list then tell * the GPU device that the cmdbatch can be submitted @@ -1613,11 +1612,11 @@ void kgsl_cmdbatch_destroy(struct kgsl_cmdbatch *cmdbatch) LIST_HEAD(cancel_synclist); int sched = 0; - spin_lock(&cmdbatch->lock); - /* Zap the canary timer */ del_timer_sync(&cmdbatch->timer); + spin_lock(&cmdbatch->lock); + /* Empty the synclist before canceling events */ list_splice_init(&cmdbatch->synclist, &cancel_synclist); spin_unlock(&cmdbatch->lock); |