aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSandor Yu <R01008@freescale.com>2014-01-15 03:50:04 -0500
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:57:22 -0400
commitb3c1a14efdd724f33b39eb534fa0147c0ad67c76 (patch)
tree7c9da55e6998a68b13603c29c4800438d694fec6
parent0e775c1e48110c9663d3710b50f14bca3575438a (diff)
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 [#1] SMP ARM Modules linked in: CPU: 0 PID: 50 Comm: ipu2_task Not tainted 3.10.17-02308-g3700819 #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 : 814f92a0 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>
-rw-r--r--drivers/mxc/ipu3/ipu_device.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/mxc/ipu3/ipu_device.c b/drivers/mxc/ipu3/ipu_device.c
index 8f6b957de3b0..f1f6ad16ff20 100644
--- a/drivers/mxc/ipu3/ipu_device.c
+++ b/drivers/mxc/ipu3/ipu_device.c
@@ -286,6 +286,7 @@ struct ipu_task_entry {
286 u8 task_in_list; 286 u8 task_in_list;
287 u8 split_done; 287 u8 split_done;
288 struct mutex split_lock; 288 struct mutex split_lock;
289 struct mutex vdic_lock;
289 wait_queue_head_t split_waitq; 290 wait_queue_head_t split_waitq;
290 291
291 struct list_head node; 292 struct list_head node;
@@ -1697,10 +1698,12 @@ static int queue_split_task(struct ipu_task_entry *t,
1697 int i, j; 1698 int i, j;
1698 struct ipu_task_entry *tsk = NULL; 1699 struct ipu_task_entry *tsk = NULL;
1699 struct mutex *lock = &t->split_lock; 1700 struct mutex *lock = &t->split_lock;
1701 struct mutex *vdic_lock = &t->vdic_lock;
1700 1702
1701 dev_dbg(t->dev, "Split task 0x%p, no-0x%x, size:%d\n", 1703 dev_dbg(t->dev, "Split task 0x%p, no-0x%x, size:%d\n",
1702 t, t->task_no, size); 1704 t, t->task_no, size);
1703 mutex_init(lock); 1705 mutex_init(lock);
1706 mutex_init(vdic_lock);
1704 init_waitqueue_head(&t->split_waitq); 1707 init_waitqueue_head(&t->split_waitq);
1705 INIT_LIST_HEAD(&t->split_list); 1708 INIT_LIST_HEAD(&t->split_list);
1706 for (j = 0; j < size; j++) { 1709 for (j = 0; j < size; j++) {
@@ -2389,11 +2392,13 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
2389 u32 line_size; 2392 u32 line_size;
2390 unsigned char *base_off; 2393 unsigned char *base_off;
2391 struct ipu_task_entry *parent = t->parent; 2394 struct ipu_task_entry *parent = t->parent;
2395 struct mutex *lock = &parent->vdic_lock;
2392 2396
2393 if (!parent) { 2397 if (!parent) {
2394 dev_err(t->dev, "ERR[0x%x]invalid parent\n", t->task_no); 2398 dev_err(t->dev, "ERR[0x%x]invalid parent\n", t->task_no);
2395 return; 2399 return;
2396 } 2400 }
2401 mutex_lock(lock);
2397 stripe_mode = t->task_no & 0xf; 2402 stripe_mode = t->task_no & 0xf;
2398 task_no = t->task_no >> 4; 2403 task_no = t->task_no >> 4;
2399 2404
@@ -2410,6 +2415,7 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
2410 vdi_size = vdi_save_lines * line_size; 2415 vdi_size = vdi_save_lines * line_size;
2411 if (vdi_save_lines <= 0) { 2416 if (vdi_save_lines <= 0) {
2412 dev_err(t->dev, "[0x%p] vdi_save_line error\n", (void *)t); 2417 dev_err(t->dev, "[0x%p] vdi_save_line error\n", (void *)t);
2418 mutex_unlock(lock);
2413 return; 2419 return;
2414 } 2420 }
2415 2421
@@ -2425,6 +2431,7 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
2425 if (parent->vditmpbuf[0] == NULL) { 2431 if (parent->vditmpbuf[0] == NULL) {
2426 dev_err(t->dev, 2432 dev_err(t->dev,
2427 "[0x%p]Falied Alloc vditmpbuf[0]\n", (void *)t); 2433 "[0x%p]Falied Alloc vditmpbuf[0]\n", (void *)t);
2434 mutex_unlock(lock);
2428 return; 2435 return;
2429 } 2436 }
2430 memset(parent->vditmpbuf[0], 0, vdi_size); 2437 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)
2433 if (parent->vditmpbuf[1] == NULL) { 2440 if (parent->vditmpbuf[1] == NULL) {
2434 dev_err(t->dev, 2441 dev_err(t->dev,
2435 "[0x%p]Falied Alloc vditmpbuf[1]\n", (void *)t); 2442 "[0x%p]Falied Alloc vditmpbuf[1]\n", (void *)t);
2443 mutex_unlock(lock);
2436 return; 2444 return;
2437 } 2445 }
2438 memset(parent->vditmpbuf[1], 0, vdi_size); 2446 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)
2451 } 2459 }
2452 if (base_off == NULL) { 2460 if (base_off == NULL) {
2453 dev_err(t->dev, "ERR[0x%p]Failed get virtual address\n", t); 2461 dev_err(t->dev, "ERR[0x%p]Failed get virtual address\n", t);
2462 mutex_unlock(lock);
2454 return; 2463 return;
2455 } 2464 }
2456 2465
@@ -2573,6 +2582,7 @@ static void vdi_split_process(struct ipu_soc *ipu, struct ipu_task_entry *t)
2573 } 2582 }
2574 if (!pfn_valid(t->output.paddr >> PAGE_SHIFT)) 2583 if (!pfn_valid(t->output.paddr >> PAGE_SHIFT))
2575 iounmap(base_off); 2584 iounmap(base_off);
2585 mutex_unlock(lock);
2576} 2586}
2577 2587
2578static void do_task_release(struct ipu_task_entry *t, int fail) 2588static void do_task_release(struct ipu_task_entry *t, int fail)