[커널 17차] 63주차

2021.11.14 02:32

ㅇㅇㅇ 조회 수:62

__cpuhp_setup_state_cpuslocked()
- 인자로 cpuhp state, state name, invoke 여부, startup/teardown callback 함수, multi instance 여부를 받는다
- 함수 cpuhp_store_callbacks()로 요청된 cpuhp state에 요청된 callback 함수를 등록하고 state name, multi instance 여부도 등록한다. 이 등록은 전역 변수 cpuhp_step 구조체 배열 cpuhp_hp_states[]에 한다
- 만약 invoke가 false이거나 startup callback이 NULL로 요청되었거나 before plug dynamic state오 요청된 경우는 callback을 수행하지 않고 그냥 종료한다
- 아닌 경우는 callback을 아래 절차를 따라 수행한다


- 각 present cpu에 대해 루프를 돌면서 아래를 수행한다
1) percpu 변수 cpuhp_state를 가져온다
2) cpuhp_state의 state를 읽어서 현재 cpu의 hot plug state값을 구한다
3) 현재 cpu state가 인자로 요청된 cpuhp_state보다 낮으면 아직 요청된 state에 도달하지 못했으므로 다음 cpu로 넘어간다
4) 함수 cpuhp_issue_call()로 callback을 수행한다
5) callback 수행에서 에러가 발생하면 롤백을 수행한다
6) 롤백은 먼저 teardown callback이 있으면 함수 cpuhp_rollback_install()로 teardown callback을 먼저 수행하고 (실패하면 안됨) 그 다음 함수 cpuhp_store_callbacks()로 위에서 등록한 state를 무효화한다

 

- 리턴한다. 이 때 after plug dynamic state로 요청된 경우는 리턴값으로 state를 반환한다

 

cpuhp_issue_call()
- 인자로 cpu, cpuhp_state, bringup 여부, hash list node를 받는다
- cpuhp_state로부터 cpuhp_hp_states[] 테이블의 state step entry sp를 가져온다
- bringup인데 table entry가 startup callback이 없거나 teardown인데 table entry의 teardown callback이 없으면 그냥 리턴한다
- 함수 cpuhp_is_ap_state()로 현재 state가 after plug인지 보고 맞으면 함수 cpuhp_invoke_ap_callback()로 callback을 수행한다. 아니면 함수 cpuhp_invoke_callback()로 callback을 수행한다
- 함수 cpuhp_is_ap_state()는 현재 state가 CPUHP_BRINGUP_CPU보다 크고 CPUHP_TEARDOWN_CPU가 아니면 true를 반환한다
- Teardown인데 invoke 실패하면 버그로 crash시킨다
- 아니면 invoke결과를 리턴한다

 

cpuhp_rollback_install()
- 인자로 failed cpu, cpuhp_state, hash list node를 받는다
- 각 present cpu에 대해 루프를 돌면서 아래를 수행한다
1) 현재 cpu의 percpu 변수 cpuhp_state를 st로 가져온다
2) st->state를 cpustate로 구한다
3) cpu가 failed cpu보다 같거나 크면 종료한다. 즉 롤백할 cpu에 대해서만 롤백을 수행한다
4) cpustate가 요청된 state보다 크면 함수 cpuhp_issue_call()로 teardown callback을 불러 롤백을 수행한다

 

cpuhp_invoke_ap_callback()
- 인자로 cpu, cpuhp_state, bringup 여부, hash list node를 받는다
- 인자로 들어온 cpu의 percpu 변수 cpuhp_state를 가져온다
- 현재 cpu가 online가 아니면 리턴한다
- 현재 cpu hp state가 thread가 아니면 함수 cpuhp_invoke_callback()로 callback 함수를 실행한다
- thread이면 아래를 cpu hp state 변수에 아래 데이터를 채워준다
- rollback = false, last = NULL, node, bringup, cb_state는 인자대로, single = true
- 함수 __cpuhp_kick_ap()로 thread를 wakeup해서 callback을 수행한다
- thread callback이 실패하고 (st->result 에러) 마지막이면 (st->last == true) st->rollback에 true를 지정하고 st->bringup은 반대로 뒤집은 뒤 다시 함수 __cpuhp_kick_ap()를 불러 thread를 wakeup시켜 rollback을 위한 callback을 수행한다
- st->node와 st->last를 NULL로 만들고 리턴한다

 

cpuhp_invoke_callback()
- 인자로 cpu, cpuhp_state, bringup 여부, hash list node, hash list last pointer를 받는다

- 인자 cpu의 percpu 변수 cpuhp_state를 가져와서 현재 cpu의 hp state를 구한다
- 현재 cpu의 hp state에 해당하는 cpuhp step을 전역변수 테이블 cpuhp_hp_states[]에서 가져온다

 

- 현재 state가 step->fail에 해당되면 에러 리턴한다. 이 때 fail은 풀어준다. 또한 bringup 여부에 따라 해당되는 callback이 없으면 에러리턴이 아니고 그냥 리턴한다
- https://github.com/torvalds/linux/commit/1db49484f21ed0fcdadd0635a3669f5f386546fa

 

- step->multi instace가 false이면 다음을 수행한다
1) bringup 여부에 따라 single callback이 NULL이면 그냥 리턴한다
2) 아니면 single callback을 호출하고 반환값을 리턴한다

 

- step->multi instance = true 이면 bringup 여부에 따라 multi callback이 NULL이면 그냥 리턴한다

 

- 인자로 hash list node가 들어오면 multi callback을 node를 인자로 주고 수행한다. 그리고 반환값을 리턴한다

 

- 인자로 hash list node가 NULL이면 step->list에 대해서 루프를 돌면서 아래를 수행한다
1) step->list의 각 node에 대해서 multi callback을 node를 인자로 주고 수행한다. 이 때 last pointer가 있으면 last pointer로 지정된 node까지만 루프를 수행한다
2) 리턴값이 에러이면 현재 node를 last pointer로 넘겨주고 에러 리턴한다. 먄약 last pointer가 없으면 error 섹션으로 점프해서 롤백을 수행한다
3) 루프가 모두 에러 없이 종료되면 리턴한다
4) error 섹션에서는 multi callback 함수를 bringup의 반대로 지정하고 step->list의 각 노드에 대해서 multi callback을 수행하여 롤백을 수행하고 리턴한다. 롤백은 앞에서 수행한 node 개수만큼만 수행한다

 

__cpuhp_kick_ap()
- 인자로 cpuhp_cpu_state st를 받는다
- st->single이 아니고 st->state와 st->target이 동일하면 그냥 리턴한다
- st->result를 0으로 초기화한다
- 메모리 배리어를 수행하고 st->should_run = true로 set.
- 함수 wake_up_process(st->thread)로 cpuhp state의 thread를 깨운다
- 함수 wait_for_ap_thread()로 깨운 thread가 callback을 수행하고 결과를 반환할 때까지 기다린다

 

page_alloc_init()
- cpuhp_setup_state_nocalls()
— __cpuhp_setup_state0
—— __cpuhp_setup_state_cpuslocked() 종료

 

callback 함수 page_alloc_cpu_dead()는 메모리 시스템이 본격적으로 나올 때 보기로 결정

 

이후엔 커널 버전 변경 논의 및 커널 빌드/디버깅 환경 구축 (QEMU) 진행

XE Login