Patch from: Zwane Mwaikambo Fix up a possible AB/BA deadlock identified by Dawson Engler's latest toy. drivers/char/rtc.c | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-) diff -puN drivers/char/rtc.c~rtc-locking-fix drivers/char/rtc.c --- 25/drivers/char/rtc.c~rtc-locking-fix 2003-03-02 21:25:37.000000000 -0800 +++ 25-akpm/drivers/char/rtc.c 2003-03-02 21:27:19.000000000 -0800 @@ -152,6 +152,9 @@ static unsigned long rtc_irq_data = 0; / static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */ #if RTC_IRQ +/* + * rtc_task_lock nests inside rtc_lock. + */ static spinlock_t rtc_task_lock = SPIN_LOCK_UNLOCKED; static rtc_task_t *rtc_callback = NULL; #endif @@ -746,13 +749,15 @@ int rtc_unregister(rtc_task_t *task) #else unsigned char tmp; - spin_lock_irq(&rtc_task_lock); + spin_lock_irq(&rtc_lock); + spin_lock(&rtc_task_lock); if (rtc_callback != task) { - spin_unlock_irq(&rtc_task_lock); + spin_unlock(&rtc_task_lock); + spin_unlock_irq(&rtc_lock); return -ENXIO; } rtc_callback = NULL; - spin_lock(&rtc_lock); + /* disable controls */ tmp = CMOS_READ(RTC_CONTROL); tmp &= ~RTC_PIE; @@ -765,8 +770,8 @@ int rtc_unregister(rtc_task_t *task) del_timer(&rtc_irq_timer); } rtc_status &= ~RTC_IS_OPEN; - spin_unlock(&rtc_lock); - spin_unlock_irq(&rtc_task_lock); + spin_unlock(&rtc_task_lock); + spin_unlock_irq(&rtc_lock); return 0; #endif } _