msm: smd_tty: Don't call del_timer() on uninitialized timers
Calling del_timer() on uninitialized timers can potentially lead to a deadlock where a CPU spins forever waiting to lock the timer base. Enabling debug objects for timers allows us to detect these problems and resolve them before they become real bugs. This scenario occurs in smd_tty when the timer has never been initialized and we close the smd_tty port. WARNING: at lib/debugobjects.c:262 debug_print_object+0x94/0xbc() ODEBUG: assert_init not available (active state 0) object type: timer_list hint: stub_timer+0x0/0x10 Modules linked in: [<c001521c>] (unwind_backtrace+0x0/0x12c) from [<c007b2fc>] (warn_slowpath_common+0x4c/0x64) [<c007b2fc>] (warn_slowpath_common+0x4c/0x64) from [<c007b394>] (warn_slowpath_fmt+0x2c/0x3c) [<c007b394>] (warn_slowpath_fmt+0x2c/0x3c) from [<c02edc20>] (debug_print_object+0x94/0xbc) [<c02edc20>] (debug_print_object+0x94/0xbc) from [<c02ede48>] (debug_object_assert_init+0xf4/0x10c) [<c02ede48>] (debug_object_assert_init+0xf4/0x10c) from [<c008ac98>] (del_timer+0x10/0x1f0) [<c008ac98>] (del_timer+0x10/0x1f0) from [<c0037794>] (smd_tty_close+0x80/0xac) [<c0037794>] (smd_tty_close+0x80/0xac) from [<c0378dec>] (tty_release+0x178/0x498) [<c0378dec>] (tty_release+0x178/0x498) from [<c037965c>] (tty_open+0x3a8/0x4f4) [<c037965c>] (tty_open+0x3a8/0x4f4) from [<c01527ac>] (chrdev_open+0x114/0x134) [<c01527ac>] (chrdev_open+0x114/0x134) from [<c014ccec>] (__dentry_open+0x190/0x29c) [<c014ccec>] (__dentry_open+0x190/0x29c) from [<c014ceb0>] (nameidata_to_filp+0x58/0x64) [<c014ceb0>] (nameidata_to_filp+0x58/0x64) from [<c015d73c>] (do_last+0x840/0x990) [<c015d73c>] (do_last+0x840/0x990) from [<c015d950>] (path_openat+0xc4/0x390) [<c015d950>] (path_openat+0xc4/0x390) from [<c015dcfc>] (do_filp_open+0x30/0x7c) [<c015dcfc>] (do_filp_open+0x30/0x7c) from [<c014c9c0>] (do_sys_open+0xd8/0x174) [<c014c9c0>] (do_sys_open+0xd8/0x174) from [<c000e340>] (ret_fast_syscall+0x0/0x3c) Fix it by initializing the timer when we setup the ports. Use mod_timer() to increase the timeout when necessary. Change-Id: Idbc1175ed08761b435c21d858e8d016d451c2991 Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
This commit is contained in:
@@ -144,14 +144,8 @@ static void smd_tty_read(unsigned long param)
|
||||
|
||||
avail = tty_prepare_flip_string(tty, &ptr, avail);
|
||||
if (avail <= 0) {
|
||||
if (!timer_pending(&info->buf_req_timer)) {
|
||||
init_timer(&info->buf_req_timer);
|
||||
info->buf_req_timer.expires = jiffies +
|
||||
((30 * HZ)/1000);
|
||||
info->buf_req_timer.function = buf_req_retry;
|
||||
info->buf_req_timer.data = param;
|
||||
add_timer(&info->buf_req_timer);
|
||||
}
|
||||
mod_timer(&info->buf_req_timer,
|
||||
jiffies + msecs_to_jiffies(30));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -572,6 +566,8 @@ static int __init smd_tty_init(void)
|
||||
smd_tty[idx].driver.driver.owner = THIS_MODULE;
|
||||
spin_lock_init(&smd_tty[idx].reset_lock);
|
||||
smd_tty[idx].is_open = 0;
|
||||
setup_timer(&smd_tty[idx].buf_req_timer, buf_req_retry,
|
||||
(unsigned long)&smd_tty[idx]);
|
||||
init_waitqueue_head(&smd_tty[idx].ch_opened_wait_queue);
|
||||
ret = platform_driver_register(&smd_tty[idx].driver);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user