linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Oops: 2.5.64 check_obj_poison for 'size-64'
@ 2003-03-07  5:13 Zwane Mwaikambo
  2003-03-07  6:23 ` Andrew Morton
  0 siblings, 1 reply; 20+ messages in thread
From: Zwane Mwaikambo @ 2003-03-07  5:13 UTC (permalink / raw)
  To: Linux Kernel

This just popped up on my screen, seems to have been triggered by sar/cron 
(i'll probably have to reboot the box soon)

slab error in check_poison_obj(): cache `size-64': object was modified after freeing
Call Trace:
 [<c0142226>] check_poison_obj+0x66/0x70
 [<c0143b92>] kmalloc+0xd2/0x180
 [<c0166078>] pipe_new+0x28/0xd0
 [<c0166153>] get_pipe_inode+0x23/0xb0
 [<c0166212>] do_pipe+0x32/0x1e0
 [<c0111ed3>] sys_pipe+0x13/0x60
 [<c010ad9b>] syscall_call+0x7/0xb

Unable to handle kernel paging request at virtual address 2020202b
 printing eip:
c010cbd7
*pde = 5a5a5a5a
Oops: 0002
CPU:    0
EIP:    0060:[<c010cbd7>]    Not tainted
EFLAGS: 00010283
EIP is at show_interrupts+0x237/0x270
eax: 20202020   ebx: e4f798a4   ecx: 00000000   edx: 0000000b
esi: c02ba31b   edi: 00000020   ebp: 00000000   esp: e424df00
ds: 007b   es: 007b   ss: 0068
Process sadc (pid: 1250, threadinfo=e424c000 task=e43780e0)
Stack: 00000390 c03b40a0 000000e0 00000001 e4f799bc 00000001 e4f799bc c0178e68 
       e4f799bc 00000001 e424df38 00000000 e424df48 00000001 00000000 00000000 
       e41d1870 e457ae84 e4649ef0 e4649ee4 00000000 40014000 e3830b54 00000400 
Call Trace:
 [<c0178e68>] seq_read+0x108/0x2c0
 [<c01590d8>] vfs_read+0xa8/0x160
 [<c01593ca>] sys_read+0x2a/0x40
 [<c010ad9b>] syscall_call+0x7/0xb

Code: c6 04 02 0a ff 43 0c a1 60 6a 3b c0 50 68 21 a3 2b c0 53 e8 

(gdb) list *show_interrupts+0x237
0xc010cbd7 is in show_interrupts (include/linux/seq_file.h:40).
35	int seq_escape(struct seq_file *, const char *, const char *);
36	
37	static inline int seq_putc(struct seq_file *m, char c)
38	{
39		if (m->count < m->size) {
40			m->buf[m->count++] = c;
41			return 0;
42		}
43		return -1;
 
-- 
function.linuxpower.ca

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Oops: 2.5.64 check_obj_poison for 'size-64'
  2003-03-07  5:13 Oops: 2.5.64 check_obj_poison for 'size-64' Zwane Mwaikambo
@ 2003-03-07  6:23 ` Andrew Morton
  2003-03-07  7:22   ` Zwane Mwaikambo
  0 siblings, 1 reply; 20+ messages in thread
From: Andrew Morton @ 2003-03-07  6:23 UTC (permalink / raw)
  To: Zwane Mwaikambo; +Cc: linux-kernel

Zwane Mwaikambo <zwane@linuxpower.ca> wrote:
>
> This just popped up on my screen, seems to have been triggered by sar/cron 
> (i'll probably have to reboot the box soon)
> 
> slab error in check_poison_obj(): cache `size-64': object was modified after freeing
> Call Trace:
>  [<c0142226>] check_poison_obj+0x66/0x70
>  [<c0143b92>] kmalloc+0xd2/0x180
>  [<c0166078>] pipe_new+0x28/0xd0
>  [<c0166153>] get_pipe_inode+0x23/0xb0
>  [<c0166212>] do_pipe+0x32/0x1e0
>  [<c0111ed3>] sys_pipe+0x13/0x60
>  [<c010ad9b>] syscall_call+0x7/0xb

Don't know.  If you're using anticipatory scheduler in 2.5.63-mmfoo this
will happen. 64-mm1 is OK.

> Unable to handle kernel paging request at virtual address 2020202b
>  printing eip:
> c010cbd7
> *pde = 5a5a5a5a
> Oops: 0002
> CPU:    0
> EIP:    0060:[<c010cbd7>]    Not tainted
> EFLAGS: 00010283
> EIP is at show_interrupts+0x237/0x270
> eax: 20202020   ebx: e4f798a4   ecx: 00000000   edx: 0000000b
> esi: c02ba31b   edi: 00000020   ebp: 00000000   esp: e424df00
> ds: 007b   es: 007b   ss: 0068
> Process sadc (pid: 1250, threadinfo=e424c000 task=e43780e0)
> Stack: 00000390 c03b40a0 000000e0 00000001 e4f799bc 00000001 e4f799bc c0178e68 
>        e4f799bc 00000001 e424df38 00000000 e424df48 00000001 00000000 00000000 
>        e41d1870 e457ae84 e4649ef0 e4649ee4 00000000 40014000 e3830b54 00000400 
> Call Trace:
>  [<c0178e68>] seq_read+0x108/0x2c0
>  [<c01590d8>] vfs_read+0xa8/0x160
>  [<c01593ca>] sys_read+0x2a/0x40
>  [<c010ad9b>] syscall_call+0x7/0xb
> 
> Code: c6 04 02 0a ff 43 0c a1 60 6a 3b c0 50 68 21 a3 2b c0 53 e8 
> 
> (gdb) list *show_interrupts+0x237
> 0xc010cbd7 is in show_interrupts (include/linux/seq_file.h:40).
> 35	int seq_escape(struct seq_file *, const char *, const char *);
> 36	
> 37	static inline int seq_putc(struct seq_file *m, char c)
> 38	{
> 39		if (m->count < m->size) {
> 40			m->buf[m->count++] = c;
> 41			return 0;
> 42		}
> 43		return -1;

show_interrupts() is walking the per-irq action chain without locking it.
Any concurrent add/remove activity will explode.

Do you want to hunt down all the show_interrupts() instances and pop a
spin_lock_irq(desc->lock) around them?



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Oops: 2.5.64 check_obj_poison for 'size-64'
  2003-03-07  6:23 ` Andrew Morton
@ 2003-03-07  7:22   ` Zwane Mwaikambo
  2003-03-07  7:35     ` Andrew Morton
  0 siblings, 1 reply; 20+ messages in thread
From: Zwane Mwaikambo @ 2003-03-07  7:22 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

On Thu, 6 Mar 2003, Andrew Morton wrote:

> Zwane Mwaikambo <zwane@linuxpower.ca> wrote:
> >
> > This just popped up on my screen, seems to have been triggered by sar/cron 
> > (i'll probably have to reboot the box soon)
> > 
> > slab error in check_poison_obj(): cache `size-64': object was modified after freeing
> > Call Trace:
> >  [<c0142226>] check_poison_obj+0x66/0x70
> >  [<c0143b92>] kmalloc+0xd2/0x180
> >  [<c0166078>] pipe_new+0x28/0xd0
> >  [<c0166153>] get_pipe_inode+0x23/0xb0
> >  [<c0166212>] do_pipe+0x32/0x1e0
> >  [<c0111ed3>] sys_pipe+0x13/0x60
> >  [<c010ad9b>] syscall_call+0x7/0xb
> 
> Don't know.  If you're using anticipatory scheduler in 2.5.63-mmfoo this
> will happen. 64-mm1 is OK.

Nope simply 2.5.64-unwashed. I don't know how to twiddle the advanced 
knobs

> show_interrupts() is walking the per-irq action chain without locking it.
> Any concurrent add/remove activity will explode.
> 
> Do you want to hunt down all the show_interrupts() instances and pop a
> spin_lock_irq(desc->lock) around them?

Sure thing.

Thanks,
	Zwane
-- 
function.linuxpower.ca

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Oops: 2.5.64 check_obj_poison for 'size-64'
  2003-03-07  7:22   ` Zwane Mwaikambo
@ 2003-03-07  7:35     ` Andrew Morton
  2003-03-07  7:40       ` Zwane Mwaikambo
                         ` (3 more replies)
  0 siblings, 4 replies; 20+ messages in thread
From: Andrew Morton @ 2003-03-07  7:35 UTC (permalink / raw)
  To: Zwane Mwaikambo; +Cc: linux-kernel

Zwane Mwaikambo <zwane@linuxpower.ca> wrote:
>
> On Thu, 6 Mar 2003, Andrew Morton wrote:
> 
> > Zwane Mwaikambo <zwane@linuxpower.ca> wrote:
> > >
> > > This just popped up on my screen, seems to have been triggered by sar/cron 
> > > (i'll probably have to reboot the box soon)
> > > 
> > > slab error in check_poison_obj(): cache `size-64': object was modified after freeing
> > > Call Trace:
> > >  [<c0142226>] check_poison_obj+0x66/0x70
> > >  [<c0143b92>] kmalloc+0xd2/0x180
> > >  [<c0166078>] pipe_new+0x28/0xd0
> > >  [<c0166153>] get_pipe_inode+0x23/0xb0
> > >  [<c0166212>] do_pipe+0x32/0x1e0
> > >  [<c0111ed3>] sys_pipe+0x13/0x60
> > >  [<c010ad9b>] syscall_call+0x7/0xb
> > 
> > Don't know.  If you're using anticipatory scheduler in 2.5.63-mmfoo this
> > will happen. 64-mm1 is OK.
> 
> Nope simply 2.5.64-unwashed. I don't know how to twiddle the advanced 
> knobs

OK.  -mm has a more sophisticated use-after-free detector.  It might be
worth dropping that in there, see if we can get more info.

ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.5/2.5.64/2.5.64-mm1/broken-out/use-after-free-check.patch

> > show_interrupts() is walking the per-irq action chain without locking it.
> > Any concurrent add/remove activity will explode.
> > 
> > Do you want to hunt down all the show_interrupts() instances and pop a
> > spin_lock_irq(desc->lock) around them?
> 
> Sure thing.

OK, thanks.

All the arch/*/kernel/irq.c implementations are distressingly similar. 
Andrey Panin did a bunch of work a while back to start consolidating the
common code but it didn't quite get finished off.  Guess we just have to grit
our teeth for now.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Oops: 2.5.64 check_obj_poison for 'size-64'
  2003-03-07  7:35     ` Andrew Morton
@ 2003-03-07  7:40       ` Zwane Mwaikambo
  2003-03-07  7:45       ` Miles Bader
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 20+ messages in thread
From: Zwane Mwaikambo @ 2003-03-07  7:40 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

On Thu, 6 Mar 2003, Andrew Morton wrote:

> OK.  -mm has a more sophisticated use-after-free detector.  It might be
> worth dropping that in there, see if we can get more info.
> 
> ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.5/2.5.64/2.5.64-mm1/broken-out/use-after-free-check.patch

Ok i'll drop that in and leave it to run for a bit.

> OK, thanks.
> 
> All the arch/*/kernel/irq.c implementations are distressingly similar. 
> Andrey Panin did a bunch of work a while back to start consolidating the
> common code but it didn't quite get finished off.  Guess we just have to grit
> our teeth for now.

Possibly didn't continue due to lack of feedback, i think he had 
personally tested most i386 combos.

	Zwane
-- 
function.linuxpower.ca

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Oops: 2.5.64 check_obj_poison for 'size-64'
  2003-03-07  7:35     ` Andrew Morton
  2003-03-07  7:40       ` Zwane Mwaikambo
@ 2003-03-07  7:45       ` Miles Bader
  2003-03-07  7:58         ` Andrew Morton
  2003-03-07 10:05       ` [PATCH] protect 'action' in show_interrupts Zwane Mwaikambo
       [not found]       ` <Pine.LNX.4.50.0303070351060.18716-100000@montezuma.mastecende.com>
  3 siblings, 1 reply; 20+ messages in thread
From: Miles Bader @ 2003-03-07  7:45 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Zwane Mwaikambo, linux-kernel

Andrew Morton <akpm@digeo.com> writes:
> All the arch/*/kernel/irq.c implementations are distressingly similar. 
> Andrey Panin did a bunch of work a while back to start consolidating the
> common code but it didn't quite get finished off.

Do you remember what was unfinished about it?  I tried his patch, and it
seemed to work fine; there were certainly still a few things left unmerged,
but it was a _huge_ improvement over the current state.

I never saw any responses to his messages on the lkml (except for mine!).

-Miles
-- 
o The existentialist, not having a pillow, goes everywhere with the book by
  Sullivan, _I am going to spit on your graves_.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Oops: 2.5.64 check_obj_poison for 'size-64'
  2003-03-07  7:45       ` Miles Bader
@ 2003-03-07  7:58         ` Andrew Morton
  2003-03-07  8:10           ` Miles Bader
  0 siblings, 1 reply; 20+ messages in thread
From: Andrew Morton @ 2003-03-07  7:58 UTC (permalink / raw)
  To: Miles Bader; +Cc: miles, zwane, linux-kernel

Miles Bader <miles@lsi.nec.co.jp> wrote:
>
> Andrew Morton <akpm@digeo.com> writes:
> > All the arch/*/kernel/irq.c implementations are distressingly similar. 
> > Andrey Panin did a bunch of work a while back to start consolidating the
> > common code but it didn't quite get finished off.
> 
> Do you remember what was unfinished about it?  I tried his patch, and it
> seemed to work fine; there were certainly still a few things left unmerged,
> but it was a _huge_ improvement over the current state.

Well I thought that many architectures were missing.  But upon a re-read, I
see that he allowed architectures to be cut over to GENERIC_IRQ one at a
time.  Seems fine.

Although at some point we really do need to stop cleaning stuff up, defer such
things into 2.7 and concentrate upon 2.5 bugs.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Oops: 2.5.64 check_obj_poison for 'size-64'
  2003-03-07  7:58         ` Andrew Morton
@ 2003-03-07  8:10           ` Miles Bader
  0 siblings, 0 replies; 20+ messages in thread
From: Miles Bader @ 2003-03-07  8:10 UTC (permalink / raw)
  To: Andrew Morton; +Cc: zwane, linux-kernel

Andrew Morton <akpm@digeo.com> writes:
> Although at some point we really do need to stop cleaning stuff up,
> defer such things into 2.7 and concentrate upon 2.5 bugs.

Agreed, though I think this particular cleanup is almost absurdly
straight-forward, and seems very unlikely to cause any problems
(for the most part it's really just moving stuff from one file to
another).

I'd think all the spelling corrections would be more controversial. :-)

-Miles
-- 
Suburbia: where they tear out the trees and then name streets after them.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Oops: 2.5.64 check_obj_poison for 'size-64'
       [not found]         ` <20030307010539.3c0a14a3.akpm@digeo.com>
@ 2003-03-07  9:53           ` Zwane Mwaikambo
  2003-03-07 19:38           ` Manfred Spraul
  1 sibling, 0 replies; 20+ messages in thread
From: Zwane Mwaikambo @ 2003-03-07  9:53 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Manfred Spraul

On Fri, 7 Mar 2003, Andrew Morton wrote:

> > [root@dev16-002 root]# Slab corruption: start=db0bbc44, expend=db0bbc83, problemat=db0bbc48
> > Data: ....71 F0 2C .........................................................
> > Next: 71 F0 2C .71 F0 2C .........................
> > slab error in check_poison_obj(): cache `size-64': object was modified after freeing
> > Call Trace:
> >  [<c0142319>] check_poison_obj+0x119/0x130
> >  [<c0143c92>] kmalloc+0xd2/0x180
> >  [<c0166188>] pipe_new+0x28/0xd0
> >  [<c0166263>] get_pipe_inode+0x23/0xb0
> >  [<c0166322>] do_pipe+0x32/0x1e0
> >  [<c01704ac>] dput+0x1c/0x2b0
> >  [<c016661e>] getname+0x5e/0xa0
> >  [<c012f9b0>] sigprocmask+0xe0/0x150
> >  [<c012fb9a>] sys_rt_sigprocmask+0x17a/0x190
> >  [<c0111ed3>] sys_pipe+0x13/0x60
> >  [<c010ad9b>] syscall_call+0x7/0xb
> 
> I don't see any clues there.
> 
> This is a bad, bad bug.  How are you triggering it?

Very hard to trigger, currently it's happening whilst the system appears 
to be idle so i'm trying to track down what processes there are when the 
trigger happens.

> Manfred, would it be possible to add builtin_return_address(0) into each
> object, so we can find out who did the initial kmalloc (or kfree, even)?
> 
> It'll probably require CONFIG_FRAME_POINTER.

	Zwane
-- 
function.linuxpower.ca

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH] protect 'action' in show_interrupts
  2003-03-07  7:35     ` Andrew Morton
  2003-03-07  7:40       ` Zwane Mwaikambo
  2003-03-07  7:45       ` Miles Bader
@ 2003-03-07 10:05       ` Zwane Mwaikambo
  2003-03-07 10:28         ` Andrew Morton
       [not found]       ` <Pine.LNX.4.50.0303070351060.18716-100000@montezuma.mastecende.com>
  3 siblings, 1 reply; 20+ messages in thread
From: Zwane Mwaikambo @ 2003-03-07 10:05 UTC (permalink / raw)
  To: Linux Kernel

This patch protects a critical section in show_interrupts against 
removal of 'action' during traversal of the handlers. All the 
architectures in one swoop.

Index: linux-2.5.64/arch/alpha/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/alpha/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/alpha/kernel/irq.c	5 Mar 2003 05:08:08 -0000	1.1.1.1
+++ linux-2.5.64/arch/alpha/kernel/irq.c	7 Mar 2003 09:11:01 -0000
@@ -515,6 +515,7 @@
 #endif
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 #ifdef CONFIG_SMP
 	seq_puts(p, "           ");
@@ -537,16 +538,23 @@
 				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		if (!action)
+			goto unlock;
+
 		seq_printf(p, "  %c%s",
-			     (action->flags & SA_INTERRUPT)?'+':' ',
-			     action->name);
+			(action->flags & SA_INTERRUPT)?'+':' ',
+			action->name);
 
 		for (action=action->next; action; action = action->next) {
 			seq_printf(p, ", %c%s",
-				     (action->flags & SA_INTERRUPT)?'+':' ',
-				     action->name);
+				  (action->flags & SA_INTERRUPT)?'+':' ',
+				   action->name);
 		}
