Linux 커 널 분석의 8 - 프로 세 스 스케줄 링 과 프로 세 스 전환 과정
6477 단어 Linux 시스템 기반
오리지널 작품 전재 출처 를 밝 혀 주 십시오.
MOOC 과정http://mooc.study.163.com/course/USTC-1000029000
1. 프로 세 스 스케줄 링 의 시기
Linux 시스템 에서 프로 세 스 스케줄 링 은 보통 중단 처리 과정 에서 발생 합 니 다 (시계 중단, I / O 중단, 시스템 호출 과 이상 포함). schedule () 시스템 호출 을 직접 호출 하거나 사용자 상태 로 돌아 갈 때 needresched 태그 호출 schedule ().프로 세 스 스케줄 링 은 주동 적 으로 스케줄 링 할 수도 있 고 수 동적 으로 스케줄 링 할 수도 있다.
커 널 스 레 드 (특수 한 프로 세 스, 사용자 상태 없 음) 는 schedule () 를 직접 호출 하여 프로 세 스 전환 을 할 수 있 고 중단 처리 과정 에서 스케줄 링 을 할 수 있 습 니 다. 즉, 커 널 스 레 드 는 특수 한 프로 세 스 로 서 주동 적 으로 스케줄 링 을 할 수도 있 고 수 동적 으로 스케줄 링 을 할 수도 있 습 니 다.사용자 상태 프로 세 스 는 주동 적 인 스케줄 링 을 실현 할 수 없습니다. 커 널 상태 에 빠 진 후의 특정한 시점 을 통 해 스케줄 링 을 할 수 있 습 니 다. 즉, 중단 처리 과정 에서 스케줄 링 을 할 수 있 습 니 다.schedule () 호출 은 다음 과 같 습 니 다.
asmlinkage __visible void __sched schedule(void)
2866{
2867 struct task_struct *tsk = current;
2868
2869 sched_submit_work(tsk);
2870 __schedule();
2871}
그 중schedule () 함수 호출 은 프로 세 스 스케줄 링 의 상세 한 작업 을 수행 합 니 다.next = pick_next_task(rq, prev);
프로 세 스 를 선택 하여 스케줄 링 합 니 다. 프로 세 스 를 선택 한 스케줄 링 알고리즘 의 실현 은 모두 pick 에 있 습 니 다.next_task 에서 알고리즘 은 여기 서 중요 하지 않 습 니 다. 어떤 알고리즘 이 든 그 역할 은 프로 세 스 를 선택 하여 전환 하 는 것 입 니 다.프로 세 스 를 선택 한 후 프로 세 스 전환 을 진행 합 니 다.2. 프로 세 스 전환
재schedule () 함수 에서 전환 을 준비 하 는 프로 세 스 를 선택 한 후 context 를 호출 합 니 다.switch () 프로 세 스 컨 텍스트 전환 을 진행 합 니 다.그 실현 은 다음 과 같다.
static inline void
2336context_switch(struct rq *rq, struct task_struct *prev,
2337 struct task_struct *next)
2338{
2339 struct mm_struct *mm, *oldmm;
2340
2341 prepare_task_switch(rq, prev, next);
2342
2343 mm = next->mm;
2344 oldmm = prev->active_mm;
2345 /*
2346 * For paravirt, this is coupled with an exit in switch_to to
2347 * combine the page table reload and the switch backend into
2348 * one hypercall.
2349 */
2350 arch_start_context_switch(prev);
2351
2352 if (!mm) {
2353 next->active_mm = oldmm;
2354 atomic_inc(&oldmm->mm_count);
2355 enter_lazy_tlb(oldmm, next);
2356 } else
2357 switch_mm(oldmm, mm, next);
2358
2359 if (!prev->mm) {
2360 prev->active_mm = NULL;
2361 rq->prev_mm = oldmm;
2362 }
2363 /*
2364 * Since the runqueue lock will be released by the next
2365 * task (which is an invalid locking op but in the case
2366 * of the scheduler it's an obvious special-case), so we
2367 * do an early lockdep release here:
2368 */
2369 spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
2370
2371 context_tracking_task_switch(prev, next);
2372 /* Here we just switch the register state and the stack. */
2373 switch_to(prev, next, prev);
2374
2375 barrier();
2376 /*
2377 * this_rq must be evaluated again because prev may have moved
2378 * CPUs since it called schedule(), thus the 'rq' on its stack
2379 * frame will be invalid.
2380 */
2381 finish_task_switch(this_rq(), prev);
2382}
pre 인 자 는 현재 전환 할 프로 세 스 입 니 다. next 인 자 는 전환 할 프로 세 스 를 선택 한 것 입 니 다. 이 함수 에서 switch 를 호출 했 습 니 다.to () 함수 스 택 교체:#define switch_to(prev, next, last) \
32do { \
33 /* \
34 * Context-switching clobbers all registers, so we clobber \
35 * them explicitly, via unused output variables. \
36 * (EAX and EBP is not listed because EBP is saved/restored \
37 * explicitly for wchan access and EAX is the return value of \
38 * __switch_to()) \
39 */ \
40 unsigned long ebx, ecx, edx, esi, edi; \
41 \
42 asm volatile("pushfl
\t" /* save flags */ \
43 "pushl %%ebp
\t" /* save EBP */ \
44 "movl %%esp,%[prev_sp]
\t" /* save ESP */ \
45 "movl %[next_sp],%%esp
\t" /* restore ESP */ \
46 "movl $1f,%[prev_ip]
\t" /* save EIP */ \
47 "pushl %[next_ip]
\t" /* restore EIP */ \
48 __switch_canary \
49 "jmp __switch_to
" /* regparm call */ \
50 "1:\t" \
51 "popl %%ebp
\t" /* restore EBP */ \
52 "popfl
" /* restore flags */ \
53 \
54 /* output parameters */ \
55 : [prev_sp] "=m" (prev->thread.sp), \
56 [prev_ip] "=m" (prev->thread.ip), \
57 "=a" (last), \
58 \
59 /* clobbered output registers: */ \
60 "=b" (ebx), "=c" (ecx), "=d" (edx), \
61 "=S" (esi), "=D" (edi) \
62 \
63 __switch_canary_oparam \
64 \
65 /* input parameters: */ \
66 : [next_sp] "m" (next->thread.sp), \
67 [next_ip] "m" (next->thread.ip), \
68 \
69 /* regparm parameters for __switch_to(): */ \
70 [prev] "a" (prev), \
71 [next] "d" (next) \
72 \
73 __switch_canary_iparam \
74 \
75 : /* reloaded segment registers */ \
76 "memory"); \
77} while (0)
78
그 중"pushfl
\t" /* save flags */ \
43 "pushl %%ebp
\t" /* save EBP */ \
44 "movl %%esp,%[prev_sp]
\t" /* save ESP
먼저 전 환 된 프로 세 스 의 CPU 실행 정 보 를 저 장 했 습 니 다. 플래그 비트, 스 택 포인터 와 스 택 포인터 등 이 있 습 니 다. 이 어 전 환 된 프로 세 스 가 전 환 될 때의 실행 주 소 를 eip 로 저장 하고 실행 할 프로 세 스 의 eip 도 초기 화 했 습 니 다. "movl $1f,%[prev_ip]
\t" /* save EIP */ \
47 "pushl %[next_ip]
\t" /* restore EIP */
이 새 프로 세 스 가 전 환 된 프로 세 스 라면 새 프로 세 스 는 레이 블 1 에서 시작 하여 이전에 스 택 에 있 던 포인터 와 플래그 위 치 를 복원 합 니 다. "1:\t" \
51 "popl %%ebp
\t" /* restore EBP */ \
52 "popfl
" /* restore flags */ \
53 \
총결산
Linux 에서 실행 중인 사용자 상태 프로 세 스 X 가 중단 되 었 습 니 다. 커 널 상태 로 전환 해 야 하기 때문에 사용자 상태의 스 택 을 커 널 스 택 에 누 르 고 이 어 CPU 가 현장 을 저장 해 야 합 니 다.중단 처리 중 또는 중단 되 기 전에 schedule () 을 호출 하면 switchto 가 관건 적 인 프로 세 스 상하 문 전환 을 했 습 니 다.새로운 사용자 상태 프로 세 스 Y 는 상기 어 셈 블 리 코드 의 레이 블 1 에서 시작 합 니 다 (프로 세 스 Y 가 전환 되 었 다 고 가정 합 니 다). 이 어 프로 세 스 Y 는 CPU 현장 을 복원 하고 커 널 스 택 에 저 장 된 정 보 를 사용자 상태 스 택 으로 압축 하여 사용자 상태 프로 세 스 Y 를 계속 실행 합 니 다. 이것 은 Linux 의 일반적인 프로 세 스 스케줄 링 과 전환 메커니즘 입 니 다.
인 터 럽 트 처 리 를 통 해 프로 세 스 스케줄 을 진행 할 때 사용자 상태 프로 세 스 와 커 널 스 레 드 간 에 서로 전환 하고 커 널 스 레 드 간 에 서로 전환 합 니 다.커 널 스 레 드 전환 사이 에 schedule () 을 주동 적 으로 호출 합 니 다. 프로 세 스 컨 텍스트 간 전환 만 있 고 컨 텍스트 전환 을 중단 하지 않 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Linux 기초 관리 - 텍스트 처리 (작은 명령 조합 으로 큰 문 제 를 해결)서버 에서 로 그 를 처리 하 는 것 은 매우 흔 한 작업 이기 때문에 운영 은 각종 텍스트 도구 에 대해 조회, 분석, 통 계 를 하 는 데 필수 적 인 기본 작업 이다.정규 표현 식, grep, egrep, tr...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.