linux-uconsole/kernel/irq
Chuansheng Liu 56f1c4124b 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:38:15 -07:00
..
autoprobe.c genirq: Handle pending irqs in irq_startup() 2012-02-15 11:56:59 +01:00
chip.c x86/MSI: Support multiple MSIs in presense of IRQ remapping 2013-01-24 17:25:12 +01:00
debug.h irq: hide debug macros so they don't collide with others. 2012-04-23 12:30:03 -04:00
devres.c devres: fix possible use after free 2011-07-25 20:57:14 -07:00
dummychip.c genirq: Export dummy_irq_chip 2012-08-21 16:14:23 +02:00
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-07-14 20:17:28 -04:00
internals.h genirq: Introduce irq_do_set_affinity() to reduce duplicated code 2012-05-24 22:36:40 +02:00
irqdesc.c genirq: Add missing irq_to_desc export for CONFIG_SPARSE_IRQ=n 2014-02-22 12:41:29 -08:00
irqdomain.c irqdomain: document the simple domain first_irq 2013-06-08 21:15:09 +01:00
Kconfig irq_domain: correct the debugfs file name 2012-04-10 22:39:17 -06:00
Makefile irq: add irq_domain translation infrastructure 2011-07-28 01:32:04 -06:00
manage.c genirq: Remove racy waitqueue_active check 2014-03-23 21:38:15 -07:00
migration.c genirq: Introduce irq_do_set_affinity() to reduce duplicated code 2012-05-24 22:36:40 +02:00
pm.c irq: Enable all irqs unconditionally in irq_resume 2013-12-11 22:36:27 -08:00
proc.c proc: Supply a function to remove a proc entry by PDE 2013-05-01 17:29:46 -04:00
resend.c genirq: Provide means to retrigger parent 2012-11-01 12:11:31 +01:00
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 2012-12-11 12:25:30 +01:00