Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] lockdep: annotate i386 apm

Lockdep doesn't like to enable interrupts when they are enabled already.

BUG: warning at kernel/lockdep.c:1814/trace_hardirqs_on() (Not tainted)
[<c04051ed>] show_trace_log_lvl+0x58/0x16a
[<c04057fa>] show_trace+0xd/0x10
[<c0405913>] dump_stack+0x19/0x1b
[<c043abfb>] trace_hardirqs_on+0xa2/0x11e
[<c041463c>] apm_bios_call_simple+0xcd/0xfd
[<c0415242>] apm+0x92/0x5b1
[<c0402005>] kernel_thread_helper+0x5/0xb
DWARF2 unwinder stuck at kernel_thread_helper+0x5/0xb
Leftover inexact backtrace:
[<c04057fa>] show_trace+0xd/0x10
[<c0405913>] dump_stack+0x19/0x1b
[<c043abfb>] trace_hardirqs_on+0xa2/0x11e
[<c041463c>] apm_bios_call_simple+0xcd/0xfd
[<c0415242>] apm+0x92/0x5b1
[<c0402005>] kernel_thread_helper+0x5/0xb

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Peter Zijlstra and committed by
Linus Torvalds
3864c489 6a15f46c

+27 -10
+27 -10
arch/i386/kernel/apm.c
··· 540 540 * Also, we KNOW that for the non error case of apm_bios_call, there 541 541 * is no useful data returned in the low order 8 bits of eax. 542 542 */ 543 - #define APM_DO_CLI \ 544 - if (apm_info.allow_ints) \ 545 - local_irq_enable(); \ 546 - else \ 543 + 544 + static inline unsigned long __apm_irq_save(void) 545 + { 546 + unsigned long flags; 547 + local_save_flags(flags); 548 + if (apm_info.allow_ints) { 549 + if (irqs_disabled_flags(flags)) 550 + local_irq_enable(); 551 + } else 547 552 local_irq_disable(); 553 + 554 + return flags; 555 + } 556 + 557 + #define apm_irq_save(flags) \ 558 + do { flags = __apm_irq_save(); } while (0) 559 + 560 + static inline void apm_irq_restore(unsigned long flags) 561 + { 562 + if (irqs_disabled_flags(flags)) 563 + local_irq_disable(); 564 + else if (irqs_disabled()) 565 + local_irq_enable(); 566 + } 548 567 549 568 #ifdef APM_ZERO_SEGS 550 569 # define APM_DECL_SEGS \ ··· 615 596 save_desc_40 = gdt[0x40 / 8]; 616 597 gdt[0x40 / 8] = bad_bios_desc; 617 598 618 - local_save_flags(flags); 619 - APM_DO_CLI; 599 + apm_irq_save(flags); 620 600 APM_DO_SAVE_SEGS; 621 601 apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi); 622 602 APM_DO_RESTORE_SEGS; 623 - local_irq_restore(flags); 603 + apm_irq_restore(flags); 624 604 gdt[0x40 / 8] = save_desc_40; 625 605 put_cpu(); 626 606 apm_restore_cpus(cpus); ··· 658 640 save_desc_40 = gdt[0x40 / 8]; 659 641 gdt[0x40 / 8] = bad_bios_desc; 660 642 661 - local_save_flags(flags); 662 - APM_DO_CLI; 643 + apm_irq_save(flags); 663 644 APM_DO_SAVE_SEGS; 664 645 error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax); 665 646 APM_DO_RESTORE_SEGS; 666 - local_irq_restore(flags); 647 + apm_irq_restore(flags); 667 648 gdt[0x40 / 8] = save_desc_40; 668 649 put_cpu(); 669 650 apm_restore_cpus(cpus);