[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: Ingo 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: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
committed by
Linus Torvalds
parent
a29b0b74e7
commit
0f74964627
@@ -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)
|
|||||||
* 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)
|
|||||||
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)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user