提交 0f749646 编写于 作者: I Ingo Molnar 提交者: Linus Torvalds

[PATCH] lockdep: HPET/RTC fix

Joseph Fannin reported that hpet_rtc_interrupt() enables hardirqs
in irq context:

[   25.628000]  [<c014af4e>] trace_hardirqs_on+0xce/0x200
[   25.628000]  [<c036cf21>] _spin_unlock_irq+0x31/0x70
[   25.628000]  [<c0296584>] rtc_get_rtc_time+0x44/0x1a0
[   25.628000]  [<c01198bb>] hpet_rtc_interrupt+0x21b/0x280
[   25.628000]  [<c0161141>] handle_IRQ_event+0x31/0x70
[   25.628000]  [<c0162d37>] handle_edge_irq+0xe7/0x210
[   25.628000]  [<c0106192>] do_IRQ+0x92/0x120
[   25.628000]  [<c0104121>] common_interrupt+0x25/0x2c

the call of rtc_get_rtc_time() is highly suspect. At a minimum we
need the patch below to save/restore hardirq state.
Signed-off-by: NIngo Molnar <mingo@elte.hu>
Cc: Joseph Fannin <jfannin@gmail.com>
Cc: John Stultz <johnstul@us.ibm.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 a29b0b74
...@@ -1245,7 +1245,7 @@ static int rtc_proc_open(struct inode *inode, struct file *file) ...@@ -1245,7 +1245,7 @@ static int rtc_proc_open(struct inode *inode, struct file *file)
void rtc_get_rtc_time(struct rtc_time *rtc_tm) void rtc_get_rtc_time(struct rtc_time *rtc_tm)
{ {
unsigned long uip_watchdog = jiffies; unsigned long uip_watchdog = jiffies, flags;
unsigned char ctrl; unsigned char ctrl;
#ifdef CONFIG_MACH_DECSTATION #ifdef CONFIG_MACH_DECSTATION
unsigned int real_year; unsigned int real_year;
...@@ -1272,7 +1272,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) ...@@ -1272,7 +1272,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
* RTC has RTC_DAY_OF_WEEK, we should usually ignore it, as it is * RTC has RTC_DAY_OF_WEEK, we should usually ignore it, as it is
* only updated by the RTC when initially set to a non-zero value. * only updated by the RTC when initially set to a non-zero value.
*/ */
spin_lock_irq(&rtc_lock); spin_lock_irqsave(&rtc_lock, flags);
rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
rtc_tm->tm_hour = CMOS_READ(RTC_HOURS); rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
...@@ -1286,7 +1286,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) ...@@ -1286,7 +1286,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
real_year = CMOS_READ(RTC_DEC_YEAR); real_year = CMOS_READ(RTC_DEC_YEAR);
#endif #endif
ctrl = CMOS_READ(RTC_CONTROL); ctrl = CMOS_READ(RTC_CONTROL);
spin_unlock_irq(&rtc_lock); spin_unlock_irqrestore(&rtc_lock, flags);
if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
{ {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册