lkml.org 
[lkml]   [1998]   [Mar]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
SubjectLINUX task switching on i386
Date
Hello once again to all LINUX kings ! (especially Jean Wolter who helped me
last time !),


As my studies of the LINUX kernel continue, I have found one last obstacle
in the way of my understanding. This is the real life implementation of
hardware task switching (i.e. using TSS's) in the LINUX OS / i386.


Regarding TSS's, when a new task is JUMPed to (via its TSS descriptor), then
the old task TSS should be chained (by the hardware), through its link
field, to other descheduled tasks (and have their NT flag set), this is
according to the text description of the TSS task linking section of the 386
manual (section 7.6). If you look at table 7-2, it says that the link field
is only used when a task switch is caused by a CALL or INTERRUPTS**, which
one is true ? I assume it is the chart which is correct because if you link
switched tasks (after the JMP tss in switch_to() called by schedule() )
their busy bit remains set and you cant re-enter them when switch_to() is
called again for the new task -> cause a GPE quickly. The only way to
unchain would be via iret which i dont think user processes will do
voluntarily and this would not be good scheduling ! :)


**just checking here: LINUX doesnt use a new task for interrupts, it just
executes in the kernel segment using the current tasks context - is this
correct ? - if it is true, then task linking never occurs in LINUX which
answers some of
my problems !


Leading on from this to a more LINUX specific issue, I will present what I
think happens when a timer interrupt occurs and would appreciate any
corrections that anyone can make:


Say a timer interrupt occurs while a user process is executing in user mode,
the timer interrupt handler is invoked (looking at build_timer_irq in
irq.h), this invokes do_timer still at interrupt level (this is slightly
different to other slow interrupts which re-enable OTHER types of interrupt
before doing do_irq) i.e. no more timer interrupts allowed, which sets up
its bottom half and exits. All interrupts are still disabled while
build_timer_irq calls ret_from_sys_call. At this point if we interrupted
another interrupt (intr_count!=0) we just iret otherwise the presence of
activated bottom halves is detected and interrupts are re-enabled before
calling handle_bottom_half, this invokes timer_bh (but only if another timer
bottom half hasn't been interrupted (a check in do_bottom_half) - is this
correct ? or is there something else preventing bottom halves from being
re-entered) which is responsible for setting need_resched if quanta have
expired etc. When the bottom half exits back to ret_from_sys_call, we check
to see if we interrupted someone in a system call (iret straight away) else
(interrupted someone in user space) we call schedule() if need_resched is
set which performs the magic JMP tss to switch to a new task. When this task
is re-invoked the last part of schedule() executes and returns us to
ret_from_sys_call which calls RESTORE_ALL which performs the iret to return
from the original timer interrupt to the user process


Somewhere I am getting mixed up with exactly how bottom halves work, how do
they avoid being re-entered (is it like i think ?), can you have more than
one type of bottom half on the active list e.g. 2 timer bottom halves, and
how does
LINUX ensure that only one bottom half is being executed at a time (in the
presence of other interrupts which call ret_from_sys_call and
do_bottom_half - it must be to do with intr_count but I dont see where the
bottom half code sets intr_count)...


Cheers for any help offered,


Mike



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu

\
 
 \ /
  Last update: 2005-03-22 13:41    [W:0.024 / U:1.056 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site