+
+unlock:
 		seq_putc(p, '\n');
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 #if CONFIG_SMP
 	seq_puts(p, "IPI: ");
Index: linux-2.5.64/arch/arm/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/arm/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/arm/kernel/irq.c	5 Mar 2003 05:08:11 -0000	1.1.1.1
+++ linux-2.5.64/arch/arm/kernel/irq.c	7 Mar 2003 08:49:53 -0000
@@ -165,17 +165,22 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
 	    	action = irq_desc[i].action;
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		if (!action)
-			continue;
+			goto unlock;
+
 		seq_printf(p, "%3d: %10u ", i, kstat_irqs(i));
 		seq_printf(p, "  %s", action->name);
-		for (action = action->next; action; action = action->next) {
+		for (action = action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
-		}
+
 		seq_putc(p, '\n');
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 
 #ifdef CONFIG_ARCH_ACORN
Index: linux-2.5.64/arch/cris/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/cris/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/cris/kernel/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/cris/kernel/irq.c	7 Mar 2003 09:09:08 -0000
@@ -228,11 +228,14 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0; i < NR_IRQS; i++) {
 		action = irq_action[i];
+
+		local_irq_save(flags);
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %10u %c %s",
 			i, kstat_cpu(0).irqs[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -243,6 +246,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/i386/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/i386/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/i386/kernel/irq.c	5 Mar 2003 05:08:03 -0000	1.1.1.1
+++ linux-2.5.64/arch/i386/kernel/irq.c	7 Mar 2003 09:04:43 -0000
 static void register_irq_proc (unsigned int irq);
@@ -135,6 +135,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_printf(p, "           ");
 	for (j=0; j<NR_CPUS; j++)
@@ -156,11 +157,17 @@
 					     kstat_cpu(j).irqs[i]);
 #endif
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		if (!action)
+			goto unlock;
 		seq_printf(p, "  %s", action->name);
 
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
+
+unlock:
 		seq_putc(p, '\n');
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	seq_printf(p, "NMI: ");
 	for (j = 0; j < NR_CPUS; j++)
Index: linux-2.5.64/arch/ia64/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/ia64/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/ia64/kernel/irq.c	5 Mar 2003 05:08:13 -0000	1.1.1.1
+++ linux-2.5.64/arch/ia64/kernel/irq.c	7 Mar 2003 08:41:09 -0000
@@ -154,6 +154,7 @@
 	int i, j;
 	struct irqaction * action;
 	irq_desc_t *idesc;
+	unsigned long flags;
 
 	seq_puts(p, "           ");
 	for (j=0; j<NR_CPUS; j++)
@@ -175,10 +176,13 @@
 				seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
 #endif
 		seq_printf(p, " %14s", idesc->handler->typename);
-		seq_printf(p, "  %s", action->name);
-
-		for (action=action->next; action; action = action->next)
-			seq_printf(p, ", %s", action->name);
+		spin_lock_irqsave(&idesc->lock, flags);
+		if (action) {
+			seq_printf(p, "  %s", action->name);
+			for (action=action->next; action; action = action->next)
+				seq_printf(p, ", %s", action->name);
+		}
+		spin_unlock_irqrestore(&idesc->lock, flags);
 		seq_putc(p, '\n');
 	}
 	seq_puts(p, "NMI: ");
