soc: rockchip: rockchip_system_monitor: Fix list_del corruption when del video info
list_del corruption, ffffffc028662d18->next is LIST_POISON1 (dead000000000100) ------------[ cut here ]------------ kernel BUG at lib/list_debug.c:47! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP Modules linked in: 8822es(O) sprdbt_tty Process CtrlThread (pid: 3697, stack limit = 0x0000000060d302a5) CPU: 1 PID: 3697 Comm: CtrlThread Tainted: G O 4.19.232 #96 Hardware name: Rockchip RK3528 DEMO4 DDR4 V10 Board (DT) pstate: 40400005 (nZcv daif +PAN -UAO) pc : __list_del_entry_valid+0x64/0xb0 lr : __list_del_entry_valid+0x64/0xb0 sp : ffffff800fd1bc70 x29: ffffff800fd1bc70 x28: ffffffc05c468000 x27: 0000000000000000 x26: 0000000000000000 x25: 0000000046000000 x24: 0000000000000011 x23: ffffff800fd1be60 x22: ffffff80098188a0 x21: ffffff8009818000 x20: ffffffc0462af700 x19: ffffffc028662d00 x18: ffffffffffffffff x17: 0000000000000000 x16: 0000000000000000 x15: ffffff800934a980 x14: 4f53494f505f5453 x13: 494c207369207478 x12: 656e3e2d38316432 x11: 3636383230636666 x10: 66666666202c6e6f x9 : 6974707572726f63 x8 : 3030303030303030 x7 : 0000000000000058 x6 : ffffffc07f74aa18 x5 : ffffffc07f74aa18 x4 : 0000000000000000 x3 : ffffffc07f753908 x2 : ac674fb1e4701200 x1 : 0000000000000000 x0 : 000000000000004e Call trace: __list_del_entry_valid+0x64/0xb0 rockchip_update_system_status+0x168/0x250 status_store+0x1c/0x38 kobj_attr_store+0x14/0x28 sysfs_kf_write+0x48/0x58 kernfs_fop_write+0xf4/0x220 __vfs_write+0x34/0x158 vfs_write+0xb0/0x1d0 ksys_write+0x64/0xe0 __arm64_sys_write+0x14/0x20 el0_svc_common.constprop.0+0x64/0x178 el0_svc_compat_handler+0x18/0x20 el0_svc_compat+0x8/0x34 Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com> Change-Id: I42e9c42d7e65c742226f82b9367466b2ed86550d
This commit is contained in:
@@ -246,34 +246,6 @@ static struct video_info *rockchip_parse_video_info(const char *buf)
|
||||
return video_info;
|
||||
}
|
||||
|
||||
static struct video_info *rockchip_find_video_info(const char *buf)
|
||||
{
|
||||
struct video_info *info, *video_info;
|
||||
|
||||
video_info = rockchip_parse_video_info(buf);
|
||||
|
||||
if (!video_info)
|
||||
return NULL;
|
||||
|
||||
mutex_lock(&video_info_mutex);
|
||||
list_for_each_entry(info, &video_info_list, node) {
|
||||
if (info->width == video_info->width &&
|
||||
info->height == video_info->height &&
|
||||
info->ishevc == video_info->ishevc &&
|
||||
info->videoFramerate == video_info->videoFramerate &&
|
||||
info->streamBitrate == video_info->streamBitrate) {
|
||||
mutex_unlock(&video_info_mutex);
|
||||
kfree(video_info);
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&video_info_mutex);
|
||||
kfree(video_info);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rockchip_add_video_info(struct video_info *video_info)
|
||||
{
|
||||
if (video_info) {
|
||||
@@ -285,12 +257,25 @@ static void rockchip_add_video_info(struct video_info *video_info)
|
||||
|
||||
static void rockchip_del_video_info(struct video_info *video_info)
|
||||
{
|
||||
if (video_info) {
|
||||
mutex_lock(&video_info_mutex);
|
||||
list_del(&video_info->node);
|
||||
mutex_unlock(&video_info_mutex);
|
||||
kfree(video_info);
|
||||
struct video_info *info, *tmp;
|
||||
|
||||
if (!video_info)
|
||||
return;
|
||||
|
||||
mutex_lock(&video_info_mutex);
|
||||
list_for_each_entry_safe(info, tmp, &video_info_list, node) {
|
||||
if (info->width == video_info->width &&
|
||||
info->height == video_info->height &&
|
||||
info->ishevc == video_info->ishevc &&
|
||||
info->videoFramerate == video_info->videoFramerate &&
|
||||
info->streamBitrate == video_info->streamBitrate) {
|
||||
list_del(&info->node);
|
||||
kfree(info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
kfree(video_info);
|
||||
mutex_unlock(&video_info_mutex);
|
||||
}
|
||||
|
||||
static void rockchip_update_video_info(void)
|
||||
@@ -338,7 +323,7 @@ void rockchip_update_system_status(const char *buf)
|
||||
switch (buf[0]) {
|
||||
case '0':
|
||||
/* clear video flag */
|
||||
video_info = rockchip_find_video_info(buf);
|
||||
video_info = rockchip_parse_video_info(buf);
|
||||
if (video_info) {
|
||||
rockchip_del_video_info(video_info);
|
||||
rockchip_update_video_info();
|
||||
|
||||
Reference in New Issue
Block a user