<4>[ 4109.549711] CPU: 0 PID: 125 Comm: ddrfreqd Not tainted 3.10.0 #136
authorcl <cl@rock-chips.com>
Tue, 6 Jan 2015 13:40:32 +0000 (21:40 +0800)
committercl <cl@rock-chips.com>
Tue, 6 Jan 2015 13:40:32 +0000 (21:40 +0800)
<4>[ 4109.549723] [<c0013e24>] (unwind_backtrace+0x0/0xe0) from [<c001172c>] (show_stack+0x10/0x14)
<4>[ 4109.549737] [<c001172c>] (show_stack+0x10/0x14) from [<c0032408>] (warn_slowpath_common+0x4c/0x68)
<4>[ 4109.549750] [<c0032408>] (warn_slowpath_common+0x4c/0x68) from [<c00324a4>] (warn_slowpath_fmt+0x2c/0x3c)
<4>[ 4109.549762] [<c00324a4>] (warn_slowpath_fmt+0x2c/0x3c) from [<c009899c>] (watchdog_check_hardlockup_other_cpu+0xd0/0xf8)
<4>[ 4109.549778] [<c009899c>] (watchdog_check_hardlockup_other_cpu+0xd0/0xf8) from [<c00989fc>] (watchdog_timer_fn+0x38/0x168)
<4>[ 4109.549793] [<c00989fc>] (watchdog_timer_fn+0x38/0x168) from [<c0054c7c>] (__run_hrtimer+0x1a4/0x2b8)
<4>[ 4109.549807] [<c0054c7c>] (__run_hrtimer+0x1a4/0x2b8) from [<c005587c>] (hrtimer_interrupt+0x11c/0x278)
<4>[ 4109.549830] [<c005587c>] (hrtimer_interrupt+0x11c/0x278) from [<c056b65c>] (arch_timer_handler_phys+0x28/0x30)
<4>[ 4109.549846] [<c056b65c>] (arch_timer_handler_phys+0x28/0x30) from [<c009c3a4>] (handle_percpu_devid_irq+0xf8/0x1b4)
<4>[ 4109.549861] [<c009c3a4>] (handle_percpu_devid_irq+0xf8/0x1b4) from [<c0098fa4>] (generic_handle_irq+0x20/0x30)
<4>[ 4109.549872] [<c0098fa4>] (generic_handle_irq+0x20/0x30) from [<c000e3ac>] (handle_IRQ+0x64/0x8c)
<4>[ 4109.549883] [<c000e3ac>] (handle_IRQ+0x64/0x8c) from [<c0008538>] (gic_handle_irq+0x34/0x58)
<4>[ 4109.549893] [<c0008538>] (gic_handle_irq+0x34/0x58) from [<c000d600>] (__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] [<c000d600>] (__irq_svc+0x40/0x70) from [<c00235ec>] (call_with_single_cpu.isra.4+0x9c/0x154)
<4>[ 4109.549952] [<c00235ec>] (call_with_single_cpu.isra.4+0x9c/0x154) from [<c0023820>] (_ddr_change_freq+0x17c/0x1c0)
<4>[ 4109.549963] [<c0023820>] (_ddr_change_freq+0x17c/0x1c0) from [<c0025088>] (ddrfreq_scale_rate_for_dvfs+0x20/0x74)
<4>[ 4109.549978] [<c0025088>] (ddrfreq_scale_rate_for_dvfs+0x20/0x74) from [<c002937c>] (dvfs_target+0x15c/0x204)
<4>[ 4109.549993] [<c002937c>] (dvfs_target+0x15c/0x204) from [<c0027d70>] (dvfs_clk_set_rate+0x44/0x80)
<4>[ 4109.550007] [<c0027d70>] (dvfs_clk_set_rate+0x44/0x80) from [<c00252a0>] (ddrfreq_mode.part.3+0x40/0xec)
<4>[ 4109.550017] [<c00252a0>] (ddrfreq_mode.part.3+0x40/0xec) from [<c00257c0>] (ddrfreq_work+0x184/0x1d4)
<4>[ 4109.550029] [<c00257c0>] (ddrfreq_work+0x184/0x1d4) from [<c0025868>] (ddrfreq_task+0x58/0x1b8)
<4>[ 4109.550041] [<c0025868>] (ddrfreq_task+0x58/0x1b8) from [<c0051ad4>] (kthread+0xa0/0xac)
<4>[ 4109.550054] [<c0051ad4>] (kthread+0xa0/0xac) from [<c000da98>] (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] [<c0037494>] (mm_update_next_owner+0xc4/0x1c0) from [<c0037704>] (exit_mm+0x174/0x184)
<4>[ 4092.709422] [<c0037704>] (exit_mm+0x174/0x184) from [<c0037918>] (do_exit+0x204/0x400)
<4>[ 4092.709433] [<c0037918>] (do_exit+0x204/0x400) from [<c0037bc8>] (do_group_exit+0x88/0xb4)
<4>[ 4092.709447] [<c0037bc8>] (do_group_exit+0x88/0xb4) from [<c00444b0>] (get_signal_to_deliver+0x3b4/0x3fc)
<4>[ 4092.709459] [<c00444b0>] (get_signal_to_deliver+0x3b4/0x3fc) from [<c0010c00>] (do_signal+0xa0/0x14c)
<4>[ 4092.709469] [<c0010c00>] (do_signal+0xa0/0x14c) from [<c0010fa4>] (do_work_pending+0x4c/0x94)
<4>[ 4092.709480] [<c0010fa4>] (do_work_pending+0x4c/0x94) from [<c000da40>] (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 <cl@rock-chips.com>
kernel/exit.c

index 89cca291f86388ca51d7704cc994f3a1c2a37abf..ab965e05a1bb608c9346d6808e15f88e34cf7a0b 100644 (file)
@@ -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;