clockevent: Prevent dead lock on clockevents_lock
authorSuresh Siddha <suresh.b.siddha@intel.com>
Thu, 22 Apr 2010 09:47:51 +0000 (11:47 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 26 May 2010 21:27:07 +0000 (14:27 -0700)
This is a merge of two mainline commits, intended
for stable@kernel.org submission for 2.6.27 kernel.

commit f833bab87fca5c3ce13778421b1365845843b976
and

commit 918aae42aa9b611a3663b16ae849fdedc67c2292
Changelog of both:

    Currently clockevents_notify() is called with interrupts enabled at
    some places and interrupts disabled at some other places.

    This results in a deadlock in this scenario.

    cpu A holds clockevents_lock in clockevents_notify() with irqs enabled
    cpu B waits for clockevents_lock in clockevents_notify() with irqs disabled
    cpu C doing set_mtrr() which will try to rendezvous of all the cpus.

    This will result in C and A come to the rendezvous point and waiting
    for B. B is stuck forever waiting for the spinlock and thus not
    reaching the rendezvous point.

    Fix the clockevents code so that clockevents_lock is taken with
    interrupts disabled and thus avoid the above deadlock.

    Also call lapic_timer_propagate_broadcast() on the destination cpu so
    that we avoid calling smp_call_function() in the clockevents notifier
    chain.

    This issue left us wondering if we need to change the MTRR rendezvous
    logic to use stop machine logic (instead of smp_call_function) or add
    a check in spinlock debug code to see if there are other spinlocks
    which gets taken under both interrupts enabled/disabled conditions.

Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: "Brown Len" <len.brown@intel.com>
Cc: stable@kernel.org
    LKML-Reference: <1250544899.2709.210.camel@sbs-t61.sc.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    I got following warning on ia64 box:
      In function 'acpi_processor_power_verify':
      642: warning: passing argument 2 of 'smp_call_function_single' from
      incompatible pointer type

    This smp_call_function_single() was introduced by a commit
    f833bab87fca5c3ce13778421b1365845843b976:

    The problem is that the lapic_timer_propagate_broadcast() has 2 versions:
    One is real code that modified in the above commit, and the other is NOP
    code that used when !ARCH_APICTIMER_STOPS_ON_C3:

      static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) { }

    So I got warning because of !ARCH_APICTIMER_STOPS_ON_C3.

    We really want to do nothing here on !ARCH_APICTIMER_STOPS_ON_C3, so
    modify lapic_timer_propagate_broadcast() of real version to use
    smp_call_function_single() in it.

Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Acked-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Signed-off-by: Thomas Renninger <trenn@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

No differences found