summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2015-05-14 11:32:24 -0700
committerEric Anholt <eric@anholt.net>2015-06-04 14:15:35 -0700
commiteb4fdfd674ab976fed764b6c606c9963c183906a (patch)
tree965093aeae52ad9983cc68c980bb61154cafcbd6
parent1fafb6cab83be514ca37d8701dc5a789abb3b333 (diff)
downloadlinux-eb4fdfd674ab976fed764b6c606c9963c183906a.tar.gz
drm/vc4: Don't forget to disable IRQs during the job_done spinlock.
The hard IRQ handler also takes this lock, so we need interrupts disabled or we'll deadlock. Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r--drivers/gpu/drm/vc4/vc4_gem.c14
-rw-r--r--drivers/gpu/drm/vc4/vc4_irq.c6
2 files changed, 12 insertions, 8 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index a6e5be04697b..c2561ea1cdb3 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -245,11 +245,12 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec)
{
struct vc4_dev *vc4 = to_vc4_dev(dev);
uint64_t seqno = ++vc4->emit_seqno;
+ unsigned long irqflags;
exec->seqno = seqno;
vc4_update_bo_seqnos(exec, seqno);
- spin_lock(&vc4->job_lock);
+ spin_lock_irqsave(&vc4->job_lock, irqflags);
list_add_tail(&exec->head, &vc4->job_list);
/* If no job was executing, kick ours off. Otherwise, it'll
@@ -261,7 +262,7 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec)
vc4_queue_hangcheck(dev);
}
- spin_unlock(&vc4->job_lock);
+ spin_unlock_irqrestore(&vc4->job_lock, irqflags);
}
/**
@@ -488,22 +489,23 @@ vc4_job_done_work(struct work_struct *work)
struct vc4_dev *vc4 =
container_of(work, struct vc4_dev, job_done_work);
struct drm_device *dev = vc4->dev;
+ unsigned long irqflags;
/* Need the struct lock for drm_gem_object_unreference(). */
mutex_lock(&dev->struct_mutex);
- spin_lock(&vc4->job_lock);
+ spin_lock_irqsave(&vc4->job_lock, irqflags);
while (!list_empty(&vc4->job_done_list)) {
struct vc4_exec_info *exec =
list_first_entry(&vc4->job_done_list,
struct vc4_exec_info, head);
list_del(&exec->head);
- spin_unlock(&vc4->job_lock);
+ spin_unlock_irqrestore(&vc4->job_lock, irqflags);
vc4_complete_exec(exec);
- spin_lock(&vc4->job_lock);
+ spin_lock_irqsave(&vc4->job_lock, irqflags);
}
- spin_unlock(&vc4->job_lock);
+ spin_unlock_irqrestore(&vc4->job_lock, irqflags);
mutex_unlock(&dev->struct_mutex);
}
diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c
index f39d80dafdd1..5af0e6ff5318 100644
--- a/drivers/gpu/drm/vc4/vc4_irq.c
+++ b/drivers/gpu/drm/vc4/vc4_irq.c
@@ -55,7 +55,9 @@ vc4_overflow_mem_work(struct work_struct *work)
*/
if (vc4->overflow_mem) {
struct vc4_exec_info *current_exec;
- spin_lock(&vc4->job_lock);
+ unsigned long irqflags;
+
+ spin_lock_irqsave(&vc4->job_lock, irqflags);
current_exec = vc4_first_job(vc4);
if (current_exec) {
vc4->overflow_mem->seqno = vc4->finished_seqno + 1;
@@ -63,7 +65,7 @@ vc4_overflow_mem_work(struct work_struct *work)
&current_exec->unref_list);
vc4->overflow_mem = NULL;
}
- spin_unlock(&vc4->job_lock);
+ spin_unlock_irqrestore(&vc4->job_lock, irqflags);
}
if (vc4->overflow_mem) {