summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2014-05-19 02:13:02 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2014-05-19 02:13:02 -0700
commite8f31f4b7de56cd09cd87e24f2b40a798351efa7 (patch)
tree6370fd8cd93aa3e4db3c77618a131d0eee70c155
parent78e5ee27d0582e7b004d2a8997e402b4ec1773ce (diff)
parentd3626a519757955214bb1927098675bda839392a (diff)
Merge "msm: kgsl: Avoid a deadlock with the cmdbatch timer"
-rw-r--r--drivers/gpu/msm/adreno_dispatch.c3
-rw-r--r--drivers/gpu/msm/kgsl.c19
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);