Index: linux-2.5.64/arch/mips/baget/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/baget/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/baget/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/baget/irq.c	7 Mar 2003 09:48:06 -0000
@@ -146,11 +146,13 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < BAGET_IRQ_NR ; i++) {
 		action = irq_action[i];
+		local_irq_save(flags);
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s",
 			i, kstat_cpu(0).irqs[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -161,6 +163,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips/dec/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/dec/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/dec/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/dec/irq.c	7 Mar 2003 09:47:41 -0000
@@ -97,11 +97,13 @@
 {
 	int i;
 	struct irqaction *action;
+	unsigned long flags;
 
 	for (i = 0; i < 32; i++) {
 		action = irq_action[i];
+		local_irq_save(flags);
 		if (!action)
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s",
 				i, kstat_cpu(0).irqs[i],
 				(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -112,6 +114,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips/ite-boards/generic/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/ite-boards/generic/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/ite-boards/generic/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/ite-boards/generic/irq.c	7 Mar 2003 09:25:42 -0000
@@ -222,6 +222,7 @@
 {
         int i, j;
         struct irqaction * action;
+	unsigned long flags;
 
         seq_printf(p, "           ");
         for (j=0; j<smp_num_cpus; j++)
@@ -230,6 +231,7 @@
 
         for (i = 0 ; i < NR_IRQS ; i++) {
                 action = irq_desc[i].action;
+
                 if ( !action || !action->handler )
                         continue;
                 seq_printf(p, "%3d: ", i);		
@@ -238,11 +240,17 @@
                         seq_printf(p, " %s ", irq_desc[i].handler->typename );
                 else
                         seq_puts(p, "  None      ");
+
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		if (!action)
+			goto unlock;
                 seq_printf(p, "    %s",action->name);
                 for (action=action->next; action; action = action->next) {
                         seq_printf(p, ", %s", action->name);
                 }
+unlock:
                 seq_putc(p, '\n');
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
         }
         seq_printf(p, "BAD: %10lu\n", spurious_count);
         return 0;
Index: linux-2.5.64/arch/mips/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/kernel/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/kernel/irq.c	7 Mar 2003 09:27:16 -0000
@@ -73,8 +73,9 @@
 int show_interrupts(struct seq_file *p, void *v)
 {
 	struct irqaction * action;
+	unsigned long flags;
 	int i;
-
+	
 	seq_puts(p, "           ");
 	for (i=0; i < 1 /*smp_num_cpus*/; i++)
 		seq_printf(p, "CPU%d       ", i);
@@ -82,8 +83,9 @@
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
 		action = irq_desc[i].action;
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		if (!action) 
-			continue;
+			goto unlock;
 		seq_printf(p, "%3d: ",i);
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
@@ -92,6 +94,8 @@
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	seq_printf(p, "ERR: %10lu\n", irq_err_count);
 	return 0;
Index: linux-2.5.64/arch/mips/kernel/old-irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/kernel/old-irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 old-irq.c
--- linux-2.5.64/arch/mips/kernel/old-irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/kernel/old-irq.c	7 Mar 2003 09:45:07 -0000
@@ -128,11 +128,13 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < 32 ; i++) {
 		action = irq_action[i];
+		local_irq_save(flags);
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s",
 			i, kstat_cpu(0).irqs[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -143,6 +145,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips/mips-boards/atlas/atlas_int.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/mips-boards/atlas/atlas_int.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 atlas_int.c
--- linux-2.5.64/arch/mips/mips-boards/atlas/atlas_int.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/mips-boards/atlas/atlas_int.c	7 Mar 2003 09:30:36 -0000
@@ -99,11 +99,13 @@
 	int i;
 	int num = 0;
 	struct irqaction *action;
+	unsigned long flags;
 
 	for (i = 0; i < ATLASINT_END; i++, num++) {
 		action = irq_desc[i].action;
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		if (!action) 
-			continue;
+			goto unlock;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -114,6 +116,8 @@
 				action->name);
 		}
 		seq_printf(p, " [hw0]\n");
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips/philips/nino/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/philips/nino/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/philips/nino/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/philips/nino/irq.c	7 Mar 2003 09:46:43 -0000
@@ -119,11 +119,13 @@
 {
     int i;
     struct irqaction *action;
+    unsigned long flags;
 
     for (i = 0; i < NR_IRQS; i++) {
 	action = irq_action[i];
+	local_irq_save(flags);
 	if (!action)
-	    continue;
+	    goto skip;
 	seq_printf(p, "%2d: %8d %c %s",
 		       i, kstat_cpu(0).irqs[i],
 		       (action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -134,6 +136,8 @@
 			   action->name);
 	}
 	seq_putc(p, '\n');
+skip:
+	local_irq_restore(flags);
     }
     return 0;
 }
Index: linux-2.5.64/arch/mips64/mips-boards/atlas/atlas_int.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips64/mips-boards/atlas/atlas_int.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 atlas_int.c
--- linux-2.5.64/arch/mips64/mips-boards/atlas/atlas_int.c	5 Mar 2003 05:08:15 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips64/mips-boards/atlas/atlas_int.c	7 Mar 2003 09:33:55 -0000
@@ -95,11 +95,13 @@
 	int i;
 	int num = 0;
 	struct irqaction *action;
+	unsigned long flags;
 
 	for (i = 0; i < ATLASINT_END; i++, num++) {
 		action = irq_desc[i].action;
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		if (!action) 
-			continue;
+			goto unlock;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -110,6 +112,8 @@
 				action->name);
 		}
 		seq_puts(p, " [hw0]\n");
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips64/mips-boards/malta/malta_int.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips64/mips-boards/malta/malta_int.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 malta_int.c
--- linux-2.5.64/arch/mips64/mips-boards/malta/malta_int.c	5 Mar 2003 05:08:15 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips64/mips-boards/malta/malta_int.c	7 Mar 2003 09:44:50 -0000
@@ -125,11 +125,13 @@
 	int i;
 	int num = 0;
 	struct irqaction *action;
+	unsigned long flags;
 
 	for (i = 0; i < 8; i++, num++) {
 		action = irq_action[i];
+		local_irq_save(flags);
 		if (!action) 
-			continue;
+			goto skip_1;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -140,11 +142,14 @@
 				action->name);
 		}
 		seq_puts(p, " [on-chip]\n");
+skip_1:
+		local_irq_restore(flags);
 	}
 	for (i = 0; i < MALTAINT_END; i++, num++) {
 		action = hw0_irq_action[i];
+		local_irq_save(flags);
 		if (!action) 
-			continue;
+			goto skip_2;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -155,6 +160,8 @@
 				action->name);
 		}
 		seq_puts(p, " [hw0]\n");
+skip_2:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips64/sgi-ip22/ip22-int.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips64/sgi-ip22/ip22-int.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ip22-int.c
--- linux-2.5.64/arch/mips64/sgi-ip22/ip22-int.c	5 Mar 2003 05:08:15 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips64/sgi-ip22/ip22-int.c	7 Mar 2003 09:41:57 -0000
@@ -237,11 +237,13 @@
 	int i;
 	int num = 0;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < 16 ; i++, num++) {
 		action = irq_action[i];
+		local_irq_save(flags);
 		if (!action) 
-			continue;
+			goto skip_1;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -252,11 +254,14 @@
 				action->name);
 		}
 		seq_puts(p, " [on-chip]\n");
+skip_1:
+		local_irq_restore(flags);
 	}
 	for (i = 0 ; i < 24 ; i++, num++) {
 		action = local_irq_action[i];
+		local_irq_save(flags);
 		if (!action) 
-			continue;
+			goto skip_2;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -267,6 +272,8 @@
 				action->name);
 		}
 		seq_puts(p, " [local]\n");
+skip_2:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips64/sgi-ip27/ip27-irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips64/sgi-ip27/ip27-irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ip27-irq.c
--- linux-2.5.64/arch/mips64/sgi-ip27/ip27-irq.c	5 Mar 2003 05:08:15 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips64/sgi-ip27/ip27-irq.c	7 Mar 2003 09:43:16 -0000
@@ -141,11 +141,13 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
 		action = irq_action[i];
+		local_irq_save(flags);
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s", i, kstat_cpu(0).irqs[i],
 		               (action->flags & SA_INTERRUPT) ? '+' : ' ',
 		               action->name);
@@ -156,6 +158,8 @@
 			                action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/ppc/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/ppc/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/ppc/kernel/irq.c	5 Mar 2003 05:08:03 -0000	1.1.1.1
+++ linux-2.5.64/arch/ppc/kernel/irq.c	7 Mar 2003 08:43:48 -0000
@@ -346,6 +346,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_puts(p, "           ");
 	for (j=0; j<NR_CPUS; j++)
@@ -371,9 +372,13 @@
 		else
 			seq_puts(p, "  None      ");
 		seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge  ");
-		seq_printf(p, "    %s", action->name);
-		for (action = action->next; action; action = action->next)
-			seq_printf(p, ", %s", action->name);
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		if (action) {
+			seq_printf(p, "    %s", action->name);
+			for (action = action->next; action; action = action->next)
+				seq_printf(p, ", %s", action->name);
+		}
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 		seq_putc(p, '\n');
 	}
 #ifdef CONFIG_TAU_INT
Index: linux-2.5.64/arch/ppc64/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/ppc64/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/ppc64/kernel/irq.c	5 Mar 2003 05:08:10 -0000	1.1.1.1
+++ linux-2.5.64/arch/ppc64/kernel/irq.c	7 Mar 2003 08:45:10 -0000
@@ -341,6 +341,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_printf(p, "           ");
 	for (j=0; j<NR_CPUS; j++) {
@@ -367,9 +368,13 @@
 		else
 			seq_printf(p, "  None      ");
 		seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge  ");
-		seq_printf(p, "    %s",action->name);
-		for (action=action->next; action; action = action->next)
-			seq_printf(p, ", %s", action->name);
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		if (action) {
+			seq_printf(p, "    %s",action->name);
+			for (action=action->next; action; action = action->next)
+				seq_printf(p, ", %s", action->name);
+		}
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 		seq_putc(p, '\n');
 	}
 	seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
Index: linux-2.5.64/arch/sh/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/sh/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/sh/kernel/irq.c	5 Mar 2003 05:08:16 -0000	1.1.1.1
+++ linux-2.5.64/arch/sh/kernel/irq.c	7 Mar 2003 09:06:38 -0000
@@ -90,6 +90,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_puts(p, "           ");
 	for (j=0; j<smp_num_cpus; j++)
@@ -98,8 +99,9 @@
 
 	for (i = 0 ; i < ACTUAL_NR_IRQS ; i++) {
 		action = irq_desc[i].action;
-		if (!action) 
-			continue;
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		if (!action)
+			goto unlock;
 		seq_printf(p, "%3d: ",i);
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
@@ -108,6 +110,8 @@
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/v850/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/v850/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/v850/kernel/irq.c	5 Mar 2003 05:08:16 -0000	1.1.1.1
+++ linux-2.5.64/arch/v850/kernel/irq.c	7 Mar 2003 09:05:29 -0000
@@ -78,6 +78,7 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_puts(p, "           ");
 	for (i=0; i < 1 /*smp_num_cpus*/; i++)
@@ -108,11 +109,16 @@
 			seq_printf(p, " %*s%d", 14 - prec, type_name, num);
 		} else
 			seq_printf(p, " %14s", type_name);
+		spin_lock_irqsave(&irq_desc[j].lock, flags);
+		if (!action)
+			goto unlock;
 		seq_printf(p, "  %s", action->name);
 
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
+unlock:
 		seq_putc(p, '\n');
+		spin_unlock_irqrestore(&irq_desc[j].lock, flags);
 	}
 	seq_printf(p, "ERR: %10lu\n", irq_err_count);
 	return 0;
Index: linux-2.5.64/arch/x86_64/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/x86_64/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/x86_64/kernel/irq.c	5 Mar 2003 05:08:16 -0000	1.1.1.1
+++ linux-2.5.64/arch/x86_64/kernel/irq.c	7 Mar 2003 09:05:00 -0000
@@ -135,6 +135,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_printf(p, "           ");
 	for (j=0; j<NR_CPUS; j++)
@@ -156,11 +157,17 @@
 				kstat_cpu(j).irqs[i]);
 #endif
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
+
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
+		if (!action)
+			goto unlock;
 		seq_printf(p, "  %s", action->name);
 
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
+unlock:
 		seq_putc(p, '\n');
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	seq_printf(p, "NMI: ");
 	for (j = 0; j < NR_CPUS; j++)

-- 
function.linuxpower.ca

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] protect 'action' in show_interrupts
  2003-03-07 10:05       ` [PATCH] protect 'action' in show_interrupts Zwane Mwaikambo
@ 2003-03-07 10:28         ` Andrew Morton
  2003-03-07 15:32           ` Zwane Mwaikambo
  0 siblings, 1 reply; 20+ messages in thread
From: Andrew Morton @ 2003-03-07 10:28 UTC (permalink / raw)
  To: Zwane Mwaikambo; +Cc: linux-kernel

Zwane Mwaikambo <zwane@linuxpower.ca> wrote:
>
> This patch protects a critical section in show_interrupts against 
> removal of 'action' during traversal of the handlers. All the 
> architectures in one swoop.

Thanks for doing this.

> ...
> --- linux-2.5.64/arch/i386/kernel/irq.c	5 Mar 2003 05:08:03 -0000	1.1.1.1
> +++ linux-2.5.64/arch/i386/kernel/irq.c	7 Mar 2003 09:04:43 -0000
>  static void register_irq_proc (unsigned int irq);
> @@ -135,6 +135,7 @@
>  {
>  	int i, j;
>  	struct irqaction * action;
> +	unsigned long flags;
>  
>  	seq_printf(p, "           ");
>  	for (j=0; j<NR_CPUS; j++)
> @@ -156,11 +157,17 @@
>  					     kstat_cpu(j).irqs[i]);
>  #endif
>  		seq_printf(p, " %14s", irq_desc[i].handler->typename);
> +		spin_lock_irqsave(&irq_desc[i].lock, flags);
> +		if (!action)
> +			goto unlock;
> +		seq_printf(p, "  %s", action->name);
 
Local variable `action' could be pointing at freed memory by now.  We need to
reload it inside the lock.  Or just hold the lock across the entire loop.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] protect 'action' in show_interrupts
  2003-03-07 10:28         ` Andrew Morton
@ 2003-03-07 15:32           ` Zwane Mwaikambo
  2003-03-07 15:46             ` Russell King
  0 siblings, 1 reply; 20+ messages in thread
From: Zwane Mwaikambo @ 2003-03-07 15:32 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux Kernel

On Fri, 7 Mar 2003, Andrew Morton wrote:

> Local variable `action' could be pointing at freed memory by now.  We need to
> reload it inside the lock.  Or just hold the lock across the entire loop.

