Skip to content
Snippets Groups Projects
Commit 1e35d59a authored by Alice Yuan's avatar Alice Yuan
Browse files

LF-4238 media: isi: fix the null point kernel panic


fix kernel null point panic
when basler camera output for m2m input pipeline created

test cmd: gst-launch-1.0 v4l2src device=/dev/video3 !
video/x-raw,format=YUY2 ! v4l2convert ! video/x-raw,
format=RGB ! videoconvert ! fakesink

[   80.780665] enter isp_s_comp
[   80.783562] enter isp_s_comp
[   80.806629] enter wdr3_hw_init
[   80.809714] wdr3 res: 3840 2160
CamEngineEnableCproc: set val  1 [   80.813793] enter isp_mi_start
1 1 1.10 -15 1.00 0.00
[   81.133511] isi-m2m 32e00000.isi:m2m_device: m2m_vb2_queue_setup
[   81.139585] isi-m2m 32e00000.isi:m2m_device: m2m_vb2_queue_setup, buf_n=2, planes[0]->size=16588800
[   81.308157] isi-m2m 32e00000.isi:m2m_device: mxc_isi_m2m_job_ready
[   81.314419] isi-m2m 32e00000.isi:m2m_device: mxc_isi_m2m_device_run enter
[   81.321290] BUG: scheduling while atomic: v4l2src0:src/639/0x00000002
[   81.327729] Modules linked in: vvcam_dwe(O) vvcam_video(O) vvcam_isp(O) imx8_media_dev(C) basler_camera_driver_vvcam(O)
[   81.338523] CPU: 0 PID: 639 Comm: v4l2src0:src Tainted: G         C O      5.10.52-05403-g1994e5c9c0a1-dirty #1
[   81.348605] Hardware name: NXP i.MX8MPlus EVK board (DT)
[   81.353912] Call trace:
[   81.356363]  dump_backtrace+0x0/0x1a0
[   81.360023]  show_stack+0x18/0x70
[   81.363339]  dump_stack+0xd0/0x12c
[   81.366738]  __schedule_bug+0x60/0x80
[   81.370399]  __schedule+0x67c/0x6d0
[   81.373885]  schedule+0x70/0x104
[   81.377111]  schedule_timeout+0x84/0xfc
[   81.380945]  msleep+0x2c/0x40
[   81.383912]  mxc_isi_channel_enable+0x74/0xc0
[   81.388266]  mxc_isi_m2m_device_run+0x80/0xc0
[   81.392620]  v4l2_m2m_try_run+0x84/0x134
[   81.396541]  v4l2_m2m_ioctl_streamon+0x68/0x80
[   81.400982]  mxc_isi_m2m_streamon+0x70/0xbc
[   81.405163]  v4l_streamon+0x28/0x34
[   81.408650]  __video_do_ioctl+0x180/0x3e4
[   81.412658]  video_usercopy+0x1a0/0x450
[   81.416491]  video_ioctl2+0x18/0x24
[   81.419978]  v4l2_ioctl+0x44/0x64
[   81.423292]  __arm64_sys_ioctl+0xa8/0xf0
[   81.427213]  el0_svc_common.constprop.0+0x78/0x1a0
[   81.432001]  do_el0_svc+0x24/0x90
[   81.435314]  el0_svc+0x14/0x20
[   81.438366]  el0_sync_handler+0x1a4/0x1b0
[   81.442373]  el0_sync+0x180/0x1c0
[   81.445745] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000a60
[   81.454530] Mem abort info:
[   81.457320]   ESR = 0x96000004
[   81.460371]   EC = 0x25: DABT (current EL), IL = 32 bits
[   81.465679]   SET = 0, FnV = 0
[   81.468729]   EA = 0, S1PTW = 0
[   81.471866] Data abort info:
[   81.474743]   ISV = 0, ISS = 0x00000004
[   81.478575]   CM = 0, WnR = 0
[   81.481539] user pgtable: 4k pages, 48-bit VAs, pgdp=00000001064d0000
[   81.487975] [0000000000000a60] pgd=0000000000000000, p4d=0000000000000000
[   81.494764] Internal error: Oops: 96000004 [#1] PREEMPT SMP
[   81.500333] Modules linked in: vvcam_dwe(O) vvcam_video(O) vvcam_isp(O) imx8_media_dev(C) basler_camera_driver_vvcam(O)
[   81.511124] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        WC O      5.10.52-05403-g1994e5c9c0a1-dirty #1
[   81.520773] Hardware name: NXP i.MX8MPlus EVK board (DT)
[   81.526082] pstate: 40000085 (nZcv daIf -PAN -UAO -TCO BTYPE=--)
[   81.532092] pc : mxc_isi_cap_frame_write_done+0x2c/0x1fc
[   81.537401] lr : mxc_isi_irq_handler+0x84/0x90
[   81.541840] sp : ffff800011d0bbf0
[   81.545150] x29: ffff800011d0bbf0 x28: ffff800011b02340
[   81.550461] x27: 0000000000000280 x26: ffff8000115d2c90
[   81.555771] x25: ffff800011c4856a x24: 00000000000016c8
[   81.561082] x23: 0000000000000039 x22: ffff0000c18a1530
[   81.566393] x21: 0000000000001600 x20: 0000000060020100
[   81.571703] x19: 0000000000000000 x18: 0000000000000030
[   81.577013] x17: 0000000000000000 x16: 0000000000000000
[   81.582324] x15: 0000000fcc57dcca x14: 00000000000000ed
[   81.587634] x13: 0000000000000000 x12: 0000000000000040
[   81.592946] x11: ffff0000c20a5ff0 x10: ffff0000c20a5ff2
[   81.598257] x9 : ffff800011b81788 x8 : ffff0000c2000270
[   81.603567] x7 : 0000000000000000 x6 : ffff0000c2000430
[   81.608878] x5 : ffff0000c2000248 x4 : 00000000000016c8
[   81.614188] x3 : 0000000000001600 x2 : 0000000000000001
[   81.619499] x1 : 0000000060020100 x0 : ffff0000c18a1480
[   81.624809] Call trace:
[   81.627255]  mxc_isi_cap_frame_write_done+0x2c/0x1fc
[   81.632217]  mxc_isi_irq_handler+0x84/0x90
[   81.636312]  __handle_irq_event_percpu+0x54/0x170
[   81.641013]  handle_irq_event+0x68/0x150
[   81.644934]  handle_fasteoi_irq+0xa4/0x1f4
[   81.649027]  __handle_domain_irq+0x7c/0xe0
[   81.653122]  gic_handle_irq+0xc0/0x140
[   81.656869]  el1_irq+0xcc/0x180
[   81.660007]  efi_header_end+0xa4/0x290
[   81.663754]  irq_exit+0xdc/0xfc
[   81.666893]  __handle_domain_irq+0x80/0xe0
[   81.670986]  gic_handle_irq+0xc0/0x140
[   81.674732]  el1_irq+0xcc/0x180
[   81.677875]  _raw_spin_unlock_irq+0x14/0x50
[   81.682056]  __schedule+0x260/0x6d0
[   81.685543]  schedule_idle+0x28/0x50
[   81.689117]  do_idle+0x198/0x2a0
[   81.692343]  cpu_startup_entry+0x24/0x70
[   81.696263]  rest_init+0xd8/0xe8
[   81.699491]  arch_call_rest_init+0x10/0x1c
[   81.703584]  start_kernel+0x4ac/0x4e4
[   81.707247] Code: a90363f7 f9400013 8b030275 8b040278 (f9453277)
[   81.713344] ---[ end trace 1a1c3af55549f42e ]---
[   81.717959] Kernel panic - not syncing: Oops: Fatal exception in interrupt
[   81.724830] SMP: stopping secondary CPUs
[   81.729069] Kernel Offset: disabled
[   81.732555] CPU features: 0x0240002,2000200c
[   81.736820] Memory Limit: none

root cause: when user is multi-processing "imx-isi-m2m" node,
the driver of "imx-isi-m2m" open and close
should have concurrent protection.

Signed-off-by: default avatarAlice Yuan <alice.yuan@nxp.com>
Reviewed-by: default avatarRobby Cai <Robby.Cai@nxp.com>
parent 9ed88c24
No related branches found
No related tags found
No related merge requests found
...@@ -227,6 +227,7 @@ struct mxc_isi_m2m_dev { ...@@ -227,6 +227,7 @@ struct mxc_isi_m2m_dev {
u32 req_out_buf_num; u32 req_out_buf_num;
u8 id; u8 id;
int refcnt;
}; };
struct mxc_isi_ctx { struct mxc_isi_ctx {
......
...@@ -532,14 +532,16 @@ static int mxc_isi_m2m_open(struct file *file) ...@@ -532,14 +532,16 @@ static int mxc_isi_m2m_open(struct file *file)
struct mxc_isi_ctx *mxc_ctx = NULL; struct mxc_isi_ctx *mxc_ctx = NULL;
int ret = 0; int ret = 0;
mutex_lock(&isi_m2m->lock);
if (isi_m2m->refcnt > 0)
goto unlock;
if (mxc_isi->cap_enabled) { if (mxc_isi->cap_enabled) {
dev_err(dev, "ISI channel[%d] is busy\n", isi_m2m->id); dev_err(dev, "ISI channel[%d] is busy\n", isi_m2m->id);
return -EBUSY; ret = -EBUSY;
goto unlock;
} }
if (mutex_lock_interruptible(&isi_m2m->lock))
return -ERESTARTSYS;
mxc_ctx = kzalloc(sizeof(*mxc_ctx), GFP_KERNEL); mxc_ctx = kzalloc(sizeof(*mxc_ctx), GFP_KERNEL);
if (!mxc_ctx) { if (!mxc_ctx) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -567,14 +569,14 @@ static int mxc_isi_m2m_open(struct file *file) ...@@ -567,14 +569,14 @@ static int mxc_isi_m2m_open(struct file *file)
isi_m2m_fmt_init(&isi_m2m->dst_f, &mxc_isi_out_formats[0]); isi_m2m_fmt_init(&isi_m2m->dst_f, &mxc_isi_out_formats[0]);
pm_runtime_get_sync(dev); pm_runtime_get_sync(dev);
if (atomic_inc_return(&mxc_isi->usage_count) == 1) mxc_isi_channel_init(mxc_isi);
mxc_isi_channel_init(mxc_isi);
/* lock host data */ /* lock host data */
mutex_lock(&mxc_isi->lock);
mxc_isi->m2m_enabled = true; mxc_isi->m2m_enabled = true;
mutex_unlock(&mxc_isi->lock); goto unlock;
unlock: unlock:
isi_m2m->refcnt++;
mutex_unlock(&isi_m2m->lock); mutex_unlock(&isi_m2m->lock);
return ret; return ret;
} }
...@@ -586,22 +588,24 @@ static int mxc_isi_m2m_release(struct file *file) ...@@ -586,22 +588,24 @@ static int mxc_isi_m2m_release(struct file *file)
struct device *dev = &isi_m2m->pdev->dev; struct device *dev = &isi_m2m->pdev->dev;
struct mxc_isi_ctx *mxc_ctx = file_to_ctx(file); struct mxc_isi_ctx *mxc_ctx = file_to_ctx(file);
v4l2_fh_del(&mxc_ctx->fh);
v4l2_fh_exit(&mxc_ctx->fh);
mutex_lock(&isi_m2m->lock); mutex_lock(&isi_m2m->lock);
v4l2_m2m_ctx_release(mxc_ctx->fh.m2m_ctx); isi_m2m->refcnt--;
mutex_unlock(&isi_m2m->lock); if (isi_m2m->refcnt == 0) {
v4l2_fh_del(&mxc_ctx->fh);
v4l2_fh_exit(&mxc_ctx->fh);
v4l2_m2m_ctx_release(mxc_ctx->fh.m2m_ctx);
kfree(mxc_ctx); kfree(mxc_ctx);
if (atomic_dec_and_test(&mxc_isi->usage_count))
mxc_isi_channel_deinit(mxc_isi); mxc_isi_channel_deinit(mxc_isi);
mutex_lock(&mxc_isi->lock); mxc_isi->m2m_enabled = false;
mxc_isi->m2m_enabled = false;
mutex_unlock(&mxc_isi->lock); pm_runtime_put(dev);
}
mutex_unlock(&isi_m2m->lock);
pm_runtime_put(dev);
return 0; return 0;
} }
...@@ -1255,7 +1259,7 @@ static int isi_m2m_probe(struct platform_device *pdev) ...@@ -1255,7 +1259,7 @@ static int isi_m2m_probe(struct platform_device *pdev)
} }
mxc_isi->isi_m2m = isi_m2m; mxc_isi->isi_m2m = isi_m2m;
isi_m2m->id = mxc_isi->id; isi_m2m->id = mxc_isi->id;
isi_m2m->refcnt = 0;
isi_m2m->colorspace = V4L2_COLORSPACE_SRGB; isi_m2m->colorspace = V4L2_COLORSPACE_SRGB;
isi_m2m->quant = V4L2_QUANTIZATION_FULL_RANGE; isi_m2m->quant = V4L2_QUANTIZATION_FULL_RANGE;
isi_m2m->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(isi_m2m->colorspace); isi_m2m->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(isi_m2m->colorspace);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment