티스토리 뷰
5-5 kernel/pid.c alloc_pidmap
- pid namespace 에서 pid 를 할당
- 여기서는 pid 를 보관할 수 있는 페이지가 없다면 페이지만 할당 해줌
// pid 가 존재할수 있는 모든 페이지, offset 이 0이라면 1을 뺌
// 그러나 페이지의 개념은 아니고, 실패시 offset 과 pid 를 새로 변경해서 할당
max_scan = DIV_ROUND_UP(pid_max, BITS_PER_PAGE) - !offset;
5-6 kernel/pid.c alloc_pidmap 2
- 현재 page 에서 pid 할당이 가능한지 확인
- 만약 안된다면 다음 페이지에서 할당 시도 or 다음페이지가 없다면 reserved pid 로 시도
// 내껄 마지막에 등록하는걸 실패하더라도, 다른 더 뒤에있던 pid 가 쓰여졌다면 write 하지 않음
static void set_last_pid(struct pid_namespace *pid_ns, int base, int pid)
{
int prev;
int last_write = base;
do {
prev = last_write;
last_write = cmpxchg(&pid_ns->last_pid, prev, pid);
} while ((prev != last_write) && (pid_before(base, last_write, pid)));
}
5.2.3 PID 해제하기
5-7 kernel/pid.c free_pid
for (i = 0; i <= pid->level; i++) { // 최상위 pid ns 부터 탐색
struct upid *upid = pid->numbers + i; // upid 는 pid 의 정수 & hash 리스트 & namespace 를 갖음
5.2.4 PID 할당을 위한 초기화 과정
5-9 kernel/pid.c pidhash_init
- pid 해시 테이블을 초기화. struct upid 의 struct hlist_node pid_chain; 리스트를 위함
- pid 와 연관된 task_struct 를 찾을 때 사용
- hlist = hash list
struct hlist_head {
struct hlist_node *first;
};
struct hlist_node {
struct hlist_node *next, **pprev;
};
5-10 kernel/pid.c pidmap_init
- PID_MAX_LIMIT : 최대 PID 개수 제한
- PIDNS_HASH_ADDING : PID 해시 테이블에 추가할 수 있는 hash 개수
#define PID_MAX_DEFAULT (CONFIG_BASE_SMALL ? 0x1000 : 0x8000)
/*
* A maximum of 4 million PIDs should be enough for a while.
* [NOTE: PID/TIDs are limited to 2^29 ~= 500+ million, see futex.h.]
*/
#define PID_MAX_LIMIT (CONFIG_BASE_SMALL ? PAGE_SIZE * 8 : \
(sizeof(long) > 4 ? 4 * 1024 * 1024 : PID_MAX_DEFAULT))
// 최초
int pid_max = PID_MAX_DEFAULT;
#define RESERVED_PIDS 300
int pid_max_min = RESERVED_PIDS + 1;
int pid_max_max = PID_MAX_LIMIT;
5.3 실행 상태 관리하기
TASK_INTERRUPTIBLE
- 시그널로 죽일수도 있는 대기 상태
TASK_UNINTERRUPTIBLE - 원하는 이벤트로만 깨울 수 있는 상태
5.4 우선순위 관리하기
5.4.1 nice 값과 우선순위
nice 가 높다 -> 친절하다 -> 다른 task 에 많이 양보
SCHED_NORMAL
- The default policy for most tasks, including the shell. It uses a dynamic priority that changes based on the thread's characteristics.
SCHED_BATCH - Used for non-interactive tasks that should run without interruption. These tasks are usually scheduled after all SCHED_NORMAL tasks are complete. SCHED_BATCH tasks don't preempt as often as regular tasks, allowing them to run longer.
SCHED_IDLE - Used for low-priority tasks that only run when nothing else is running. SCHED_IDLE tasks are given some time to run even if other SCHED_NORMAL tasks are running.
5.4.2 static priority, normal priority, dynamic priority
- static priority : 실시간 task 에서 사용
- normal priority : 일반 task 에서 동적으로 dynamic priority 와 사용
- dynamic priority : 실시간 task 에서 동적으로 boosting 하기도 하는데 기준을 normal priority 로 잡음
5.4.3 우선순위 설정하기
5-11 kernel/sched/core.c set_user_nice
// sched.h
struct rq {}
5-12 kernel/sched/core.c set_load_weight
struct task_struct {
struct sched_entity se;
}
// include/linux/sched.h
struct sched_entity {
struct load_weight load; /* for load-balancing */
}
struct load_weight *load = &p->se.load;
sched_prio_to_weight[40 nice] -> 낮을 수록 nice 하지 않으니 weight 가 큼
load->weight = scale_load(sched_prio_to_weight[prio]);
load->inv_weight = sched_prio_to_wmult[prio];
5.4.4 PI boosting priority leak PI boosting priority leak
boost-up 된 부모의 우선순위 누수
태스크가 생성될때 자식 태스크의 static, normal priority 는 별도로 재성성 되지 않고 부모의 우선순위를 상속 받는다.
dynamic 만 부모의 normal priority 로 재설정 된다
그 이유는 boost-up 된 부모 태스크의 dynamic priority 를 자식이 상속 받는것을 막기 위해. 이 경우를 PI boosting priority leak 이라 부름
부모의 우선순위를 상속받지 않고 초기화 하기
SCHED_FLAG_RESET_ON_FORK 를 사용하면, 부모 태스크의 우선순위를 모두 상속받지 않음
5.5 태스크 생성하기
5-13 kernel/fork.c _do_fork
태스크 생성의 시작점
5.5.2 copy_process
태스크 생성은 기본적으로 부모 태스크를 복사하고, 전달된 clone 플래그에 따라 복사할 부분과 공유할 부분을 결정한다.
5-14 kernel/fork.c copy_process
CLONE_FS : 부모의 현재, 최상위 디렉토리를 자식과 공유.
- CLONE_NEWNS 는 마운트 포인트 리스트를 새로 생성해서, 같은 곳을 바라보지 못하기 때문에 사용 x
- CLONE_USER 도 아무런 이득이 없음
CLONE_THREAD 로 쓰레드를 생성할때 쓰레드 그룹은 시그널 정보를 공유해야 하므로 CLONE_SIGHAND 가 필요
CLONE_SIGHAND 플래그를 사용하면 시그널 정보를 공유하기 위해 CLONE_VM 가 필요
current->signal->flags & SIGNAL_UNKILLABLE 일때 current 는 init 태스크이다 (Pid=1) 이때 CLONE_PARENT 를 사용하면 swapper 가 새로운 부모가 되는데(init 태스크보다 높은 0), swapper 는 죽은 자식 task 를 처리할 수 없어 계속 좀비로 머문다. 따라서 플래그를 사용하면 안됨
CLONE_THREAD 때는 NEWUSER 나 NEWPID 를 사용하면 안됨
5-15 kernel/fork.c copy_process 2
Linux Security Module (LSM)
retval = security_task_create(clone_flags); // 보안 검사
dup_task_struct
// task_struct, kernel stack 할당
// task_struct 를 부모것을 복사 후 task_struct 의 stack 을 할당된 것에 가르키게하고, thread_info 의 task 를 연결
cred: The security context of a task
유저가 보유할수 있는 task 를 넘거나, thread max 를 넘어가는 경우 실패
그 외 task 초기화 등등
'개발 > 코드로 알아보는 ARM 리눅스 커널 TIL' 카테고리의 다른 글
20250111 5.5 테스크 생성하기 ~ 5.7 idle 쓰레드 (swapper) (0) | 2025.01.18 |
---|---|
20241221 4.9.5 per-cpu 동적 할당 (1) | 2025.01.04 |
20241214 4.9.3 per-cpu first_chunk 구성 & 초기화 & 동적할당 (1) | 2024.12.21 |
20241207 4.9.2 per-cpu (p516) first_chunk 할당 과정 (0) | 2024.12.07 |
20241130 4.8 kmalloc 과 vmalloc (p487) ~ 4.9 per-cpu 할당자 (0) | 2024.12.07 |
- Total
- Today
- Yesterday
- mysql
- 우리는 vr핏이라고 부릅니다
- Golang
- cockroach db
- Visual Studio
- SuffixArray
- red underline
- 영상 픽셀화 하기
- chrome-extension
- 에러 위치 찾기
- vrpit
- print shared_ptr class member variable
- 면접
- 클래스 맴버 변수 출력하기
- ad skip
- 코어 남기기
- RVO
- 카카오
- vr핏
- set value
- hole-punching
- it's called a vrpit
- Obstacle Avoidance
- 잘못된 빨간줄
- Reciprocal n-body Collision Avoidance
- C++
- Quest2
- boost
- 봄날에 스케치
- shared_from_this
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |