diff options
author | Eric Anholt <eric@anholt.net> | 2015-05-14 11:32:24 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2015-06-04 14:15:35 -0700 |
commit | eb4fdfd674ab976fed764b6c606c9963c183906a (patch) | |
tree | 965093aeae52ad9983cc68c980bb61154cafcbd6 | |
parent | 1fafb6cab83be514ca37d8701dc5a789abb3b333 (diff) | |
download | linux-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.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_irq.c | 6 |
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) ¤t_exec->unref_list); vc4->overflow_mem = NULL; } - spin_unlock(&vc4->job_lock); + spin_unlock_irqrestore(&vc4->job_lock, irqflags); } if (vc4->overflow_mem) { |