Hi Gavin, It seems the cpu->cpu_intr_stack is only used for high level interrupt right?
For low level interrupt, we use interrupt thread's stack instead of cpu->cpu_intr_stack. The assembler code you showed below is about the context switch for loading a new low level interrupt thread, and the T_STACK must refer to the stack pointer register for SPARC CPU right? Sorry, I'm not familiar with SPARC platform. I just want to make sure my understanding is right. Thanks. Gavin Maltby wrote: > On 07/31/07 13:39, Frank Hofmann wrote: > >> Running the interrupt handler on the stack of whatever kernel thread >> was active at that point gains performance - no cycles wasted on >> switching stacks, no TLB miss for the new stackpage. That's also why >> high-level interrupts never passivate. > > For low PIL interrupts we *do* switch stacks in intr_thread: > > ! > ! Push interrupted thread onto list from new thread. > ! Set the new thread as the current one. > ! Set interrupted thread's T_SP because if it is the idle thread, > ! resume may use that stack between threads. > ! > stn %o7, [THREAD_REG + T_PC] ! mark pc for resume > stn %sp, [THREAD_REG + T_SP] ! mark stack for resume > stn THREAD_REG, [%o3 + T_INTR] ! push old thread > stn %o3, [%o2 + CPU_THREAD] ! set new thread > mov %o3, THREAD_REG ! set global curthread > register > ldn [%o3 + T_STACK], %o4 ! interrupt stack pointer > sub %o4, STACK_BIAS, %sp > > For each cpu and PIL 1 to 10 (or maybe 9 - 10 is for the clock and > might be a special case) we create a dedicated interrupt thread > with associated stack. In intr_thread above we switch to using > the stack of the corresponding interrupt thread, and update > CPU->cpu_thread to point to the interrupt thread (the latter necessary > not just for accounting but for determining things like if a mutex > owner is on cpu). What we don't do, unless we passivate, is to > preempt the thread we have "pinned" - we leave it momentarily > in a pinned state, meaning it is the dispatched thread for that > cpu (CPU->cpu_disp_thread) but not the on-proc thread (CPU->cpu_thread). > If the interrupt thread passivates or if we appear to be pinning the > innocent victim thread for an extended period (*) then the interrupt > thread becomes a fully schedulable thread like any other - goes onto > a sleep queue somewhere, wakes up onto a dispatch queue etc. > > (*) This is possible because more than one interrupt may be serviced > during > a single actual level interrupt (aka PIL interrupt). Level interrupts > are queued on per-PIL queues for a processor, and there may be more than > one queued at the time the level interrupt is taken. Furthermore, > additional interrupts for the current level may be queued even as > we service those already queued - that's because they are mostly > queued from vec_interrupt at traplevel 1 which is a higher-priority > trap and so can be taken even while we're in a level interrupt trap. > > High level interrupts do not have an associated thread of their own - > no pool of dedicated per-PIL interrupt threads. There *is*, however, > a dedicated high-PIL interrupt stack to which we switch in > current_thread processing (we need this to guard against > stack overflow). Since the high level interrupts do not have > a thread of their own they do not change CPU->cpu_thread > and they cannot block because there is no thread object to > throw onto sleep queues, schedule on wakeup etc. Since high PIL > interrupts "squat" on the thread structure of the innocent > victim they have interrupted they must not change or make > any assumptions about the kthread_t pointed to by cpu_thread. > > Cheers > > Gavin > ------------------------------------------------------------------------ > > _______________________________________________ > mdb-discuss mailing list > mdb-discuss at opensolaris.org > -- Cheers, ---------------------------------------------------------- Oliver Yang | Work from home | http://blog.csdn.net/yayong