Re: Possible kernel stack overflow due to fast interrupts

2010-10-15 Thread Rick Tao
You are exactly right! Ensuring interrupts would not cause more preemptions. 
Thanks for pointing it out.
Rick

--- On Thu, 10/14/10, Benjamin Herrenschmidt b...@kernel.crashing.org wrote:

 From: Benjamin Herrenschmidt b...@kernel.crashing.org
 Subject: Re: Possible kernel stack overflow due to fast interrupts
 To: Rick Tao tao_r...@yahoo.com
 Cc: linuxppc-dev@lists.ozlabs.org
 Date: Thursday, October 14, 2010, 4:57 PM
 On Thu, 2010-10-14 at 13:45 -0700,
 Rick Tao wrote:
  Hi, all,
 
  .../...
 
  In the context of task A
  a. NIP would point to the instruction after
 switch_to(). 
  b. MSR_EE is enabled in the call trace
 (finish_task_switch
 --finish_lock_switch--spin_unlock_irq)
  c. do something that would trigger an interrupt later
 on (such as timer)
  d. call schedule() for context switch to task B.
     In this step, 
       task B's stack is popped
 INT_FRAME_SIZE size for context restore.  
     Note that task B's ksp = X -
 INT_FRAME_SIZE
  
  In the context of task B again
  a1. similar to step a above
 
  b1. similar to step b above 
  c1. interrupt occurs, go to step 1 above, and
 repeat!!!
  
  As you can see, task B's kernel stack space is reduced
 by INT_FRAME_SIZE
  on each loop. It will eventually overflow.
 
 So if I follow you correctly, you are worried that by the
 time execution
 resumes in B, and before it pops the second frame off, it
 might get
 another interrupt and re-preempt...
 
 Now unless I missed something, that cannot happen because
 preempt_schedule_irq() does increment the preempt count:
 
     add_preempt_count(PREEMPT_ACTIVE);
     local_irq_enable();
     schedule();
     local_irq_disable();
     sub_preempt_count(PREEMPT_ACTIVE);
 
 Which means that it won't preempt again in
 finish_task_switch, and so
 will eventually come back, turn EE back off, and pop off
 the stack
 frame.
 
 Or am I missing something ?
 
 Cheers,
 Ben.
 
 
 ___
 Linuxppc-dev mailing list
 Linuxppc-dev@lists.ozlabs.org
 https://lists.ozlabs.org/listinfo/linuxppc-dev
 


  
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Possible kernel stack overflow due to fast interrupts

2010-10-14 Thread Rick Tao
Hi, all,

I am looking at the kernel source of 2.6.32. It appears to me that kernel stack 
can be easily getting overflowed in case of fast interrupts. Here is my 
observation, any comments? Thanks,

Let's assume task A triggers the fast interrupts, and task B was running when 
the fast interrupt occur. 

In the context of task B (according to entry_32.S)
0. Assume task B's ksp = X
1. the interrupt causes exception, allocate exception frame space from
   the task B'stack (ksp = X - INT_FRAME_SIZE).
2. interrupt handler is invoked
3. ret_from_except, and resume_kernel is invoked
4. then preempt_schedule_irq is called, which in trun, __schedule() and 
   context_switch is called. Assume it switches to task A. 
   In this step,
 task B's stack is pushed another INT_FRAME_SIZE to save its context,
 so task B's ksp = X - 2 * INT_FRAME_SIZE now.

In the context of task A
a. NIP would point to the instruction after switch_to(). 
b. MSR_EE is enabled in the call trace (finish_task_switch 
--finish_lock_switch--spin_unlock_irq)
c. do something that would trigger an interrupt later on (such as timer)
d. call schedule() for context switch to task B.
   In this step, 
 task B's stack is popped INT_FRAME_SIZE size for context restore.  
   Note that task B's ksp = X - INT_FRAME_SIZE

In the context of task B again
a1. similar to step a above
b1. similar to step b above 
c1. interrupt occurs, go to step 1 above, and repeat!!!

As you can see, task B's kernel stack space is reduced by INT_FRAME_SIZE
on each loop. It will eventually overflow.

Thanks for your input.

Rick





  
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: Possible kernel stack overflow due to fast interrupts

2010-10-14 Thread Benjamin Herrenschmidt
On Thu, 2010-10-14 at 13:45 -0700, Rick Tao wrote:
 Hi, all,

 .../...

 In the context of task A
 a. NIP would point to the instruction after switch_to(). 
 b. MSR_EE is enabled in the call trace (finish_task_switch 
 --finish_lock_switch--spin_unlock_irq)
 c. do something that would trigger an interrupt later on (such as timer)
 d. call schedule() for context switch to task B.
In this step, 
  task B's stack is popped INT_FRAME_SIZE size for context restore.  
Note that task B's ksp = X - INT_FRAME_SIZE
 
 In the context of task B again
 a1. similar to step a above

 b1. similar to step b above 
 c1. interrupt occurs, go to step 1 above, and repeat!!!
 
 As you can see, task B's kernel stack space is reduced by INT_FRAME_SIZE
 on each loop. It will eventually overflow.

So if I follow you correctly, you are worried that by the time execution
resumes in B, and before it pops the second frame off, it might get
another interrupt and re-preempt...

Now unless I missed something, that cannot happen because
preempt_schedule_irq() does increment the preempt count:

add_preempt_count(PREEMPT_ACTIVE);
local_irq_enable();
schedule();
local_irq_disable();
sub_preempt_count(PREEMPT_ACTIVE);

Which means that it won't preempt again in finish_task_switch, and so
will eventually come back, turn EE back off, and pop off the stack
frame.

Or am I missing something ?

Cheers,
Ben.


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev