Skip to content

Commit b3c1a14

Browse files
Sandor YuNitin Garg
authored andcommitted
ENGR00295201 ipuv3: vdic: kernel dump when run deinterlace stress test
Kernel will dump when run deinterlace stress test. It is caused by vditmpbuf being reallocated by another thread when one thread accesses it. Issue is fixed by putting these code in mutex. Kernel dump log: [Playing ][Vol=01][00:00:10/00:00:30][fps:32]Unable to handle kernel paging request at virtual address 607d6085 pgd = 80004000 [607d6085] *pgd=00000000 Internal error: Oops: 5 [wandboard-org#1] SMP ARM Modules linked in: CPU: 0 PID: 50 Comm: ipu2_task Not tainted 3.10.17-02308-g3700819 torvalds#28 task: ac1dc700 ti: ac1ba000 task.ti: ac1ba000 PC is at __kmalloc+0x40/0x114 LR is at __kmalloc+0x14/0x114 pc : [<800bbd40>] lr : [<800bbd14>] psr: 200f0013 sp : ac1bbbc8 ip : 008cc000 fp : 00001e40 r10: ac772e00 r9 : 0057b255 r8 : 000000d0 r7 : 00000790 r6 : ac773800 r5 : 607d6085 r4 : ac001b00 r3 : 00000000 r2 : 814f92a r1 : 000000d0 r0 : 000398c9 Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c53c7d Table: 3c4c004a DAC: 00000015 Process ipu2_task (pid: 50, stack limit = 0xac1ba238) Stack: (0xac1bbbc8 to 0xac1bc000) Signed-off-by: Sandor Yu <R01008@freescale.com>
1 parent 0e775c1 commit b3c1a14

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

drivers/mxc/ipu3/ipu_device.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ struct ipu_task_entry {
286286
u8 task_in_list;
287287
u8 split_done;
288288
struct mutex split_lock;
289+
struct mutex vdic_lock;
289290
wait_queue_head_t split_waitq;
290291

291292
struct list_head node;
@@ -1697,10 +1698,12 @@ static int queue_split_task(struct ipu_task_entry *t,
16971698
int i, j;
16981699
struct ipu_task_entry *tsk = NULL;
16991700
struct mutex *lock = &t->split_lock;
1701+
struct mutex *vdic_lock = &t->vdic_lock;
17001702

17011703
dev_dbg(t->dev, "Split task 0x%p, no-0x%x, size:%d\n",
17021704
t, t->task_no, size);
17031705
mutex_init(lock);
1706+
mutex_init(vdic_lock);
17041707
init_waitqueue_head(&t->split_waitq);
17051708
INIT_LIST_HEAD(&t->split_list);
17061709
for (j = 0; j < size; j++) {
@@ -2389,11 +2392,13 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
23892392
u32 line_size;
23902393
unsigned char *base_off;
23912394
struct ipu_task_entry *parent = t->parent;
2395+
struct mutex *lock = &parent->vdic_lock;
23922396

23932397
if (!parent) {
23942398
dev_err(t->dev, "ERR[0x%x]invalid parent\n", t->task_no);
23952399
return;
23962400
}
2401+
mutex_lock(lock);
23972402
stripe_mode = t->task_no & 0xf;
23982403
task_no = t->task_no >> 4;
23992404

@@ -2410,6 +2415,7 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
24102415
vdi_size = vdi_save_lines * line_size;
24112416
if (vdi_save_lines <= 0) {
24122417
dev_err(t->dev, "[0x%p] vdi_save_line error\n", (void *)t);
2418+
mutex_unlock(lock);
24132419
return;
24142420
}
24152421

@@ -2425,6 +2431,7 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
24252431
if (parent->vditmpbuf[0] == NULL) {
24262432
dev_err(t->dev,
24272433
"[0x%p]Falied Alloc vditmpbuf[0]\n", (void *)t);
2434+
mutex_unlock(lock);
24282435
return;
24292436
}
24302437
memset(parent->vditmpbuf[0], 0, vdi_size);
@@ -2433,6 +2440,7 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
24332440
if (parent->vditmpbuf[1] == NULL) {
24342441
dev_err(t->dev,
24352442
"[0x%p]Falied Alloc vditmpbuf[1]\n", (void *)t);
2443+
mutex_unlock(lock);
24362444
return;
24372445
}
24382446
memset(parent->vditmpbuf[1], 0, vdi_size);
@@ -2451,6 +2459,7 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
24512459
}
24522460
if (base_off == NULL) {
24532461
dev_err(t->dev, "ERR[0x%p]Failed get virtual address\n", t);
2462+
mutex_unlock(lock);
24542463
return;
24552464
}
24562465

@@ -2573,6 +2582,7 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
25732582
}
25742583
if (!pfn_valid(t->output.paddr >> PAGE_SHIFT))
25752584
iounmap(base_off);
2585+
mutex_unlock(lock);
25762586
}
25772587

25782588
static void do_task_release(struct ipu_task_entry *t, int fail)

0 commit comments

Comments
 (0)