android_kernel_google_msm/kernel/irq
Chuansheng Liu b46741f24d genirq: Remove racy waitqueue_active check
commit c685689fd2 upstream.

We hit one rare case below:

T1 calling disable_irq(), but hanging at synchronize_irq()
always;
The corresponding irq thread is in sleeping state;
And all CPUs are in idle state;

After analysis, we found there is one possible scenerio which
causes T1 is waiting there forever:
CPU0                                       CPU1
 synchronize_irq()
  wait_event()
    spin_lock()
                                           atomic_dec_and_test(&threads_active)
      insert the __wait into queue
    spin_unlock()
                                           if(waitqueue_active)
    atomic_read(&threads_active)
                                             wake_up()

Here after inserted the __wait into queue on CPU0, and before
test if queue is empty on CPU1, there is no barrier, it maybe
cause it is not visible for CPU1 immediately, although CPU0 has
updated the queue list.
It is similar for CPU0 atomic_read() threads_active also.

So we'd need one smp_mb() before waitqueue_active.that, but removing
the waitqueue_active() check solves it as wel l and it makes
things simple and clear.

Signed-off-by: Chuansheng Liu <chuansheng.liu@intel.com>
Cc: Xiaoming Wang <xiaoming.wang@intel.com>
Link: http://lkml.kernel.org/r/1393212590-32543-1-git-send-email-chuansheng.liu@intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-03-23 21:37:05 -07:00
..
autoprobe.c genirq: Handle pending irqs in irq_startup() 2012-02-15 11:56:59 +01:00
chip.c genirq: export handle_edge_irq() and irq_to_desc() 2012-05-15 08:10:07 -07:00
debug.h irq: hide debug macros so they don't collide with others. 2012-04-23 12:30:03 -04:00
devres.c
dummychip.c
generic-chip.c kernel: Fix files explicitly needing EXPORT_SYMBOL infrastructure 2011-10-31 19:30:05 -04:00
handle.c random: make 'add_interrupt_randomness()' do something sane 2012-08-15 08:10:10 -07:00
internals.h Merge branch 'linus' into irq/core 2012-03-13 16:35:16 +01:00
irqdesc.c genirq: Add missing irq_to_desc export for CONFIG_SPARSE_IRQ=n 2014-02-22 10:32:46 -08:00
irqdomain.c irq_domain: fix type mismatch in debugfs output format 2012-04-12 16:25:48 -06:00
Kconfig irq_domain: correct the debugfs file name 2012-04-10 22:39:17 -06:00
Makefile
manage.c genirq: Remove racy waitqueue_active check 2014-03-23 21:37:05 -07:00
migration.c genirq: Adjust irq thread affinity on IRQ_SET_MASK_OK_NOCOPY return value 2012-03-30 23:13:46 +02:00
pm.c irq: Enable all irqs unconditionally in irq_resume 2013-12-11 22:34:11 -08:00
proc.c
resend.c
settings.h genirq: Add support for per-cpu dev_id interrupts 2011-10-03 15:35:26 +02:00
spurious.c genirq: Avoid deadlock in spurious handling 2013-02-28 06:58:58 -08:00