Oops monkey at the helm...

PS sparc is just a strange one. I wonder if i should just grab the global 
irq lock (urgh...)

Index: linux-2.5.64/arch/alpha/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/alpha/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/alpha/kernel/irq.c	5 Mar 2003 05:08:08 -0000	1.1.1.1
+++ linux-2.5.64/arch/alpha/kernel/irq.c	7 Mar 2003 15:05:23 -0000
@@ -515,6 +515,7 @@
 #endif
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 #ifdef CONFIG_SMP
 	seq_puts(p, "           ");
@@ -525,9 +526,10 @@
 #endif
 
 	for (i = 0; i < ACTUAL_NR_IRQS; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto unlock;
 		seq_printf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
@@ -538,15 +540,18 @@
 #endif
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
 		seq_printf(p, "  %c%s",
-			     (action->flags & SA_INTERRUPT)?'+':' ',
-			     action->name);
+			(action->flags & SA_INTERRUPT)?'+':' ',
+			action->name);
 
 		for (action=action->next; action; action = action->next) {
 			seq_printf(p, ", %c%s",
-				     (action->flags & SA_INTERRUPT)?'+':' ',
-				     action->name);
+				  (action->flags & SA_INTERRUPT)?'+':' ',
+				   action->name);
 		}
+
 		seq_putc(p, '\n');
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 #if CONFIG_SMP
 	seq_puts(p, "IPI: ");
Index: linux-2.5.64/arch/arm/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/arm/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/arm/kernel/irq.c	5 Mar 2003 05:08:11 -0000	1.1.1.1
+++ linux-2.5.64/arch/arm/kernel/irq.c	7 Mar 2003 15:05:36 -0000
@@ -165,17 +165,22 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 	    	action = irq_desc[i].action;
 		if (!action)
-			continue;
+			goto unlock;
+
 		seq_printf(p, "%3d: %10u ", i, kstat_irqs(i));
 		seq_printf(p, "  %s", action->name);
-		for (action = action->next; action; action = action->next) {
+		for (action = action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
-		}
+
 		seq_putc(p, '\n');
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 
 #ifdef CONFIG_ARCH_ACORN
Index: linux-2.5.64/arch/cris/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/cris/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/cris/kernel/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/cris/kernel/irq.c	7 Mar 2003 15:06:02 -0000
@@ -228,11 +228,13 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0; i < NR_IRQS; i++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %10u %c %s",
 			i, kstat_cpu(0).irqs[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -243,6 +245,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/i386/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/i386/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/i386/kernel/irq.c	5 Mar 2003 05:08:03 -0000	1.1.1.1
+++ linux-2.5.64/arch/i386/kernel/irq.c	7 Mar 2003 15:15:28 -0000
@@ -135,6 +135,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_printf(p, "           ");
 	for (j=0; j<NR_CPUS; j++)
@@ -143,9 +144,10 @@
 	seq_putc(p, '\n');
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
@@ -160,7 +162,10 @@
 
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
+
 		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	seq_printf(p, "NMI: ");
 	for (j = 0; j < NR_CPUS; j++)
Index: linux-2.5.64/arch/ia64/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/ia64/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/ia64/kernel/irq.c	5 Mar 2003 05:08:13 -0000	1.1.1.1
+++ linux-2.5.64/arch/ia64/kernel/irq.c	7 Mar 2003 15:07:18 -0000
@@ -154,6 +154,7 @@
 	int i, j;
 	struct irqaction * action;
 	irq_desc_t *idesc;
+	unsigned long flags;
 
 	seq_puts(p, "           ");
 	for (j=0; j<NR_CPUS; j++)
@@ -163,9 +164,10 @@
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
 		idesc = irq_desc(i);
+		spin_lock_irqsave(&idesc->lock, flags);
 		action = idesc->action;
 		if (!action)
-			continue;
+			goto skip;
 		seq_printf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
@@ -176,10 +178,12 @@
 #endif
 		seq_printf(p, " %14s", idesc->handler->typename);
 		seq_printf(p, "  %s", action->name);
-
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
+		
 		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&idesc->lock, flags);
 	}
 	seq_puts(p, "NMI: ");
 	for (j = 0; j < NR_CPUS; j++)
Index: linux-2.5.64/arch/mips/baget/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/baget/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/baget/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/baget/irq.c	7 Mar 2003 15:15:45 -0000
@@ -146,11 +146,13 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < BAGET_IRQ_NR ; i++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s",
 			i, kstat_cpu(0).irqs[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -161,6 +163,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips/dec/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/dec/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/dec/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/dec/irq.c	7 Mar 2003 15:26:50 -0000
@@ -97,11 +97,13 @@
 {
 	int i;
 	struct irqaction *action;
+	unsigned long flags;
 
 	for (i = 0; i < 32; i++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action)
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s",
 				i, kstat_cpu(0).irqs[i],
 				(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -112,6 +114,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips/ite-boards/generic/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/ite-boards/generic/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/ite-boards/generic/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/ite-boards/generic/irq.c	7 Mar 2003 15:16:41 -0000
@@ -222,6 +222,7 @@
 {
         int i, j;
         struct irqaction * action;
+	unsigned long flags;
 
         seq_printf(p, "           ");
         for (j=0; j<smp_num_cpus; j++)
@@ -229,20 +230,25 @@
 	seq_putc(p, '\n');
 
         for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
                 action = irq_desc[i].action;
+
                 if ( !action || !action->handler )
-                        continue;
+                        goto skip;
                 seq_printf(p, "%3d: ", i);		
                 seq_printf(p, "%10u ", kstat_irqs(i));
                 if ( irq_desc[i].handler )		
                         seq_printf(p, " %s ", irq_desc[i].handler->typename );
                 else
                         seq_puts(p, "  None      ");
+
                 seq_printf(p, "    %s",action->name);
                 for (action=action->next; action; action = action->next) {
                         seq_printf(p, ", %s", action->name);
                 }
                 seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
         }
         seq_printf(p, "BAD: %10lu\n", spurious_count);
         return 0;
Index: linux-2.5.64/arch/mips/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/kernel/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/kernel/irq.c	7 Mar 2003 15:16:59 -0000
@@ -73,17 +73,19 @@
 int show_interrupts(struct seq_file *p, void *v)
 {
 	struct irqaction * action;
+	unsigned long flags;
 	int i;
-
+	
 	seq_puts(p, "           ");
 	for (i=0; i < 1 /*smp_num_cpus*/; i++)
 		seq_printf(p, "CPU%d       ", i);
 	seq_putc(p, '\n');
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto unlock;
 		seq_printf(p, "%3d: ",i);
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
@@ -92,6 +94,8 @@
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	seq_printf(p, "ERR: %10lu\n", irq_err_count);
 	return 0;
Index: linux-2.5.64/arch/mips/kernel/old-irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/kernel/old-irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 old-irq.c
--- linux-2.5.64/arch/mips/kernel/old-irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/kernel/old-irq.c	7 Mar 2003 15:26:35 -0000
@@ -128,11 +128,13 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < 32 ; i++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s",
 			i, kstat_cpu(0).irqs[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -143,6 +145,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips/mips-boards/atlas/atlas_int.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/mips-boards/atlas/atlas_int.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 atlas_int.c
--- linux-2.5.64/arch/mips/mips-boards/atlas/atlas_int.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/mips-boards/atlas/atlas_int.c	7 Mar 2003 15:18:07 -0000
@@ -99,11 +99,13 @@
 	int i;
 	int num = 0;
 	struct irqaction *action;
+	unsigned long flags;
 
 	for (i = 0; i < ATLASINT_END; i++, num++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -114,6 +116,8 @@
 				action->name);
 		}
 		seq_printf(p, " [hw0]\n");
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips/philips/nino/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/philips/nino/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/philips/nino/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/philips/nino/irq.c	7 Mar 2003 15:17:31 -0000
@@ -119,11 +119,13 @@
 {
     int i;
     struct irqaction *action;
+    unsigned long flags;
 
     for (i = 0; i < NR_IRQS; i++) {
+	local_irq_save(flags);
 	action = irq_action[i];
 	if (!action)
-	    continue;
+	    goto skip;
 	seq_printf(p, "%2d: %8d %c %s",
 		       i, kstat_cpu(0).irqs[i],
 		       (action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -134,6 +136,8 @@
 			   action->name);
 	}
 	seq_putc(p, '\n');
+skip:
+	local_irq_restore(flags);
     }
     return 0;
 }
Index: linux-2.5.64/arch/mips64/mips-boards/atlas/atlas_int.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips64/mips-boards/atlas/atlas_int.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 atlas_int.c
--- linux-2.5.64/arch/mips64/mips-boards/atlas/atlas_int.c	5 Mar 2003 05:08:15 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips64/mips-boards/atlas/atlas_int.c	7 Mar 2003 15:03:22 -0000
@@ -95,11 +95,13 @@
 	int i;
 	int num = 0;
 	struct irqaction *action;
+	unsigned long flags;
 
 	for (i = 0; i < ATLASINT_END; i++, num++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto unlock;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -110,6 +112,8 @@
 				action->name);
 		}
 		seq_puts(p, " [hw0]\n");
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips64/mips-boards/malta/malta_int.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips64/mips-boards/malta/malta_int.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 malta_int.c
--- linux-2.5.64/arch/mips64/mips-boards/malta/malta_int.c	5 Mar 2003 05:08:15 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips64/mips-boards/malta/malta_int.c	7 Mar 2003 15:23:14 -0000
@@ -125,11 +125,13 @@
 	int i;
 	int num = 0;
 	struct irqaction *action;
+	unsigned long flags;
 
 	for (i = 0; i < 8; i++, num++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action) 
-			continue;
+			goto skip_1;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -140,11 +142,14 @@
 				action->name);
 		}
 		seq_puts(p, " [on-chip]\n");
+skip_1:
+		local_irq_restore(flags);
 	}
 	for (i = 0; i < MALTAINT_END; i++, num++) {
+		local_irq_save(flags);
 		action = hw0_irq_action[i];
 		if (!action) 
-			continue;
+			goto skip_2;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -155,6 +160,8 @@
 				action->name);
 		}
 		seq_puts(p, " [hw0]\n");
+skip_2:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips64/sgi-ip22/ip22-int.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips64/sgi-ip22/ip22-int.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ip22-int.c
--- linux-2.5.64/arch/mips64/sgi-ip22/ip22-int.c	5 Mar 2003 05:08:15 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips64/sgi-ip22/ip22-int.c	7 Mar 2003 15:04:05 -0000
@@ -237,11 +237,13 @@
 	int i;
 	int num = 0;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < 16 ; i++, num++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action) 
-			continue;
+			goto skip_1;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -252,11 +254,14 @@
 				action->name);
 		}
 		seq_puts(p, " [on-chip]\n");
+skip_1:
+		local_irq_restore(flags);
 	}
 	for (i = 0 ; i < 24 ; i++, num++) {
+		local_irq_save(flags);
 		action = local_irq_action[i];
 		if (!action) 
-			continue;
+			goto skip_2;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -267,6 +272,8 @@
 				action->name);
 		}
 		seq_puts(p, " [local]\n");
+skip_2:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips64/sgi-ip27/ip27-irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips64/sgi-ip27/ip27-irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ip27-irq.c
--- linux-2.5.64/arch/mips64/sgi-ip27/ip27-irq.c	5 Mar 2003 05:08:15 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips64/sgi-ip27/ip27-irq.c	7 Mar 2003 15:04:20 -0000
@@ -141,11 +141,13 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s", i, kstat_cpu(0).irqs[i],
 		               (action->flags & SA_INTERRUPT) ? '+' : ' ',
 		               action->name);
@@ -156,6 +158,8 @@
 			                action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/ppc/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/ppc/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/ppc/kernel/irq.c	5 Mar 2003 05:08:03 -0000	1.1.1.1
+++ linux-2.5.64/arch/ppc/kernel/irq.c	7 Mar 2003 15:08:19 -0000
@@ -346,6 +346,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_puts(p, "           ");
 	for (j=0; j<NR_CPUS; j++)
@@ -354,9 +355,10 @@
 	seq_putc(p, '\n');
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if ( !action || !action->handler )
-			continue;
+			goto skip;
 		seq_printf(p, "%3d: ", i);		
 #ifdef CONFIG_SMP
 		for (j = 0; j < NR_CPUS; j++)
@@ -373,8 +375,10 @@
 		seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge  ");
 		seq_printf(p, "    %s", action->name);
 		for (action = action->next; action; action = action->next)
-			seq_printf(p, ", %s", action->name);
+				seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 #ifdef CONFIG_TAU_INT
 	if (tau_initialized){
Index: linux-2.5.64/arch/ppc64/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/ppc64/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/ppc64/kernel/irq.c	5 Mar 2003 05:08:10 -0000	1.1.1.1
+++ linux-2.5.64/arch/ppc64/kernel/irq.c	7 Mar 2003 15:09:24 -0000
@@ -341,6 +341,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_printf(p, "           ");
 	for (j=0; j<NR_CPUS; j++) {
@@ -350,9 +351,10 @@
 	seq_putc(p, '\n');
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action || !action->handler)
-			continue;
+			goto skip;
 		seq_printf(p, "%3d: ", i);		
 #ifdef CONFIG_SMP
 		for (j = 0; j < NR_CPUS; j++) {
@@ -371,6 +373,8 @@
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
 	return 0;
Index: linux-2.5.64/arch/sh/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/sh/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/sh/kernel/irq.c	5 Mar 2003 05:08:16 -0000	1.1.1.1
+++ linux-2.5.64/arch/sh/kernel/irq.c	7 Mar 2003 15:02:47 -0000
@@ -90,6 +90,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_puts(p, "           ");
 	for (j=0; j<smp_num_cpus; j++)
@@ -97,9 +98,10 @@
 	seq_putc(p, '\n');
 
 	for (i = 0 ; i < ACTUAL_NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
-		if (!action) 
-			continue;
+		if (!action)
+			goto unlock;
 		seq_printf(p, "%3d: ",i);
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
@@ -108,6 +110,8 @@
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/sparc/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/sparc/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/sparc/kernel/irq.c	5 Mar 2003 05:08:05 -0000	1.1.1.1
+++ linux-2.5.64/arch/sparc/kernel/irq.c	7 Mar 2003 15:10:48 -0000
@@ -104,6 +104,7 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 #ifdef CONFIG_SMP
 	int j;
 #endif
@@ -114,9 +115,10 @@
 		return show_sun4d_interrupts(p, v);
 	}
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		local_irq_save(flags);
 	        action = *(i + irq_action);
 		if (!action) 
-		        continue;
+		        goto skip;
 		seq_printf(p, "%3d: ", i);
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
@@ -136,6 +138,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/v850/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/v850/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/v850/kernel/irq.c	5 Mar 2003 05:08:16 -0000	1.1.1.1
+++ linux-2.5.64/arch/v850/kernel/irq.c	7 Mar 2003 15:13:53 -0000
@@ -78,6 +78,7 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_puts(p, "           ");
 	for (i=0; i < 1 /*smp_num_cpus*/; i++)
@@ -87,10 +88,10 @@
 	for (i = 0 ; i < NR_IRQS ; i++) {
 		int j, count, num;
 		const char *type_name = irq_desc[i].handler->typename;
-
+		spin_lock_irqsave(&irq_desc[j].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto skip;
 
 		count = 0;
 		num = -1;
@@ -108,11 +109,13 @@
 			seq_printf(p, " %*s%d", 14 - prec, type_name, num);
 		} else
 			seq_printf(p, " %14s", type_name);
+		
 		seq_printf(p, "  %s", action->name);
-
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[j].lock, flags);
 	}
 	seq_printf(p, "ERR: %10lu\n", irq_err_count);
 	return 0;
Index: linux-2.5.64/arch/x86_64/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/x86_64/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/x86_64/kernel/irq.c	5 Mar 2003 05:08:16 -0000	1.1.1.1
+++ linux-2.5.64/arch/x86_64/kernel/irq.c	7 Mar 2003 15:14:44 -0000
@@ -135,6 +135,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_printf(p, "           ");
 	for (j=0; j<NR_CPUS; j++)
@@ -143,9 +144,10 @@
 	seq_putc(p, '\n');
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
@@ -156,11 +158,13 @@
 				kstat_cpu(j).irqs[i]);
 #endif
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
-		seq_printf(p, "  %s", action->name);
 
+		seq_printf(p, "  %s", action->name);
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	seq_printf(p, "NMI: ");
 	for (j = 0; j < NR_CPUS; j++)
-- 
function.linuxpower.ca

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] protect 'action' in show_interrupts
  2003-03-07 15:32           ` Zwane Mwaikambo
@ 2003-03-07 15:46             ` Russell King
  2003-03-07 16:25               ` Zwane Mwaikambo
  0 siblings, 1 reply; 20+ messages in thread
From: Russell King @ 2003-03-07 15:46 UTC (permalink / raw)
  To: Zwane Mwaikambo; +Cc: Andrew Morton, Linux Kernel

On Fri, Mar 07, 2003 at 10:32:13AM -0500, Zwane Mwaikambo wrote:
> --- linux-2.5.64/arch/arm/kernel/irq.c	5 Mar 2003 05:08:11 -0000	1.1.1.1
> +++ linux-2.5.64/arch/arm/kernel/irq.c	7 Mar 2003 15:05:36 -0000
> @@ -165,17 +165,22 @@
>  {
>  	int i;
>  	struct irqaction * action;
> +	unsigned long flags;
>  
>  	for (i = 0 ; i < NR_IRQS ; i++) {
> +		spin_lock_irqsave(&irq_desc[i].lock, flags);
>  	    	action = irq_desc[i].action;
>  		if (!action)
> -			continue;
> +			goto unlock;
> +
>  		seq_printf(p, "%3d: %10u ", i, kstat_irqs(i));
>  		seq_printf(p, "  %s", action->name);
> -		for (action = action->next; action; action = action->next) {
> +		for (action = action->next; action; action = action->next)
>  			seq_printf(p, ", %s", action->name);
> -		}
> +
>  		seq_putc(p, '\n');
> +unlock:
> +		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
>  	}
>  
>  #ifdef CONFIG_ARCH_ACORN

We don't have a per-irq_desc spinlock on ARM - it's a global
irq_controller_lock.

Thanks.

-- 
Russell King (rmk@arm.linux.org.uk)                The developer of ARM Linux
             http://www.arm.linux.org.uk/personal/aboutme.html


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] protect 'action' in show_interrupts
  2003-03-07 15:46             ` Russell King
@ 2003-03-07 16:25               ` Zwane Mwaikambo
  2003-03-07 22:01                 ` Andrew Morton
  0 siblings, 1 reply; 20+ messages in thread
From: Zwane Mwaikambo @ 2003-03-07 16:25 UTC (permalink / raw)
  To: Russell King; +Cc: Andrew Morton, Linux Kernel

On Fri, 7 Mar 2003, Russell King wrote:

> We don't have a per-irq_desc spinlock on ARM - it's a global
> irq_controller_lock.
> 
> Thanks.

Ok thanks for spotting that. Andrew here it is rediffed.

Index: linux-2.5.64/arch/alpha/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/alpha/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/alpha/kernel/irq.c	5 Mar 2003 05:08:08 -0000	1.1.1.1
+++ linux-2.5.64/arch/alpha/kernel/irq.c	7 Mar 2003 15:05:23 -0000
@@ -515,6 +515,7 @@
 #endif
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 #ifdef CONFIG_SMP
 	seq_puts(p, "           ");
@@ -525,9 +526,10 @@
 #endif
 
 	for (i = 0; i < ACTUAL_NR_IRQS; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto unlock;
 		seq_printf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
@@ -538,15 +540,18 @@
 #endif
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
 		seq_printf(p, "  %c%s",
-			     (action->flags & SA_INTERRUPT)?'+':' ',
-			     action->name);
+			(action->flags & SA_INTERRUPT)?'+':' ',
+			action->name);
 
 		for (action=action->next; action; action = action->next) {
 			seq_printf(p, ", %c%s",
-				     (action->flags & SA_INTERRUPT)?'+':' ',
-				     action->name);
+				  (action->flags & SA_INTERRUPT)?'+':' ',
+				   action->name);
 		}
+
 		seq_putc(p, '\n');
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 #if CONFIG_SMP
 	seq_puts(p, "IPI: ");
Index: linux-2.5.64/arch/arm/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/arm/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/arm/kernel/irq.c	5 Mar 2003 05:08:11 -0000	1.1.1.1
+++ linux-2.5.64/arch/arm/kernel/irq.c	7 Mar 2003 16:22:44 -0000
@@ -165,17 +165,22 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_controller_lock, flags);
 	    	action = irq_desc[i].action;
 		if (!action)
-			continue;
+			goto unlock;
+
 		seq_printf(p, "%3d: %10u ", i, kstat_irqs(i));
 		seq_printf(p, "  %s", action->name);
-		for (action = action->next; action; action = action->next) {
+		for (action = action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
-		}
+
 		seq_putc(p, '\n');
+unlock:
+		spin_unlock_irqrestore(&irq_controller_lock, flags);
 	}
 
 #ifdef CONFIG_ARCH_ACORN
Index: linux-2.5.64/arch/cris/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/cris/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/cris/kernel/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/cris/kernel/irq.c	7 Mar 2003 15:06:02 -0000
@@ -228,11 +228,13 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0; i < NR_IRQS; i++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %10u %c %s",
 			i, kstat_cpu(0).irqs[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -243,6 +245,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/i386/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/i386/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/i386/kernel/irq.c	5 Mar 2003 05:08:03 -0000	1.1.1.1
+++ linux-2.5.64/arch/i386/kernel/irq.c	7 Mar 2003 15:15:28 -0000
@@ -135,6 +135,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_printf(p, "           ");
 	for (j=0; j<NR_CPUS; j++)
@@ -143,9 +144,10 @@
 	seq_putc(p, '\n');
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
@@ -160,7 +162,10 @@
 
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
+
 		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	seq_printf(p, "NMI: ");
 	for (j = 0; j < NR_CPUS; j++)
Index: linux-2.5.64/arch/ia64/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/ia64/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/ia64/kernel/irq.c	5 Mar 2003 05:08:13 -0000	1.1.1.1
+++ linux-2.5.64/arch/ia64/kernel/irq.c	7 Mar 2003 15:07:18 -0000
@@ -154,6 +154,7 @@
 	int i, j;
 	struct irqaction * action;
 	irq_desc_t *idesc;
+	unsigned long flags;
 
 	seq_puts(p, "           ");
 	for (j=0; j<NR_CPUS; j++)
@@ -163,9 +164,10 @@
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
 		idesc = irq_desc(i);
+		spin_lock_irqsave(&idesc->lock, flags);
 		action = idesc->action;
 		if (!action)
-			continue;
+			goto skip;
 		seq_printf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
@@ -176,10 +178,12 @@
 #endif
 		seq_printf(p, " %14s", idesc->handler->typename);
 		seq_printf(p, "  %s", action->name);
-
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
+		
 		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&idesc->lock, flags);
 	}
 	seq_puts(p, "NMI: ");
 	for (j = 0; j < NR_CPUS; j++)
Index: linux-2.5.64/arch/mips/baget/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/baget/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/baget/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/baget/irq.c	7 Mar 2003 15:15:45 -0000
@@ -146,11 +146,13 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < BAGET_IRQ_NR ; i++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s",
 			i, kstat_cpu(0).irqs[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -161,6 +163,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips/dec/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/dec/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/dec/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/dec/irq.c	7 Mar 2003 15:26:50 -0000
@@ -97,11 +97,13 @@
 {
 	int i;
 	struct irqaction *action;
+	unsigned long flags;
 
 	for (i = 0; i < 32; i++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action)
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s",
 				i, kstat_cpu(0).irqs[i],
 				(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -112,6 +114,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips/ite-boards/generic/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/ite-boards/generic/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/ite-boards/generic/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/ite-boards/generic/irq.c	7 Mar 2003 15:16:41 -0000
@@ -222,6 +222,7 @@
 {
         int i, j;
         struct irqaction * action;
+	unsigned long flags;
 
         seq_printf(p, "           ");
         for (j=0; j<smp_num_cpus; j++)
@@ -229,20 +230,25 @@
 	seq_putc(p, '\n');
 
         for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
                 action = irq_desc[i].action;
+
                 if ( !action || !action->handler )
-                        continue;
+                        goto skip;
                 seq_printf(p, "%3d: ", i);		
                 seq_printf(p, "%10u ", kstat_irqs(i));
                 if ( irq_desc[i].handler )		
                         seq_printf(p, " %s ", irq_desc[i].handler->typename );
                 else
                         seq_puts(p, "  None      ");
+
                 seq_printf(p, "    %s",action->name);
                 for (action=action->next; action; action = action->next) {
                         seq_printf(p, ", %s", action->name);
                 }
                 seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
         }
         seq_printf(p, "BAD: %10lu\n", spurious_count);
         return 0;
Index: linux-2.5.64/arch/mips/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/kernel/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/kernel/irq.c	7 Mar 2003 15:16:59 -0000
@@ -73,17 +73,19 @@
 int show_interrupts(struct seq_file *p, void *v)
 {
 	struct irqaction * action;
+	unsigned long flags;
 	int i;
-
+	
 	seq_puts(p, "           ");
 	for (i=0; i < 1 /*smp_num_cpus*/; i++)
 		seq_printf(p, "CPU%d       ", i);
 	seq_putc(p, '\n');
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto unlock;
 		seq_printf(p, "%3d: ",i);
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
@@ -92,6 +94,8 @@
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	seq_printf(p, "ERR: %10lu\n", irq_err_count);
 	return 0;
Index: linux-2.5.64/arch/mips/kernel/old-irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/kernel/old-irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 old-irq.c
--- linux-2.5.64/arch/mips/kernel/old-irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/kernel/old-irq.c	7 Mar 2003 15:26:35 -0000
@@ -128,11 +128,13 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < 32 ; i++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s",
 			i, kstat_cpu(0).irqs[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -143,6 +145,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips/mips-boards/atlas/atlas_int.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/mips-boards/atlas/atlas_int.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 atlas_int.c
--- linux-2.5.64/arch/mips/mips-boards/atlas/atlas_int.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/mips-boards/atlas/atlas_int.c	7 Mar 2003 15:18:07 -0000
@@ -99,11 +99,13 @@
 	int i;
 	int num = 0;
 	struct irqaction *action;
+	unsigned long flags;
 
 	for (i = 0; i < ATLASINT_END; i++, num++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -114,6 +116,8 @@
 				action->name);
 		}
 		seq_printf(p, " [hw0]\n");
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips/philips/nino/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips/philips/nino/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/mips/philips/nino/irq.c	5 Mar 2003 05:08:09 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips/philips/nino/irq.c	7 Mar 2003 15:17:31 -0000
@@ -119,11 +119,13 @@
 {
     int i;
     struct irqaction *action;
+    unsigned long flags;
 
     for (i = 0; i < NR_IRQS; i++) {
+	local_irq_save(flags);
 	action = irq_action[i];
 	if (!action)
-	    continue;
+	    goto skip;
 	seq_printf(p, "%2d: %8d %c %s",
 		       i, kstat_cpu(0).irqs[i],
 		       (action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -134,6 +136,8 @@
 			   action->name);
 	}
 	seq_putc(p, '\n');
+skip:
+	local_irq_restore(flags);
     }
     return 0;
 }
Index: linux-2.5.64/arch/mips64/mips-boards/atlas/atlas_int.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips64/mips-boards/atlas/atlas_int.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 atlas_int.c
--- linux-2.5.64/arch/mips64/mips-boards/atlas/atlas_int.c	5 Mar 2003 05:08:15 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips64/mips-boards/atlas/atlas_int.c	7 Mar 2003 15:03:22 -0000
@@ -95,11 +95,13 @@
 	int i;
 	int num = 0;
 	struct irqaction *action;
+	unsigned long flags;
 
 	for (i = 0; i < ATLASINT_END; i++, num++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto unlock;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -110,6 +112,8 @@
 				action->name);
 		}
 		seq_puts(p, " [hw0]\n");
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips64/mips-boards/malta/malta_int.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips64/mips-boards/malta/malta_int.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 malta_int.c
--- linux-2.5.64/arch/mips64/mips-boards/malta/malta_int.c	5 Mar 2003 05:08:15 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips64/mips-boards/malta/malta_int.c	7 Mar 2003 15:23:14 -0000
@@ -125,11 +125,13 @@
 	int i;
 	int num = 0;
 	struct irqaction *action;
+	unsigned long flags;
 
 	for (i = 0; i < 8; i++, num++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action) 
-			continue;
+			goto skip_1;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -140,11 +142,14 @@
 				action->name);
 		}
 		seq_puts(p, " [on-chip]\n");
+skip_1:
+		local_irq_restore(flags);
 	}
 	for (i = 0; i < MALTAINT_END; i++, num++) {
+		local_irq_save(flags);
 		action = hw0_irq_action[i];
 		if (!action) 
-			continue;
+			goto skip_2;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -155,6 +160,8 @@
 				action->name);
 		}
 		seq_puts(p, " [hw0]\n");
+skip_2:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips64/sgi-ip22/ip22-int.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips64/sgi-ip22/ip22-int.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ip22-int.c
--- linux-2.5.64/arch/mips64/sgi-ip22/ip22-int.c	5 Mar 2003 05:08:15 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips64/sgi-ip22/ip22-int.c	7 Mar 2003 15:04:05 -0000
@@ -237,11 +237,13 @@
 	int i;
 	int num = 0;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < 16 ; i++, num++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action) 
-			continue;
+			goto skip_1;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -252,11 +254,14 @@
 				action->name);
 		}
 		seq_puts(p, " [on-chip]\n");
+skip_1:
+		local_irq_restore(flags);
 	}
 	for (i = 0 ; i < 24 ; i++, num++) {
+		local_irq_save(flags);
 		action = local_irq_action[i];
 		if (!action) 
-			continue;
+			goto skip_2;
 		seq_printf(p, "%2d: %8d %c %s",
 			num, kstat_cpu(0).irqs[num],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -267,6 +272,8 @@
 				action->name);
 		}
 		seq_puts(p, " [local]\n");
+skip_2:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/mips64/sgi-ip27/ip27-irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/mips64/sgi-ip27/ip27-irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ip27-irq.c
--- linux-2.5.64/arch/mips64/sgi-ip27/ip27-irq.c	5 Mar 2003 05:08:15 -0000	1.1.1.1
+++ linux-2.5.64/arch/mips64/sgi-ip27/ip27-irq.c	7 Mar 2003 15:04:20 -0000
@@ -141,11 +141,13 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		local_irq_save(flags);
 		action = irq_action[i];
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%2d: %8d %c %s", i, kstat_cpu(0).irqs[i],
 		               (action->flags & SA_INTERRUPT) ? '+' : ' ',
 		               action->name);
@@ -156,6 +158,8 @@
 			                action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/ppc/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/ppc/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/ppc/kernel/irq.c	5 Mar 2003 05:08:03 -0000	1.1.1.1
+++ linux-2.5.64/arch/ppc/kernel/irq.c	7 Mar 2003 15:08:19 -0000
@@ -346,6 +346,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_puts(p, "           ");
 	for (j=0; j<NR_CPUS; j++)
@@ -354,9 +355,10 @@
 	seq_putc(p, '\n');
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if ( !action || !action->handler )
-			continue;
+			goto skip;
 		seq_printf(p, "%3d: ", i);		
 #ifdef CONFIG_SMP
 		for (j = 0; j < NR_CPUS; j++)
@@ -373,8 +375,10 @@
 		seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge  ");
 		seq_printf(p, "    %s", action->name);
 		for (action = action->next; action; action = action->next)
-			seq_printf(p, ", %s", action->name);
+				seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 #ifdef CONFIG_TAU_INT
 	if (tau_initialized){
Index: linux-2.5.64/arch/ppc64/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/ppc64/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/ppc64/kernel/irq.c	5 Mar 2003 05:08:10 -0000	1.1.1.1
+++ linux-2.5.64/arch/ppc64/kernel/irq.c	7 Mar 2003 15:09:24 -0000
@@ -341,6 +341,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_printf(p, "           ");
 	for (j=0; j<NR_CPUS; j++) {
@@ -350,9 +351,10 @@
 	seq_putc(p, '\n');
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action || !action->handler)
-			continue;
+			goto skip;
 		seq_printf(p, "%3d: ", i);		
 #ifdef CONFIG_SMP
 		for (j = 0; j < NR_CPUS; j++) {
@@ -371,6 +373,8 @@
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts);
 	return 0;
Index: linux-2.5.64/arch/sh/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/sh/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/sh/kernel/irq.c	5 Mar 2003 05:08:16 -0000	1.1.1.1
+++ linux-2.5.64/arch/sh/kernel/irq.c	7 Mar 2003 15:02:47 -0000
@@ -90,6 +90,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_puts(p, "           ");
 	for (j=0; j<smp_num_cpus; j++)
@@ -97,9 +98,10 @@
 	seq_putc(p, '\n');
 
 	for (i = 0 ; i < ACTUAL_NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
-		if (!action) 
-			continue;
+		if (!action)
+			goto unlock;
 		seq_printf(p, "%3d: ",i);
 		seq_printf(p, "%10u ", kstat_irqs(i));
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
@@ -108,6 +110,8 @@
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+unlock:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/sparc/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/sparc/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/sparc/kernel/irq.c	5 Mar 2003 05:08:05 -0000	1.1.1.1
+++ linux-2.5.64/arch/sparc/kernel/irq.c	7 Mar 2003 15:10:48 -0000
@@ -104,6 +104,7 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 #ifdef CONFIG_SMP
 	int j;
 #endif
@@ -114,9 +115,10 @@
 		return show_sun4d_interrupts(p, v);
 	}
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		local_irq_save(flags);
 	        action = *(i + irq_action);
 		if (!action) 
-		        continue;
+		        goto skip;
 		seq_printf(p, "%3d: ", i);
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
@@ -136,6 +138,8 @@
 				action->name);
 		}
 		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
 	}
 	return 0;
 }
Index: linux-2.5.64/arch/v850/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/v850/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/v850/kernel/irq.c	5 Mar 2003 05:08:16 -0000	1.1.1.1
+++ linux-2.5.64/arch/v850/kernel/irq.c	7 Mar 2003 15:13:53 -0000
@@ -78,6 +78,7 @@
 {
 	int i;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_puts(p, "           ");
 	for (i=0; i < 1 /*smp_num_cpus*/; i++)
@@ -87,10 +88,10 @@
 	for (i = 0 ; i < NR_IRQS ; i++) {
 		int j, count, num;
 		const char *type_name = irq_desc[i].handler->typename;
-
+		spin_lock_irqsave(&irq_desc[j].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto skip;
 
 		count = 0;
 		num = -1;
@@ -108,11 +109,13 @@
 			seq_printf(p, " %*s%d", 14 - prec, type_name, num);
 		} else
 			seq_printf(p, " %14s", type_name);
+		
 		seq_printf(p, "  %s", action->name);
-
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[j].lock, flags);
 	}
 	seq_printf(p, "ERR: %10lu\n", irq_err_count);
 	return 0;
