Kernel Programming Task Management ( 월 ) 이 병 희
Contents Introduction Task state transition Task structure Scheduling
Introduction What is the task ? Running or runable program Execution environment of a program Scheduling entity task management of kernel task 의 생성 / 소멸 / 상태전이 / 문맥교환 등을 관리 task management 를 위해 task 가 사용하는 자원에 대한 정보 유지 (task_struct 사용 ) Creation of task Use fork() function fork : 자신의 프로세스와 똑같은 프로세스를 copy-on-write 형식으로 실행, 이때 생성된 프로세는 자신만의 PID 를 가짐 exec : 역시 fork 와 마찬가지로 새로운 프로세스를 생성, 하지만 fork 와 같이 copy-on-write 를 이용한 전혀 새로운 프로세스를 실행시키지 않고, 현재의 프로세스이미지를 새로운 프로세스 이미지가 덮어씀
Task state transition initial fork ready fork running dispatch timeout waiting zombie wakeup exit sleep wait ready state : 생성된 task 가 준비상태가 되어 ready_queue 에 연결됨 스케줄러는 자신의 스케줄링 정책에 따라 task 를 선택하여 running state 로 바꿈 zombie state : 자신의 모든 자원을 커널에 반납 task 의 exit status 상태와 PID 는 여전히 남아서 task_struct 에 유지 waiting state : sleep system call 이 불리거나 lock 이 걸려있는 자원을 기다릴 경우 waiting 상태로 전이. waiting state 로 전이되는 경우 sleep_queue 에 연결
Task state transition user program execution user level running return from system call Interrupt routine system call Interrupt Scheduler readywaiting Kernel level running kernel level running 상태로의 전이 : system call 과 interrupt running state
Task structure Task 가 생성된 후 kernel 은 task 의 정보관리를 위해 여러 자료구조들 (context) 을 할당 Context 는 3 부분으로 구분가능 system context memory context hardware context sp eip … eflags file structure inode fd task_structsegment table page table thread structure (TSS) swap or a.out disk system context hardware context memory context
Task structure task_struct Include/linux/sched.h 에 정의 각 task 마다 하나씩 존재 task identification state task relationship scheduling information signal information memory information file information thread structure time information resource limits miscellaneous
Task structure state
Task structure task relationship new processes are copied from previous process task structure keeps pointers to its parent process and it siblings all processes in the system are held in a doubly linked list prev_task init_task prev_task next_task prev_task next_task task next_task.... prev_task next_task task prev_run next_run run_queue prev_run next_run youngest child parent childoldest child task_struct p_ctpr p_pptr p_ysptr p_osptr p_ysptr [ Task family relationship]
Task structure task relationship
Task structure signal information task 에게 비동기적인 사건의 발생을 알리는 매커니즘 signal 처리를 위한 3 가지 기능 다른 task 에게 signal 을 보낼 수 있어야 함 (sys_kill() system call) signal 을 수신할 수 있어야 함 (sigpending, signal, blocked) signal 이 오면 이를 처리할 수 있는 함수를 호출 (sys_signal(), sig)
Task structure count action[_NSIG] siglock sa_handler sa_flags sa_restorer sa_mask sys_signal(sig, handler) /* kernel/signal.c */ do_sigaction(sig, new_sa, old_sa) …. sig signal,blocked sigpending …. task_struct …. signal_struct sigaction sigset_t 63 0 …. sigset_t 63 0 sys_kill(pid,sig) /* kernel/signal.c */ kill_proc_info(sig, info, pid) send_sig_info(sig, info, *t) sigaddset(t->signal, sig); t->sigpending = 1;
Task structure thread information task 가 실행되다 중지할 때 현재 어디까지 실행하였는지 저장 처리기의 레지스터들의 내용을 저장 include/asm-i386/processor.h unsigned long esp0; unsigned short ss0; unsigned long esp1; unsigned short ss1; unsigned long esp2; unsigned short ss2; unsigned long cr3; unsigned long eip, eflags; unsigned long eax, ecx, edx, ebx; unsigned long esp; unsigned long ebp, esi, edi; unsigned short es, cs, ss, ds, fs, gs; unsigned short ldt; ……..... tss... task_struct
Task structure time information kernel keeps track of time information start_time : task creation time struct tms times : task start time at user and kernel level resource limits indicates limitation of resource task_struct … rlim[] … /*include/linux/resource.h */
Scheduling Linux scheduling clock interrupt 는 10msec 마다 발생 real-time task 지원 task_struct 스케줄링 관련 변수 (/*include/linux/sched.h */) policy 태스크 유형 (task type) SCHED_FIFO :real-time task, non-preemptive SCHED_RR : real-time task, preemptive SCHED_OTHER : normal task, preemptive priority 태스크 우선순위 태스크가 생성될 때 기본 값인 20 (DEF_PRIORITY) 으로 설정 sys_nice() 나 sys_setpriority() 시스템 호출로 변경 가능
Scheduling counter 태스크의 처리기 사용량 태스크가 생성될 때 priority 값으로 설정 태스크가 수행중일 때, clock interrupt 이 발생하면 1 씩 감소 모든 태스크의 counter 값이 0 이 되면, 모든 태스크의 counter 값을 priority 값으로 재 설정 normal task 의 경우, 스케줄러는 priority + counter 값이 가장 큰 태스크를 선택하여 수행 need_resched 스케줄링이 수행될 필요가 있으면 1 로 설정 커널 수준 실행 상태에서 사용자 수준 실행 상태로 전이될 때 ( 시스템 호출이나 인터럽트 처리를 마칠 때 ), 이 변수를 조사하여 1 이면 스케줄러 호출 rt_priority 실시간 태스크의 우선 순위, 보통 1000 이상 sched_setscheduler(pid, policy, sched_param) 시스템 호출로 설정 실시간 태스크의 경우, 스케줄러는 이 값이 가장 큰 태스크를 선택하여 수행
Scheduling 스케줄링 함수 : schedule() function /* kernel/sched.c */ schedule() need_resched sleep_on - schedule real time task first (rt_priority) - select a task which has highest values of counter + priority (using goodness function) give advantage to the task which run this_cpu give slight advantage to the task which has mm object - if (counter == 0) for all task counter = priority - context switch : switch_to (current, next) /* arch/i386/kernel/process.c */
Scheduling Example of linux scheduling 3 normal tasks 단일 처리기 시스템 clock interrupt 는 10ms 마다 한 번씩 발생 T1 priority counter millisecond T2 priority counter T3 priority counter