From f657ffbff7d0e2cdfd1b69a638899eaf5b5b1ba6 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 2 Jul 2012 17:28:13 -0700 Subject: [PATCH] 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: [] (unwind_backtrace+0x0/0x12c) from [] (warn_slowpath_common+0x4c/0x64) [] (warn_slowpath_common+0x4c/0x64) from [] (warn_slowpath_fmt+0x2c/0x3c) [] (warn_slowpath_fmt+0x2c/0x3c) from [] (debug_print_object+0x94/0xbc) [] (debug_print_object+0x94/0xbc) from [] (debug_object_assert_init+0xf4/0x10c) [] (debug_object_assert_init+0xf4/0x10c) from [] (del_timer+0x10/0x1f0) [] (del_timer+0x10/0x1f0) from [] (smd_tty_close+0x80/0xac) [] (smd_tty_close+0x80/0xac) from [] (tty_release+0x178/0x498) [] (tty_release+0x178/0x498) from [] (tty_open+0x3a8/0x4f4) [] (tty_open+0x3a8/0x4f4) from [] (chrdev_open+0x114/0x134) [] (chrdev_open+0x114/0x134) from [] (__dentry_open+0x190/0x29c) [] (__dentry_open+0x190/0x29c) from [] (nameidata_to_filp+0x58/0x64) [] (nameidata_to_filp+0x58/0x64) from [] (do_last+0x840/0x990) [] (do_last+0x840/0x990) from [] (path_openat+0xc4/0x390) [] (path_openat+0xc4/0x390) from [] (do_filp_open+0x30/0x7c) [] (do_filp_open+0x30/0x7c) from [] (do_sys_open+0xd8/0x174) [] (do_sys_open+0xd8/0x174) from [] (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 --- arch/arm/mach-msm/smd_tty.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c index 68e0f41a35a..44ef8221ce7 100644 --- a/arch/arm/mach-msm/smd_tty.c +++ b/arch/arm/mach-msm/smd_tty.c @@ -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);