高通Android 7.1平台出现内核崩溃,log如下:
(红色是关键信息)
[ 65.862388] msm_isp_get_buf: bug mgr open cnt = 0
[ 65.871767] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[ 65.879833] pgd = ffffffc02718f000
[ 65.883217] [00000000] *pgd=0000000000000000
[ 66.148672] , *pud=0000000000000000
[ 66.152318] Internal error: Oops: 96000005 [#1] PREEMPT SMP
[ 66.157870] Modules linked in: wlan(O) streamax_jiami(O)
[ 66.163169] CPU: 0 PID: 3450 Comm: AVStreamManager Tainted: G W O 3.18.31 #9
[ 66.171063] Hardware name: Qualcomm Technologies, Inc. MSM8953 QRD NOPMI SKU3 (DT)
[ 66.178618] task: ffffffc012672940 ti: ffffffc027188000 task.ti: ffffffc027188000
[ 66.186092]PC is at msm_isp_cfg_ping_pong_address+0x240/0x5fc
[ 66.191898] LR is at msm_isp_cfg_ping_pong_address+0x214/0x5fc
[ 66.197714]pc : [(ffffffc00088ebb0>] lr : [(ffffffc00088eb84>] pstate: 000001c5
[ 66.205093] sp : ffffffc02718b9f0
[ 66.208391] x29: ffffffc02718b9f0 x28: ffffffc067765098
[ 66.213686] x27: ffffffc067760000 x26: 0000000000000003
[ 66.230003] x25: 0000000000000003 x24: ffffffc067764ec8
[ 66.235299] x23: ffffffc067764648 x22: 0000000001000300
[ 66.240595] x21: 0000000000000000 x20: 0000000000000000
[ 66.245890] x19: ffffffc067764ec8 x18: 0000000000000000
[ 66.251185] x17: 0000000000000000 x16: ffffffc0002021a0
[ 66.256481] x15: 0000000000000000 x14: 0ffffffffffffffe
[ 66.261775] x13: 0000000000000038 x12: 0101010101010101
[ 66.267071] x11: 7f7f7f7f7f7f7f7f x10: 5e6f72685e6c726c
[ 66.272364] x9 : 7f7f7f7f7f7f7f7f x8 : 6e63206e65706f20
[ 66.277660] x7 : 72676d2067756220 x6 : ffffffc001b027cc
[ 66.282955] x5 : 0000000000000000 x4 : 0000000000000000
[ 66.288251] x3 : 0000000000000000 x2 : cb88537fdc8cb01f
[ 66.293546] x1 : cb88537fdc8cb01f x0 : 0000000000000001
[ 66.298844]
[ 66.298844] PC: 0xffffffc00088eab0:
[ 66.303789] eab0 b9414800 34000160 7100109f 54000128 f9400760 d2804314 f9401801 2a1903e0
[ 66.705352]
[ 66.706829]Process Stream (pid: 3450, stack limit = 0xffffffc027188058)
[ 66.714293] Call trace:
[66.716728][(ffffffc00088ebb0>] msm_isp_cfg_ping_pong_address+0x240/0x5fc
[66.723583][(ffffffc00088f034>] msm_isp_init_stream_ping_pong_reg+0xc8/0x138
[ 66.730700] [(ffffffc000890670>] msm_isp_cfg_axi_stream+0x37c/0xdfc
[ 66.736954] [(ffffffc00088ac64>] msm_isp_ioctl+0x520/0xc08
[ 66.742424] [(ffffffc0008a2a74>] msm_isp_subdev_do_ioctl+0xf0/0xfc
[ 66.748585] [(ffffffc0007e30c8>] video_usercopy+0x2d4/0x574
aarch64-linux-android-objdump -S -l -z vmlinux > vmlinux.txt
aarch64-linux-android-objdump:prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-objdump
vmlinux是带符号表的kernel:out/target/product/msm8953_64/obj/KERNEL_OBJ/vmlinux。需要在内核config加入: CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO_REDUCED=y。
/home3/liutao2/8953_MG/SLM758C_AIBOX2/8953_MG/kernel/msm-3.18/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c:1726
return buf;
if (buf->num_planes != stream_info->num_planes) {
ffffffc00088ebac: 39403260 ldrb w0, [x19,#12]
ffffffc00088ebb0: b9400281 ldr w1, [x20]
ffffffc00088ebb4: 6b00003f cmp w1, w0
ffffffc00088ebb8: 54ffff20 b.eq ffffffc00088eb9c (msm_isp_cfg_ping_pong_address+0x22c>
问题点在文件msm_isp_axi_util.c的1726行代码
if (buf->num_planes != stream_info->num_planes) {
在vmlinux.txt查找函数msm_isp_cfg_ping_pong_address的PC地址:
ffffffc00088e970 (msm_isp_cfg_ping_pong_address>:
msm_isp_cfg_ping_pong_address():
/home3/liutao2/8953_MG/SLM758C_AIBOX2/8953_MG/kernel/msm-3.18/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c:1815
msm_isp_cfg_ping_pong_address的PC地址是ffffffc00088e970,msm_isp_cfg_ping_pong_address+0x240 =ffffffc00088ebb0
函数msm_isp_cfg_ping_pong_address代码段:
rc = vfe_dev->buf_mgr->ops->get_buf(vfe_dev->buf_mgr,
vfe_dev->pdev->id, bufq_handle, buf_index,&buf);
if (rc == -EFAULT) {
msm_isp_halt_send_error(vfe_dev, ISP_EVENT_BUF_FATAL_ERROR);
return buf;
}
if (rc < 0)
return buf;
if (buf->num_planes != stream_info->num_planes) {
pr_err("%s: Invalid buffer\n", __func__);
vfe_dev->buf_mgr->ops->put_buf(vfe_dev->buf_mgr,
bufq_handle, buf->buf_idx);
buf = NULL;
}
从问题行if (buf->num_planes != stream_info->num_planes)判断buf或者stream_info为NULL,阅读代码逻辑后stream_info不会是NULL。rc >= 0时,走到问题代码行。
再看get_buf函数:
static int msm_isp_get_buf(struct msm_isp_buf_mgr *buf_mgr, uint32_t id,
uint32_t bufq_handle, uint32_t buf_index,
struct msm_isp_buffer **buf_info)
{
......
// open_count == 0,返回0
if (buf_mgr->open_count == 0) {
pr_err_ratelimited("%s: bug mgr open cnt = 0\n",
__func__);
return 0;
}
......
// buf != NULL,返回0
if (!(*buf_info)) {
rc = -ENOMEM;
} else {
(*buf_info)->state = MSM_ISP_BUFFER_STATE_DEQUEUED;
rc = 0;
}
}
问题出现在open_count == 0,再看内核日志,有bug mgr open cnt = 0的log。确认了获取的buf是NULL。
if (buf_mgr->open_count == 0) {
pr_err_ratelimited("%s: bug mgr open cnt = 0\n", __func__);
- return 0;
+ return rc;
}