2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-11-26 11:34:42 +08:00
linux-next/kernel/irq
Chuansheng Liu c685689fd2 genirq: Remove racy waitqueue_active check
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
Cc: stable@vger.kernel.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
2014-02-27 10:54:16 +01:00
..
autoprobe.c genirq: Handle pending irqs in irq_startup() 2012-02-15 11:56:59 +01:00
chip.c irq: Fix some trivial typos in comments 2013-10-18 14:49:30 +02:00
debug.h irq: hide debug macros so they don't collide with others. 2012-04-23 12:30:03 -04:00
devres.c genirq: Add devm_request_any_context_irq() 2014-02-09 15:27:21 +01:00
dummychip.c genirq: Export dummy_irq_chip 2012-08-21 16:14:23 +02:00
generic-chip.c Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2013-07-13 15:37:30 -07: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-11 10:30:36 +01:00
irqdomain.c of/irq: simplify args to irq_create_of_mapping 2013-10-24 11:42:57 +01:00
Kconfig genirq: Generic irq chip requires IRQ_DOMAIN 2014-02-05 10:17:32 +01: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-02-27 10:54:16 +01: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-11-25 22:20:02 +01:00
proc.c irqdomain: Include hwirq number in /proc/interrupts 2013-06-24 14:02:42 +01:00
resend.c genirq: Provide means to retrigger parent 2012-11-01 12:11:31 +01:00
settings.h genirq: Prevent spurious detection for unconditionally polled interrupts 2013-11-13 16:03:02 +01:00
spurious.c genirq: Prevent spurious detection for unconditionally polled interrupts 2013-11-13 16:03:02 +01:00