>>> Zwane Mwaikambo <[EMAIL PROTECTED]> 08.09.05 19:37:20 >>>
>On Thu, 8 Sep 2005, Jan Beulich wrote:
>
>> diff -Npru 2.6.13/arch/i386/kernel/traps.c
>> 2.6.13-i386-die-irq/arch/i386/kernel/traps.c
>> --- 2.6.13/arch/i386/kernel/traps.c  2005-08-29 01:41:01.000000000
>> +0200
>> +++ 2.6.13-i386-die-irq/arch/i386/kernel/traps.c     2005-09-07
>> 11:39:40.000000000 +0200
>> @@ -304,6 +304,7 @@ void die(const char * str, struct pt_reg
>>              spinlock_t lock;
>>              u32 lock_owner;
>>              int lock_owner_depth;
>> +            unsigned long flags;
>>      } die = {
>>              .lock =                 SPIN_LOCK_UNLOCKED,
>>              .lock_owner =           -1,
>> @@ -313,7 +314,7 @@ void die(const char * str, struct pt_reg
>>  
>>      if (die.lock_owner != raw_smp_processor_id()) {
>>              console_verbose();
>> -            spin_lock_irq(&die.lock);
>> +            spin_lock_irqsave(&die.lock, die.flags);
>
>This corrupts flags on contention, use a stack variable.

Indeed. Corrected below:

(Note: Patch also attached because the inline version is certain to
get
line wrapped.)

Rather than blindly re-enabling interrupts in die(), save their state
upon
entry and then restore that state.

Signed-off-by: Jan Beulich <[EMAIL PROTECTED]>

diff -Npru 2.6.13/arch/i386/kernel/traps.c
2.6.13-i386-die-irq/arch/i386/kernel/traps.c
--- 2.6.13/arch/i386/kernel/traps.c     2005-08-29 01:41:01.000000000
+0200
+++ 2.6.13-i386-die-irq/arch/i386/kernel/traps.c        2005-09-09
11:33:30.202343904 +0200
@@ -310,14 +310,17 @@ void die(const char * str, struct pt_reg
                .lock_owner_depth =     0
        };
        static int die_counter;
+       unsigned long flags;
 
        if (die.lock_owner != raw_smp_processor_id()) {
                console_verbose();
-               spin_lock_irq(&die.lock);
+               spin_lock_irqsave(&die.lock, flags);
                die.lock_owner = smp_processor_id();
                die.lock_owner_depth = 0;
                bust_spinlocks(1);
        }
+       else
+               local_save_flags(flags);
 
        if (++die.lock_owner_depth < 3) {
                int nl = 0;
@@ -344,7 +347,7 @@ void die(const char * str, struct pt_reg
 
        bust_spinlocks(0);
        die.lock_owner = -1;
-       spin_unlock_irq(&die.lock);
+       spin_unlock_irqrestore(&die.lock, flags);
 
        if (kexec_should_crash(current))
                crash_kexec(regs);

Attachment: linux-2.6.13-i386-die-irq.patch
Description: Binary data

Reply via email to