From fb24629ff4a5fa45221753adbdaf61158936cd12 Mon Sep 17 00:00:00 2001 From: cl Date: Tue, 6 Jan 2015 21:40:32 +0800 Subject: [PATCH] <4>[ 4109.549711] CPU: 0 PID: 125 Comm: ddrfreqd Not tainted 3.10.0 #136 <4>[ 4109.549723] [] (unwind_backtrace+0x0/0xe0) from [] (show_stack+0x10/0x14) <4>[ 4109.549737] [] (show_stack+0x10/0x14) from [] (warn_slowpath_common+0x4c/0x68) <4>[ 4109.549750] [] (warn_slowpath_common+0x4c/0x68) from [] (warn_slowpath_fmt+0x2c/0x3c) <4>[ 4109.549762] [] (warn_slowpath_fmt+0x2c/0x3c) from [] (watchdog_check_hardlockup_other_cpu+0xd0/0xf8) <4>[ 4109.549778] [] (watchdog_check_hardlockup_other_cpu+0xd0/0xf8) from [] (watchdog_timer_fn+0x38/0x168) <4>[ 4109.549793] [] (watchdog_timer_fn+0x38/0x168) from [] (__run_hrtimer+0x1a4/0x2b8) <4>[ 4109.549807] [] (__run_hrtimer+0x1a4/0x2b8) from [] (hrtimer_interrupt+0x11c/0x278) <4>[ 4109.549830] [] (hrtimer_interrupt+0x11c/0x278) from [] (arch_timer_handler_phys+0x28/0x30) <4>[ 4109.549846] [] (arch_timer_handler_phys+0x28/0x30) from [] (handle_percpu_devid_irq+0xf8/0x1b4) <4>[ 4109.549861] [] (handle_percpu_devid_irq+0xf8/0x1b4) from [] (generic_handle_irq+0x20/0x30) <4>[ 4109.549872] [] (generic_handle_irq+0x20/0x30) from [] (handle_IRQ+0x64/0x8c) <4>[ 4109.549883] [] (handle_IRQ+0x64/0x8c) from [] (gic_handle_irq+0x34/0x58) <4>[ 4109.549893] [] (gic_handle_irq+0x34/0x58) from [] (__irq_svc+0x40/0x70) <4>[ 4109.549901] Exception stack(0xed0addd8 to 0xed0ade20) <4>[ 4109.549910] ddc0: 00000003 00000000 <4>[ 4109.549920] dde0: 00000003 c0c5bff3 c0c5bff0 c0c5bff0 547b152f 000003c8 00000000 c0b8446c <4>[ 4109.549930] de00: ed0ade48 83126e97 00000003 ed0ade20 c0023638 c00235ec 600f0113 ffffffff <4>[ 4109.549941] [] (__irq_svc+0x40/0x70) from [] (call_with_single_cpu.isra.4+0x9c/0x154) <4>[ 4109.549952] [] (call_with_single_cpu.isra.4+0x9c/0x154) from [] (_ddr_change_freq+0x17c/0x1c0) <4>[ 4109.549963] [] (_ddr_change_freq+0x17c/0x1c0) from [] (ddrfreq_scale_rate_for_dvfs+0x20/0x74) <4>[ 4109.549978] [] (ddrfreq_scale_rate_for_dvfs+0x20/0x74) from [] (dvfs_target+0x15c/0x204) <4>[ 4109.549993] [] (dvfs_target+0x15c/0x204) from [] (dvfs_clk_set_rate+0x44/0x80) <4>[ 4109.550007] [] (dvfs_clk_set_rate+0x44/0x80) from [] (ddrfreq_mode.part.3+0x40/0xec) <4>[ 4109.550017] [] (ddrfreq_mode.part.3+0x40/0xec) from [] (ddrfreq_work+0x184/0x1d4) <4>[ 4109.550029] [] (ddrfreq_work+0x184/0x1d4) from [] (ddrfreq_task+0x58/0x1b8) <4>[ 4109.550041] [] (ddrfreq_task+0x58/0x1b8) from [] (kthread+0xa0/0xac) <4>[ 4109.550054] [] (kthread+0xa0/0xac) from [] (ret_from_fork+0x14/0x3c) <4>[ 4092.709215] CPU: 2 PID: 17844 Comm: mali-utility-wo Not tainted 3.10.0 #136 <4>[ 4092.709408] [] (mm_update_next_owner+0xc4/0x1c0) from [] (exit_mm+0x174/0x184) <4>[ 4092.709422] [] (exit_mm+0x174/0x184) from [] (do_exit+0x204/0x400) <4>[ 4092.709433] [] (do_exit+0x204/0x400) from [] (do_group_exit+0x88/0xb4) <4>[ 4092.709447] [] (do_group_exit+0x88/0xb4) from [] (get_signal_to_deliver+0x3b4/0x3fc) <4>[ 4092.709459] [] (get_signal_to_deliver+0x3b4/0x3fc) from [] (do_signal+0xa0/0x14c) <4>[ 4092.709469] [] (do_signal+0xa0/0x14c) from [] (do_work_pending+0x4c/0x94) <4>[ 4092.709480] [] (do_work_pending+0x4c/0x94) from [] (work_pending+0xc/0x20) cpu0 is waiting for the other cpu respond ipi, but one cpu is blocked on getting &tasklist_lock while irq is disabled and it will not respond ipi. If all the operation of &tasklist_lock is irq-disabled, the &tasklist_lock will become available before the owner respond ipi, so the blocked cpu will get the &tasklist_lock. Signed-off-by: cl --- kernel/exit.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 89cca291f863..ab965e05a1bb 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -262,9 +262,9 @@ int is_current_pgrp_orphaned(void) { int retval; - read_lock(&tasklist_lock); + read_lock_irq(&tasklist_lock); retval = will_become_orphaned_pgrp(task_pgrp(current), NULL); - read_unlock(&tasklist_lock); + read_unlock_irq(&tasklist_lock); return retval; } @@ -387,7 +387,7 @@ retry: return; } - read_lock(&tasklist_lock); + read_lock_irq(&tasklist_lock); /* * Search in the children */ @@ -413,7 +413,7 @@ retry: goto assign_new_owner; } while_each_thread(g, c); - read_unlock(&tasklist_lock); + read_unlock_irq(&tasklist_lock); /* * We found no owner yet mm_users > 1: this implies that we are * most likely racing with swapoff (try_to_unuse()) or /proc or @@ -434,7 +434,7 @@ assign_new_owner: * Delay read_unlock() till we have the task_lock() * to ensure that c does not slip away underneath us */ - read_unlock(&tasklist_lock); + read_unlock_irq(&tasklist_lock); if (c->mm != mm) { task_unlock(c); put_task_struct(c); @@ -1042,7 +1042,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) int why; get_task_struct(p); - read_unlock(&tasklist_lock); + read_unlock_irq(&tasklist_lock); if ((exit_code & 0x7f) == 0) { why = CLD_EXITED; status = exit_code >> 8; @@ -1126,7 +1126,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) * Now we are sure this task is interesting, and no other * thread can reap it because we set its state to EXIT_DEAD. */ - read_unlock(&tasklist_lock); + read_unlock_irq(&tasklist_lock); retval = wo->wo_rusage ? getrusage(p, RUSAGE_BOTH, wo->wo_rusage) : 0; @@ -1260,7 +1260,7 @@ unlock_sig: get_task_struct(p); pid = task_pid_vnr(p); why = ptrace ? CLD_TRAPPED : CLD_STOPPED; - read_unlock(&tasklist_lock); + read_unlock_irq(&tasklist_lock); if (unlikely(wo->wo_flags & WNOWAIT)) return wait_noreap_copyout(wo, p, pid, uid, why, exit_code); @@ -1322,7 +1322,7 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p) pid = task_pid_vnr(p); get_task_struct(p); - read_unlock(&tasklist_lock); + read_unlock_irq(&tasklist_lock); if (!wo->wo_info) { retval = wo->wo_rusage @@ -1538,7 +1538,7 @@ repeat: goto notask; set_current_state(TASK_INTERRUPTIBLE); - read_lock(&tasklist_lock); + read_lock_irq(&tasklist_lock); tsk = current; do { retval = do_wait_thread(wo, tsk); @@ -1552,7 +1552,7 @@ repeat: if (wo->wo_flags & __WNOTHREAD) break; } while_each_thread(current, tsk); - read_unlock(&tasklist_lock); + read_unlock_irq(&tasklist_lock); notask: retval = wo->notask_error; -- 2.34.1