2005-09-08 15:13:46

by Jan Beulich

[permalink] [raw]
Subject: [PATCH] fix i386 interrupt re-enabling in die()

(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-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);
die.lock_owner = smp_processor_id();
die.lock_owner_depth = 0;
bust_spinlocks(1);
@@ -344,7 +345,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, die.flags);

if (kexec_should_crash(current))
crash_kexec(regs);


Attachments:
(No filename) (1.22 kB)
linux-2.6.13-i386-die-irq.patch (1.22 kB)
Download all attachments

2005-09-08 17:37:21

by Zwane Mwaikambo

[permalink] [raw]
Subject: Re: [PATCH] fix i386 interrupt re-enabling in die()

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.

2005-09-09 09:44:12

by Jan Beulich

[permalink] [raw]
Subject: Re: [PATCH] fix i386 interrupt re-enabling in die() (attempt 2)

>>> 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);


Attachments:
(No filename) (2.08 kB)
linux-2.6.13-i386-die-irq.patch (1.17 kB)
Download all attachments

2005-09-09 15:53:03

by Zwane Mwaikambo

[permalink] [raw]
Subject: Re: [PATCH] fix i386 interrupt re-enabling in die() (attempt 2)

Hello Jan,

On Fri, 9 Sep 2005, Jan Beulich wrote:

> - 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);

Just one tiny nit, that else should be on the same line as the curly
brace.

Thanks