video: rockchip: mpp: Fix issue for multi-core jpeg encoder

tips:
1. each task may work different core, thus, if use session->mpp
   then it will be change when each alloc task.
2. alloc_task and isr are in the different thread, so, the session->mpp
   will be overwrite when following task alloc.
3. based above, use task->mpp instead of session->mpp is the better.

backtrace when error:
[   36.421939 ][  T160 ] mpp_vepu2 fdba4000.jpege-core: no current task
[   36.623432 ][    C6 ] Unable to handle kernel NULL pointerdereference at virtual address 0000000000000102
[   36.624290 ][    C6 ] Mem abort info:
[   36.624615 ][    C6 ]   ESR = 0x96000005
[   36.624966 ][    C6 ]   EC = 0x25: DABT (current EL), IL = 32 bits
[   36.625509 ][    C6 ]   SET = 0, FnV = 0
[   36.625856 ][    C6 ]   EA = 0, S1PTW = 0
[   36.626212 ][    C6 ] Data abort info:
[   36.626546 ][    C6 ]   ISV = 0, ISS = 0x00000005
[   36.626953 ][    C6 ]   CM = 0, WnR = 0
[   36.627292 ][    C6 ] user pgtable: 4k pages, 39-bit VAs,pgdp=0000000107211000
[   36.627934 ][    C6 ] [0000000000000102] pgd=0000000000000000,p4d=0000000000000000, pud=0000000000000000
[   36.628797 ][    C6 ] Internal error: Oops: 96000005 [#1] PREEMPT SMP
[   36.629365 ][    C6 ] Modules linked in: bcmdhd r8168
[   36.629843 ][    C6 ] CPU: 6 PID: 0 Comm: swapper/6 Not tainted5.10.66 #1092
[   36.630472 ][    C6 ] Hardware name: Rockchip RK3588 EVB1 LP4 V10Board (DT)
[   36.631095 ][    C6 ] pstate: 20400089 (nzCv daIf +PAN -UAO -TCOBTYPE=--)
[   36.631721 ][    C6 ] pc : __queue_work+0x24/0x538
[   36.632154 ][    C6 ] lr : delayed_work_timer_fn+0x24/0x34

Change-Id: I610f16ec33ef29217975779ba5d09c7274009c61
Signed-off-by: Ding Wei <leo.ding@rock-chips.com>
This commit is contained in:
Ding Wei
2022-02-24 10:55:59 +08:00
committed by Tao Huang
parent 2272d9dec7
commit 8ac72c875a
2 changed files with 52 additions and 13 deletions

View File

@@ -498,13 +498,7 @@ void mpp_free_task(struct kref *ref)
session->index, task->task_index, task->state,
atomic_read(&task->abort_request));
mpp = session->mpp;
if (!mpp) {
mpp_err("task %d:%d mpp is null.\n",
session->index, task->task_index);
return;
}
mpp = mpp_get_task_used_device(task, session);
if (mpp->dev_ops->free_task)
mpp->dev_ops->free_task(session, task);
@@ -537,8 +531,8 @@ static void mpp_task_timeout_work(struct work_struct *work_s)
mpp_err("session %p, session->mpp is null.\n", session);
return;
}
mpp = session->mpp;
mpp = mpp_get_task_used_device(task, session);
/* hardware maybe dead, reset it */
mpp_reset_up_read(mpp->reset_group);
mpp_dev_reset(mpp);
@@ -571,6 +565,9 @@ static int mpp_process_task_default(struct mpp_session *session,
mpp_err("alloc_task failed.\n");
return -ENOMEM;
}
/* ensure current device */
mpp = mpp_get_task_used_device(task, session);
kref_init(&task->ref);
init_waitqueue_head(&task->wait);
atomic_set(&task->abort_request, 0);
@@ -1701,7 +1698,7 @@ int mpp_translate_reg_address(struct mpp_session *session,
cnt = session->trans_count;
tbl = session->trans_table;
} else {
struct mpp_dev *mpp = session->mpp;
struct mpp_dev *mpp = mpp_get_task_used_device(task, session);
struct mpp_trans_info *trans_info = mpp->var->trans_info;
cnt = trans_info[fmt].count;

View File

@@ -328,15 +328,57 @@ static struct vepu_dev *vepu_core_balance(struct vepu_ccu *ccu)
static void *vepu_ccu_alloc_task(struct mpp_session *session,
struct mpp_task_msgs *msgs)
{
struct vepu_dev *enc = to_vepu_dev(session->mpp);
int ret;
struct mpp_task *mpp_task = NULL;
struct vepu_task *task = NULL;
struct mpp_dev *mpp = session->mpp;
struct vepu_dev *enc = to_vepu_dev(mpp);
/* if multi-cores, choose one for current task */
mpp_debug_enter();
task = kzalloc(sizeof(*task), GFP_KERNEL);
if (!task)
return NULL;
mpp_task = &task->mpp_task;
/* if multicore, choose one for current task */
if (enc->ccu) {
enc = vepu_core_balance(enc->ccu);
session->mpp = &enc->mpp;
mpp_task->mpp = &enc->mpp;
mpp = mpp_task->mpp;
mpp_debug(DEBUG_TASK_INFO, "%s\n", dev_name(mpp->dev));
}
return vepu_alloc_task(session, msgs);
mpp_task_init(session, mpp_task);
mpp_task->hw_info = mpp->var->hw_info;
mpp_task->reg = task->reg;
/* extract reqs for current task */
ret = vepu_extract_task_msg(task, msgs);
if (ret)
goto fail;
/* process fd in register */
if (!(msgs->flags & MPP_FLAGS_REG_FD_NO_TRANS)) {
ret = vepu_process_reg_fd(session, task, msgs);
if (ret)
goto fail;
}
task->clk_mode = CLK_MODE_NORMAL;
/* get resolution info */
task->width = VEPU2_GET_WIDTH(task->reg[VEPU2_REG_ENC_EN_INDEX]);
task->height = VEPU2_GET_HEIGHT(task->reg[VEPU2_REG_ENC_EN_INDEX]);
task->pixels = task->width * task->height;
mpp_debug(DEBUG_TASK_INFO, "width=%d, height=%d\n", task->width, task->height);
mpp_debug_leave();
return mpp_task;
fail:
mpp_task_dump_mem_region(mpp, mpp_task);
mpp_task_dump_reg(mpp, mpp_task);
mpp_task_finalize(session, mpp_task);
kfree(task);
return NULL;
}
static int vepu_run(struct mpp_dev *mpp,