# load balancing: 바쁜 CPU에서 옮길 수 있는 작업 찾기

v6.18.37 / kernel/sched/fair.c

CPU마다 일이 고르게 있지 않으면 어떤 CPU는 쉬는데 다른 CPU에는 실행 대기가 쌓일 수 있습니다. 그렇다고 아무 task나 가져올 수는 없습니다. CPU 허용 범위, 현재 실행 상태와 캐시 비용 등을 고려하여 이동 가능한 후보를 찾아야 합니다.

## detach_one_task

```c

static struct task_struct *detach_one_task(struct lb_env *env)
{
	struct task_struct *p;

	lockdep_assert_rq_held(env->src_rq);

	list_for_each_entry_reverse(p,
			&env->src_rq->cfs_tasks, se.group_node) {
		if (!can_migrate_task(p, env))
			continue;

		detach_task(p, env);

		/*
		 * Right now, this is only the second place where
		 * lb_gained[env->idle] is updated (other is detach_tasks)
		 * so we can safely collect stats here rather than
		 * inside detach_tasks().
		 */
		schedstat_inc(env->sd->lb_gained[env->idle]);
		return p;
	}
	return NULL;
}

```

### 9675행

```c

static struct task_struct *detach_one_task(struct lb_env *env)

```

load balancing 환경에 맞는 task 하나를 원래 실행 큐에서 분리합니다. 여러 task를 한번에 옮기는 함수와 구분합니다.

### 9677행

```c

	struct task_struct *p;

```

각 후보 task를 가리킬 포인터를 준비합니다.

### 9679행

```c

	lockdep_assert_rq_held(env->src_rq);

```

호출자가 원래 rq 잠금을 잡고 있어야 한다는 조건을 lockdep으로 확인합니다. 여기서 잠금을 새로 획득하는 줄이 아닙니다.

### 9681행

```c

	list_for_each_entry_reverse(p,

```

리스트를 뒤에서부터 순회하면서 task 구조체를 차례로 얻습니다. 매크로가 반복문을 구성합니다.

### 9682행

```c

			&env->src_rq->cfs_tasks, se.group_node) {

```

src_rq의 cfs_tasks 목록에서 se.group_node 멤버를 연결 노드로 사용합니다. 반복 본문이 여기서 열립니다.

### 9683행

```c

		if (!can_migrate_task(p, env))

```

이 후보를 현재 환경의 대상 CPU로 이동시킬 수 없는지 확인합니다. 판단 세부 사항은 can_migrate_task에 있습니다.

### 9684행

```c

			continue;

```

불가능한 후보는 건드리지 않고 다음 task를 검사합니다.

### 9686행

```c

		detach_task(p, env);

```

가능한 후보 하나를 원래 실행 큐에서 분리하고 이동 상태를 준비합니다. 이 시점에 대상 rq에 붙이는 호출은 아닙니다.

### 9694행

```c

		schedstat_inc(env->sd->lb_gained[env->idle]);

```

현재 idle 분류에 맞는 부하 이동 성공 통계를 증가시킵니다. 정책 상태와 관찰용 통계를 구분해 보시면 됩니다.

### 9695행

```c

		return p;

```

분리한 task를 반환합니다. 첫 성공에서 끝나므로 여러 task를 계속 옮기지 않습니다.

### 9697행

```c

	return NULL;

```

이동 가능한 task를 찾지 못했으면 NULL을 반환합니다. 일상적으로 가능한 결과입니다.

