video: rockchip: mpp: Use spinlock for queue->running_lock

reason: mpp_iommu_handle is called by irq for iommu, thus it cannot
use mutex which might case sleep, thus use spinlock instead.

Call trace:
[   71.047958 ] Call trace:
[   71.047974 ]  dump_backtrace+0x0/0x160
[   71.047988 ]  show_stack+0x14/0x1c
[   71.048003 ]  dump_stack+0xd0/0x120
[   71.048018 ]  ___might_sleep+0x1f4/0x204
[   71.048032 ]  __might_sleep+0x4c/0x80
[   71.048045 ]  __mutex_lock_common+0x60/0x1028
[   71.048057 ]  mutex_lock_nested+0x28/0x30
[   71.048073 ]  mpp_iommu_handle+0x44/0x1c8
[   71.048088 ]  report_iommu_fault+0x3c/0x198
[   71.048102 ]  rk_iommu_irq+0x2a4/0x3bc
[   71.048117 ]  __handle_irq_event_percpu+0x114/0x3c4
[   71.048131 ]  handle_irq_event+0x5c/0xd0
[   71.048143 ]  handle_fasteoi_irq+0x124/0x220
[   71.048156 ]  __handle_domain_irq+0x9c/0xf4
[   71.048169 ]  gic_handle_irq+0x108/0x180
[   71.048181 ]  el1_irq+0xec/0x1a0
[   71.048194 ]  _raw_spin_unlock_irqrestore+0x3c/0x78
[   71.048209 ]  vop2_crtc_atomic_flush+0x1c78/0x202c
[   71.048223 ]  drm_atomic_helper_commit_planes+0x1a4/0x210
[   71.048238 ]  rockchip_atomic_commit_complete+0x1a4/0x390
[   71.048252 ]  rockchip_drm_atomic_commit+0x22c/0x24c
[   71.048266 ]  drm_mode_atomic_ioctl+0xa18/0xddc
[   71.048280 ]  drm_ioctl+0x2d8/0x46c
[   71.048296 ]  do_vfs_ioctl+0x4dc/0x794
[   71.048308 ]  __arm64_sys_ioctl+0x70/0x98
[   71.048322 ]  el0_svc_common+0xa0/0x18c
[   71.048335 ]  el0_svc_handler+0x28/0x60
[   71.048348 ]  el0_svc+0x8/0xc

Change-Id: Ie8e79995ec4bebf4ccbb509a57306541de861754
Signed-off-by: Ding Wei <leo.ding@rock-chips.com>
This commit is contained in:
Ding Wei
2021-10-15 11:15:17 +08:00
committed by Tao Huang
parent 3ea11abdbe
commit fd69926be3
3 changed files with 20 additions and 12 deletions

View File

@@ -138,11 +138,12 @@ mpp_taskqueue_get_pending_task(struct mpp_taskqueue *queue)
static bool
mpp_taskqueue_is_running(struct mpp_taskqueue *queue)
{
unsigned long flags;
bool flag;
mutex_lock(&queue->running_lock);
spin_lock_irqsave(&queue->running_lock, flags);
flag = !list_empty(&queue->running_list);
mutex_unlock(&queue->running_lock);
spin_unlock_irqrestore(&queue->running_lock, flags);
return flag;
}
@@ -151,10 +152,13 @@ static int
mpp_taskqueue_pending_to_run(struct mpp_taskqueue *queue,
struct mpp_task *task)
{
unsigned long flags;
mutex_lock(&queue->pending_lock);
mutex_lock(&queue->running_lock);
spin_lock_irqsave(&queue->running_lock, flags);
list_move_tail(&task->queue_link, &queue->running_list);
mutex_unlock(&queue->running_lock);
spin_unlock_irqrestore(&queue->running_lock, flags);
mutex_unlock(&queue->pending_lock);
return 0;
@@ -163,13 +167,14 @@ mpp_taskqueue_pending_to_run(struct mpp_taskqueue *queue,
static struct mpp_task *
mpp_taskqueue_get_running_task(struct mpp_taskqueue *queue)
{
unsigned long flags;
struct mpp_task *task = NULL;
mutex_lock(&queue->running_lock);
spin_lock_irqsave(&queue->running_lock, flags);
task = list_first_entry_or_null(&queue->running_list,
struct mpp_task,
queue_link);
mutex_unlock(&queue->running_lock);
spin_unlock_irqrestore(&queue->running_lock, flags);
return task;
}
@@ -178,12 +183,14 @@ static int
mpp_taskqueue_pop_running(struct mpp_taskqueue *queue,
struct mpp_task *task)
{
unsigned long flags;
if (!task->session || !task->session->mpp)
return -EINVAL;
mutex_lock(&queue->running_lock);
spin_lock_irqsave(&queue->running_lock, flags);
list_del_init(&task->queue_link);
mutex_unlock(&queue->running_lock);
spin_unlock_irqrestore(&queue->running_lock, flags);
kref_put(&task->ref, mpp_free_task);
return 0;
@@ -941,7 +948,7 @@ struct mpp_taskqueue *mpp_taskqueue_init(struct device *dev)
mutex_init(&queue->session_lock);
mutex_init(&queue->pending_lock);
mutex_init(&queue->running_lock);
spin_lock_init(&queue->running_lock);
mutex_init(&queue->mmu_lock);
mutex_init(&queue->dev_lock);
INIT_LIST_HEAD(&queue->session_attach);

View File

@@ -433,7 +433,7 @@ struct mpp_taskqueue {
struct mutex pending_lock;
struct list_head pending_list;
/* lock for running list */
struct mutex running_lock;
spinlock_t running_lock;
struct list_head running_list;
/* point to MPP Service */

View File

@@ -855,12 +855,13 @@ fail:
static void *rkvdec_prepare_with_reset(struct mpp_dev *mpp,
struct mpp_task *mpp_task)
{
unsigned long flags;
struct mpp_task *out_task = NULL;
struct rkvdec_dev *dec = to_rkvdec_dev(mpp);
mutex_lock(&mpp->queue->running_lock);
spin_lock_irqsave(&mpp->queue->running_lock, flags);
out_task = list_empty(&mpp->queue->running_list) ? mpp_task : NULL;
mutex_unlock(&mpp->queue->running_lock);
spin_unlock_irqrestore(&mpp->queue->running_lock, flags);
if (out_task && !dec->had_reset) {
struct rkvdec_task *task = to_rkvdec_task(out_task);