Hi,

On 08/12/07 05:14, Oliver Yang wrote:
> Hi Gavin,
> 
> It seems the cpu->cpu_intr_stack is only used for high level interrupt 
> right?

Yes, one stack used for all high level interrupts on that cpu instance.

> For low level interrupt, we use interrupt thread's stack instead of  
> cpu->cpu_intr_stack.

Yes, for each low-level interrupt we use the stack of a per-level
interrupt thread.

> The assembler code you showed below is about the context switch for 
> loading a new low level interrupt thread, 

Yes, although technically this is not a context switch here - we're already
running in kernel context and now it is just about deciding which stack
etc we'd like to use.

> and the T_STACK must refer to 
> the stack pointer register for SPARC CPU right?

No.  T_STACK is a preprocessor symbol, automatically generated to be the
offset of the t_stack member in the kthread_t structure.  See input file
usr/src/uts/sun4/ml/offsets.in (which applies for sun4* architectures) -
this is parsed during build by genasym to generate header files for
a bunch of offset defines including T_STACK.  The sparc stack pointer
register is %sp (an alias for %o6).

> Sorry, I'm not familiar with SPARC platform. I just want to make sure my 
> understanding is right. Thanks.

No problem, I'm happy to answer al the questions I can.  I no longer do
much sparc work but I used to know this area of the code well.

Gavin

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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 3249 bytes
Desc: S/MIME Cryptographic Signature
URL: 
<http://mail.opensolaris.org/pipermail/mdb-discuss/attachments/20070820/4189eba7/attachment.bin>

Reply via email to