Index: linux-2.5.64/arch/x86_64/kernel/irq.c
===================================================================
RCS file: /build/cvsroot/linux-2.5.64/arch/x86_64/kernel/irq.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 irq.c
--- linux-2.5.64/arch/x86_64/kernel/irq.c	5 Mar 2003 05:08:16 -0000	1.1.1.1
+++ linux-2.5.64/arch/x86_64/kernel/irq.c	7 Mar 2003 15:14:44 -0000
@@ -135,6 +135,7 @@
 {
 	int i, j;
 	struct irqaction * action;
+	unsigned long flags;
 
 	seq_printf(p, "           ");
 	for (j=0; j<NR_CPUS; j++)
@@ -143,9 +144,10 @@
 	seq_putc(p, '\n');
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
+		spin_lock_irqsave(&irq_desc[i].lock, flags);
 		action = irq_desc[i].action;
 		if (!action) 
-			continue;
+			goto skip;
 		seq_printf(p, "%3d: ",i);
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
@@ -156,11 +158,13 @@
 				kstat_cpu(j).irqs[i]);
 #endif
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
-		seq_printf(p, "  %s", action->name);
 
+		seq_printf(p, "  %s", action->name);
 		for (action=action->next; action; action = action->next)
 			seq_printf(p, ", %s", action->name);
 		seq_putc(p, '\n');
+skip:
+		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
 	}
 	seq_printf(p, "NMI: ");
 	for (j = 0; j < NR_CPUS; j++)
-- 
function.linuxpower.ca

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Oops: 2.5.64 check_obj_poison for 'size-64'
       [not found]         ` <20030307010539.3c0a14a3.akpm@digeo.com>
  2003-03-07  9:53           ` Oops: 2.5.64 check_obj_poison for 'size-64' Zwane Mwaikambo
@ 2003-03-07 19:38           ` Manfred Spraul
  2003-03-07 21:57             ` Zwane Mwaikambo
  1 sibling, 1 reply; 20+ messages in thread
From: Manfred Spraul @ 2003-03-07 19:38 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Zwane Mwaikambo, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 792 bytes --]

Andrew Morton wrote:

>This is a bad, bad bug.  How are you triggering it?
>
>Manfred, would it be possible to add builtin_return_address(0) into each
>object, so we can find out who did the initial kmalloc (or kfree, even)?
>
>It'll probably require CONFIG_FRAME_POINTER.
>  
>
No, CONFIG_FRAME_POINTER is only needed for __builtin_return_address(x, 
x>0). _address(0) always works.

I've attached a patch that records the last kfree address and prints 
that if a poison check fails.

Zwane, could you try to reproduce the bug?

If this doesn't help, we must implement the brute force approach: Use 
one page for each object and unmap it with change_page_addr from the 
linear mapping. Solaris can do that to hunt such bugs.

patch against 2.5.64+use_after_free_check.patch.

--
    Manfred

[-- Attachment #2: patch-slab-caller --]
[-- Type: text/plain, Size: 7772 bytes --]

// $Header$
// Kernel Version:
//  VERSION = 2
//  PATCHLEVEL = 5
//  SUBLEVEL = 64
//  EXTRAVERSION =
--- 2.5/include/linux/slab.h	2003-02-10 20:27:29.000000000 +0100
+++ build-2.5/include/linux/slab.h	2003-03-07 20:08:54.000000000 +0100
@@ -37,6 +37,7 @@
 #define	SLAB_HWCACHE_ALIGN	0x00002000UL	/* align objs on a h/w cache lines */
 #define SLAB_CACHE_DMA		0x00004000UL	/* use GFP_DMA memory */
 #define SLAB_MUST_HWCACHE_ALIGN	0x00008000UL	/* force alignment */
+#define SLAB_STORE_USER		0x00010000UL	/* store the last owner for bug hunting */
 
 /* flags passed to a constructor func */
 #define	SLAB_CTOR_CONSTRUCTOR	0x001UL		/* if not set, then deconstructor */
--- 2.5/mm/slab.c	2003-03-07 20:30:51.000000000 +0100
+++ build-2.5/mm/slab.c	2003-03-07 20:33:17.000000000 +0100
@@ -114,7 +114,7 @@
 # define CREATE_MASK	(SLAB_DEBUG_INITIAL | SLAB_RED_ZONE | \
 			 SLAB_POISON | SLAB_HWCACHE_ALIGN | \
 			 SLAB_NO_REAP | SLAB_CACHE_DMA | \
-			 SLAB_MUST_HWCACHE_ALIGN)
+			 SLAB_MUST_HWCACHE_ALIGN | SLAB_STORE_USER)
 #else
 # define CREATE_MASK	(SLAB_HWCACHE_ALIGN | SLAB_NO_REAP | \
 			 SLAB_CACHE_DMA | SLAB_MUST_HWCACHE_ALIGN)
@@ -280,9 +280,7 @@
 #endif
 };
 
-/* internal c_flags */
-#define	CFLGS_OFF_SLAB	0x010000UL	/* slab management in own cache */
-
+#define CFLGS_OFF_SLAB		(0x80000000UL)
 #define	OFF_SLAB(x)	((x)->flags & CFLGS_OFF_SLAB)
 
 #define BATCHREFILL_LIMIT	16
@@ -764,6 +762,9 @@
 		addr += BYTES_PER_WORD;
 		size -= 2*BYTES_PER_WORD;
 	}
+	if (cachep->flags & SLAB_STORE_USER) {
+		size -= BYTES_PER_WORD;
+	}
 	memset(addr, val, size);
 	*(unsigned char *)(addr+size-1) = POISON_END;
 }
@@ -791,11 +792,21 @@
 		addr += BYTES_PER_WORD;
 		size -= 2*BYTES_PER_WORD;
 	}
+	if (cachep->flags & SLAB_STORE_USER) {
+		size -= BYTES_PER_WORD;
+	}
 	end = fprob(addr, size);
 	if (end) {
 		int s;
 		printk(KERN_ERR "Slab corruption: start=%p, expend=%p, "
 				"problemat=%p\n", addr, addr+size-1, end);
+		if (cachep->flags & SLAB_STORE_USER) {
+			if (cachep->flags & SLAB_RED_ZONE)
+				printk(KERN_ERR "Last user: [<%p>]\n", *(void**)(addr+size+BYTES_PER_WORD));
+			else
+				printk(KERN_ERR "Last user: [<%p>]\n", *(void**)(addr+size));
+
+		}
 		printk(KERN_ERR "Data: ");
 		for (s = 0; s < size; s++) {
 			if (((char*)addr)[s] == POISON_BEFORE)
@@ -831,16 +842,19 @@
 	int i;
 	for (i = 0; i < cachep->num; i++) {
 		void *objp = slabp->s_mem + cachep->objsize * i;
+		int objlen = cachep->objsize;
 
 		if (cachep->flags & SLAB_POISON)
 			check_poison_obj(cachep, objp);
+		if (cachep->flags & SLAB_STORE_USER)
+			objlen -= BYTES_PER_WORD;
 
 		if (cachep->flags & SLAB_RED_ZONE) {
 			if (*((unsigned long*)(objp)) != RED_INACTIVE)
 				slab_error(cachep, "start of a freed object "
 							"was overwritten");
-			if (*((unsigned long*)(objp + cachep->objsize -
-					BYTES_PER_WORD)) != RED_INACTIVE)
+			if (*((unsigned long*)(objp + objlen - BYTES_PER_WORD))
+				       	!= RED_INACTIVE)
 				slab_error(cachep, "end of a freed object "
 							"was overwritten");
 			objp += BYTES_PER_WORD;
@@ -929,7 +943,7 @@
 		 * do not red zone large object, causes severe
 		 * fragmentation.
 		 */
-		flags |= SLAB_RED_ZONE;
+		flags |= SLAB_RED_ZONE|SLAB_STORE_USER;
 	flags |= SLAB_POISON;
 #endif
 #endif
@@ -966,6 +980,10 @@
 		flags &= ~SLAB_HWCACHE_ALIGN;
 		size += 2*BYTES_PER_WORD;	/* words for redzone */
 	}
+	if (flags & SLAB_STORE_USER) {
+		flags &= ~SLAB_HWCACHE_ALIGN;
+		size += BYTES_PER_WORD;		/* word for kfree caller address */
+	}
 #endif
 	align = BYTES_PER_WORD;
 	if (flags & SLAB_HWCACHE_ALIGN)
@@ -1322,15 +1340,20 @@
 	for (i = 0; i < cachep->num; i++) {
 		void* objp = slabp->s_mem+cachep->objsize*i;
 #if DEBUG
+		int objlen = cachep->objsize;
 		/* need to poison the objs? */
 		if (cachep->flags & SLAB_POISON)
 			poison_obj(cachep, objp, POISON_BEFORE);
+		if (cachep->flags & SLAB_STORE_USER) {
+			objlen -= BYTES_PER_WORD;
+			((unsigned long*)(objp+objlen))[0] = 0;
+		}
 
 		if (cachep->flags & SLAB_RED_ZONE) {
 			*((unsigned long*)(objp)) = RED_INACTIVE;
-			*((unsigned long*)(objp + cachep->objsize -
-					BYTES_PER_WORD)) = RED_INACTIVE;
 			objp += BYTES_PER_WORD;
+			objlen -= 2* BYTES_PER_WORD;
+			*((unsigned long*)(objp + objlen)) = RED_INACTIVE;
 		}
 		/*
 		 * Constructors are not allowed to allocate memory from
@@ -1341,14 +1364,13 @@
 			cachep->ctor(objp, cachep, ctor_flags);
 
 		if (cachep->flags & SLAB_RED_ZONE) {
+			if (*((unsigned long*)(objp + objlen)) != RED_INACTIVE)
+				slab_error(cachep, "constructor overwrote the"
+							" end of an object");
 			objp -= BYTES_PER_WORD;
 			if (*((unsigned long*)(objp)) != RED_INACTIVE)
 				slab_error(cachep, "constructor overwrote the"
 							" start of an object");
-			if (*((unsigned long*)(objp + cachep->objsize -
-					BYTES_PER_WORD)) != RED_INACTIVE)
-				slab_error(cachep, "constructor overwrote the"
-							" end of an object");
 		}
 #else
 		if (cachep->ctor)
@@ -1490,11 +1512,12 @@
 #endif 
 }
 
-static inline void *cache_free_debugcheck (kmem_cache_t * cachep, void * objp)
+static inline void *cache_free_debugcheck (kmem_cache_t * cachep, void * objp, void *caller)
 {
 #if DEBUG
 	struct page *page;
 	unsigned int objnr;
+	int objlen = cachep->objsize;
 	struct slab *slabp;
 
 	kfree_debugcheck(objp);
@@ -1503,16 +1526,21 @@
 	BUG_ON(GET_PAGE_CACHE(page) != cachep);
 	slabp = GET_PAGE_SLAB(page);
 
+	if (cachep->flags & SLAB_STORE_USER) {
+		objlen -= BYTES_PER_WORD;
+	}
 	if (cachep->flags & SLAB_RED_ZONE) {
 		objp -= BYTES_PER_WORD;
 		if (xchg((unsigned long *)objp, RED_INACTIVE) != RED_ACTIVE)
 			slab_error(cachep, "double free, or memory before"
 						" object was overwritten");
-		if (xchg((unsigned long *)(objp+cachep->objsize -
-				BYTES_PER_WORD), RED_INACTIVE) != RED_ACTIVE)
+		if (xchg((unsigned long *)(objp+objlen-BYTES_PER_WORD), RED_INACTIVE) != RED_ACTIVE)
 			slab_error(cachep, "double free, or memory after "
 						" object was overwritten");
 	}
+	if (cachep->flags & SLAB_STORE_USER) {
+		*((void**)(objp+objlen)) = caller;
+	}
 
 	objnr = (objp-slabp->s_mem)/cachep->objsize;
 
@@ -1665,22 +1693,31 @@
 
 static inline void *
 cache_alloc_debugcheck_after(kmem_cache_t *cachep,
-			unsigned long flags, void *objp)
+			unsigned long flags, void *objp, void *caller)
 {
 #if DEBUG
+	int objlen = cachep->objsize;
+
 	if (!objp)	
 		return objp;
 	if (cachep->flags & SLAB_POISON)
 		check_poison_obj(cachep, objp);
+	if (cachep->flags & SLAB_STORE_USER) {
+		objlen -= BYTES_PER_WORD;
+		*((void **)(objp+objlen)) = caller;
+	}
+
 	if (cachep->flags & SLAB_RED_ZONE) {
 		/* Set alloc red-zone, and check old one. */
-		if (xchg((unsigned long *)objp, RED_ACTIVE) != RED_INACTIVE)
+		if (xchg((unsigned long *)objp, RED_ACTIVE) != RED_INACTIVE) {
 			slab_error(cachep, "memory before object was "
 						"overwritten");
-		if (xchg((unsigned long *)(objp+cachep->objsize -
-			  BYTES_PER_WORD), RED_ACTIVE) != RED_INACTIVE)
+		}
+		if (xchg((unsigned long *)(objp+objlen - BYTES_PER_WORD),
+				       	RED_ACTIVE) != RED_INACTIVE) {
 			slab_error(cachep, "memory after object was "
 						"overwritten");
+		}
 		objp += BYTES_PER_WORD;
 	}
 	if (cachep->ctor && cachep->flags & SLAB_POISON) {
@@ -1715,7 +1752,7 @@
 		objp = cache_alloc_refill(cachep, flags);
 	}
 	local_irq_restore(save_flags);
-	objp = cache_alloc_debugcheck_after(cachep, flags, objp);
+	objp = cache_alloc_debugcheck_after(cachep, flags, objp, __builtin_return_address(0));
 	return objp;
 }
 
@@ -1822,7 +1859,7 @@
 	struct array_cache *ac = ac_data(cachep);
 
 	check_irq_off();
-	objp = cache_free_debugcheck(cachep, objp);
+	objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
 
 	if (likely(ac->avail < ac->limit)) {
 		STATS_INC_FREEHIT(cachep);

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Oops: 2.5.64 check_obj_poison for 'size-64'
  2003-03-07 19:38           ` Manfred Spraul
@ 2003-03-07 21:57             ` Zwane Mwaikambo
  2003-03-08  2:11               ` Zwane Mwaikambo
  0 siblings, 1 reply; 20+ messages in thread
From: Zwane Mwaikambo @ 2003-03-07 21:57 UTC (permalink / raw)
  To: Manfred Spraul; +Cc: Andrew Morton, linux-kernel

On Fri, 7 Mar 2003, Manfred Spraul wrote:

> Andrew Morton wrote:
> 
> >This is a bad, bad bug.  How are you triggering it?
> >
> >Manfred, would it be possible to add builtin_return_address(0) into each
> >object, so we can find out who did the initial kmalloc (or kfree, even)?
> >
> >It'll probably require CONFIG_FRAME_POINTER.
> >  
> >
> No, CONFIG_FRAME_POINTER is only needed for __builtin_return_address(x, 
> x>0). _address(0) always works.
> 
> I've attached a patch that records the last kfree address and prints 
> that if a poison check fails.
> 
> Zwane, could you try to reproduce the bug?

I can almost always witness it given approx 30minutes of runtime, however 
i still don't know how to trigger it by on demand. I'll apply your patch 
and get back to you when it triggers next.

	Zwane
-- 
function.linuxpower.ca

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] protect 'action' in show_interrupts
  2003-03-07 16:25               ` Zwane Mwaikambo
@ 2003-03-07 22:01                 ` Andrew Morton
  0 siblings, 0 replies; 20+ messages in thread
From: Andrew Morton @ 2003-03-07 22:01 UTC (permalink / raw)
  To: Zwane Mwaikambo; +Cc: rmk, linux-kernel

Zwane Mwaikambo <zwane@linuxpower.ca> wrote:
>
> On Fri, 7 Mar 2003, Russell King wrote:
> 
> > We don't have a per-irq_desc spinlock on ARM - it's a global
> > irq_controller_lock.
> > 
> > Thanks.
> 
> Ok thanks for spotting that. Andrew here it is rediffed.

Thanks, Zwane.  Looks good.

I made some adjustments down in mips land - they weren't initialising the
irq_desc_t locks on startup.

That's pretty academic, but doing spin_lock_irqsave() is as good a way as any
of saying "preempt_disable()", and it keeps all the code looking the same.





^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Oops: 2.5.64 check_obj_poison for 'size-64'
  2003-03-07 21:57             ` Zwane Mwaikambo
@ 2003-03-08  2:11               ` Zwane Mwaikambo
  2003-03-08  2:24                 ` Andrew Morton
  0 siblings, 1 reply; 20+ messages in thread
From: Zwane Mwaikambo @ 2003-03-08  2:11 UTC (permalink / raw)
  To: Manfred Spraul; +Cc: Andrew Morton, linux-kernel

On Fri, 7 Mar 2003, Zwane Mwaikambo wrote:

> > >  
> > >
> > No, CONFIG_FRAME_POINTER is only needed for __builtin_return_address(x, 
> > x>0). _address(0) always works.
> > 
> > I've attached a patch that records the last kfree address and prints 
> > that if a poison check fails.
> > 
> > Zwane, could you try to reproduce the bug?
> 
> I can almost always witness it given approx 30minutes of runtime, however 
> i still don't know how to trigger it by on demand. I'll apply your patch 
> and get back to you when it triggers next.

Just triggered an oops, looks like debris from something else though. 
still no slab debug messages.

Unable to handle kernel NULL pointer dereference at virtual address 00000001
 printing eip:
c01da9a6
*pde = 245f2001
*pte = 00000000
Oops: 0002
CPU:    1
EIP:    0060:[<c01da9a6>]    Not tainted
EFLAGS: 00010246
EIP is at number+0x1b6/0x2c0
eax: 00000004   ebx: 00000000   ecx: 00000000   edx: 00000006
esi: 00000000   edi: 00000001   ebp: 00000003   esp: e390be24
ds: 007b   es: 007b   ss: 0068
Process sadc (pid: 1205, threadinfo=e390a000 task=e3d398e0)
Stack: 00000000 e390be38 00000006 c02ae560 2000002c 31323335 c0143333 
e59ff060 
       e59cfbfc 00000779 c0135fd6 e390be50 e390be50 c3a82a9c 00000001 00000000 
       e390a000 c0128640 00000000 c03b4444 c03b4444 00000001 c034fa08 ffffffdd 
Call Trace:
 [<c0143333>] cache_grow+0x2e3/0x360
 [<c0135fd6>] rcu_process_callbacks+0x1a6/0x1c0
 [<c0128640>] tasklet_action+0x80/0xd0
 [<c01dad52>] vsnprintf+0x2a2/0x430
 [<c01796a9>] seq_printf+0x29/0x50
 [<c010cc38>] show_interrupts+0x298/0x2f0
 [<c0179148>] seq_read+0x108/0x2c0
 [<c01593b8>] vfs_read+0xa8/0x160
 [<c01596aa>] sys_read+0x2a/0x40
 [<c010ad9b>] syscall_call+0x7/0xb

Code: c6 07 20 89 e8 47 4d 85 c0 7f ef 80 7c 24 12 00 74 0e 3b 7c 

-- 
function.linuxpower.ca

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Oops: 2.5.64 check_obj_poison for 'size-64'
  2003-03-08  2:11               ` Zwane Mwaikambo
@ 2003-03-08  2:24                 ` Andrew Morton
  2003-03-08  2:42                   ` Zwane Mwaikambo
  0 siblings, 1 reply; 20+ messages in thread
From: Andrew Morton @ 2003-03-08  2:24 UTC (permalink / raw)
  To: Zwane Mwaikambo; +Cc: manfred, linux-kernel

Zwane Mwaikambo <zwane@linuxpower.ca> wrote:
>
> Just triggered an oops, looks like debris from something else though. 
> still no slab debug messages.
> 
> Unable to handle kernel NULL pointer dereference at virtual address 00000001
>  printing eip:
> c01da9a6
> *pde = 245f2001
> *pte = 00000000
> Oops: 0002
> CPU:    1
> EIP:    0060:[<c01da9a6>]    Not tainted
> EFLAGS: 00010246
> EIP is at number+0x1b6/0x2c0
> eax: 00000004   ebx: 00000000   ecx: 00000000   edx: 00000006
> esi: 00000000   edi: 00000001   ebp: 00000003   esp: e390be24
> ds: 007b   es: 007b   ss: 0068
> Process sadc (pid: 1205, threadinfo=e390a000 task=e3d398e0)
> Stack: 00000000 e390be38 00000006 c02ae560 2000002c 31323335 c0143333 
> e59ff060 
>        e59cfbfc 00000779 c0135fd6 e390be50 e390be50 c3a82a9c 00000001 00000000 
>        e390a000 c0128640 00000000 c03b4444 c03b4444 00000001 c034fa08 ffffffdd 
> Call Trace:
>  [<c0143333>] cache_grow+0x2e3/0x360
>  [<c0135fd6>] rcu_process_callbacks+0x1a6/0x1c0
>  [<c0128640>] tasklet_action+0x80/0xd0
>  [<c01dad52>] vsnprintf+0x2a2/0x430
>  [<c01796a9>] seq_printf+0x29/0x50
>  [<c010cc38>] show_interrupts+0x298/0x2f0
>  [<c0179148>] seq_read+0x108/0x2c0
>  [<c01593b8>] vfs_read+0xa8/0x160
>  [<c01596aa>] sys_read+0x2a/0x40
>  [<c010ad9b>] syscall_call+0x7/0xb
> 

Looks to me like you overran the page for seq_printf, which then returned -1
which then triggered what appears to be some utterly bogus code in
show_interrupts():

        for (j = 0; j < NR_CPUS; j++)
                if (cpu_online(j))
                        p += seq_printf(p, "%10u ", irq_stat[j].apic_timer_irqs);

Why is it modifying `p' there?  That's the pointer to the seq_file which
we're using.

Kill.  Two instances.



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Oops: 2.5.64 check_obj_poison for 'size-64'
  2003-03-08  2:24                 ` Andrew Morton
@ 2003-03-08  2:42                   ` Zwane Mwaikambo
  0 siblings, 0 replies; 20+ messages in thread
From: Zwane Mwaikambo @ 2003-03-08  2:42 UTC (permalink / raw)
  To: Andrew Morton; +Cc: manfred, linux-kernel

On Fri, 7 Mar 2003, Andrew Morton wrote:

> Looks to me like you overran the page for seq_printf, which then returned -1
> which then triggered what appears to be some utterly bogus code in
> show_interrupts():
> 
>         for (j = 0; j < NR_CPUS; j++)
>                 if (cpu_online(j))
>                         p += seq_printf(p, "%10u ", irq_stat[j].apic_timer_irqs);
> 
> Why is it modifying `p' there?  That's the pointer to the seq_file which
> we're using.

Probably leftovers from the previous interface.

> Kill.  Two instances.

Ok i'm just testing the seq_file buffer increase.

Thanks,
	Zwane
-- 
function.linuxpower.ca

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2003-03-08  2:34 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-03-07  5:13 Oops: 2.5.64 check_obj_poison for 'size-64' Zwane Mwaikambo
2003-03-07  6:23 ` Andrew Morton
2003-03-07  7:22   ` Zwane Mwaikambo
2003-03-07  7:35     ` Andrew Morton
2003-03-07  7:40       ` Zwane Mwaikambo
2003-03-07  7:45       ` Miles Bader
2003-03-07  7:58         ` Andrew Morton
2003-03-07  8:10           ` Miles Bader
2003-03-07 10:05       ` [PATCH] protect 'action' in show_interrupts Zwane Mwaikambo
2003-03-07 10:28         ` Andrew Morton
2003-03-07 15:32           ` Zwane Mwaikambo
2003-03-07 15:46             ` Russell King
2003-03-07 16:25               ` Zwane Mwaikambo
2003-03-07 22:01                 ` Andrew Morton
     [not found]       ` <Pine.LNX.4.50.0303070351060.18716-100000@montezuma.mastecende.com>
     [not found]         ` <20030307010539.3c0a14a3.akpm@digeo.com>
2003-03-07  9:53           ` Oops: 2.5.64 check_obj_poison for 'size-64' Zwane Mwaikambo
2003-03-07 19:38           ` Manfred Spraul
2003-03-07 21:57             ` Zwane Mwaikambo
2003-03-08  2:11               ` Zwane Mwaikambo
2003-03-08  2:24                 ` Andrew Morton
2003-03-08  2:42                   ` Zwane Mwaikambo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).