lkml.org 
[lkml]   [2008]   [Oct]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 34/71] rtc: fix deadlock
    2.6.26-stable review patch.  If anyone has any objections, please let us
    know.

    ------------------
    From: Ingo Molnar <mingo@elte.hu>

    commit 38c052f8cff1bd323ccfa968136a9556652ee420 upstream

    if get_rtc_time() is _ever_ called with IRQs off, we deadlock badly
    in it, waiting for jiffies to increment.

    So make the code more robust by doing an explicit mdelay(20).

    This solves a very hard to reproduce/debug hard lockup reported
    by Mikael Pettersson.

    Reported-by: Mikael Pettersson <mikpe@it.uu.se>
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    include/asm-generic/rtc.h | 12 ++++--------
    1 file changed, 4 insertions(+), 8 deletions(-)

    --- a/include/asm-generic/rtc.h
    +++ b/include/asm-generic/rtc.h
    @@ -15,6 +15,7 @@
    #include <linux/mc146818rtc.h>
    #include <linux/rtc.h>
    #include <linux/bcd.h>
    +#include <linux/delay.h>

    #define RTC_PIE 0x40 /* periodic interrupt enable */
    #define RTC_AIE 0x20 /* alarm interrupt enable */
    @@ -43,7 +44,6 @@ static inline unsigned char rtc_is_updat

    static inline unsigned int get_rtc_time(struct rtc_time *time)
    {
    - unsigned long uip_watchdog = jiffies;
    unsigned char ctrl;
    unsigned long flags;

    @@ -53,19 +53,15 @@ static inline unsigned int get_rtc_time(

    /*
    * read RTC once any update in progress is done. The update
    - * can take just over 2ms. We wait 10 to 20ms. There is no need to
    + * can take just over 2ms. We wait 20ms. There is no need to
    * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP.
    * If you need to know *exactly* when a second has started, enable
    * periodic update complete interrupts, (via ioctl) and then
    * immediately read /dev/rtc which will block until you get the IRQ.
    * Once the read clears, read the RTC time (again via ioctl). Easy.
    */
    -
    - if (rtc_is_updating() != 0)
    - while (jiffies - uip_watchdog < 2*HZ/100) {
    - barrier();
    - cpu_relax();
    - }
    + if (rtc_is_updating())
    + mdelay(20);

    /*
    * Only the values that we read from the RTC are set. We leave
    --


    \
     
     \ /
      Last update: 2008-10-07 02:55    [W:0.058 / U:32.916 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site