<kernel v5.4>
Group Scheduling 관리
그룹 스케줄링은 cgroup의 cpu 서브시스템을 사용하여 구현하였고 각 그룹은 태스크 그룹(struct task_group)으로 관리된다.
- 참고로 그룹 스케줄링(스케줄 그룹)과 유사한 단어인 스케줄링 그룹(sched_group)은 로드 밸런스에서 사용하는 점에 유의한다.
다음 그림은 태스크 그룹간 계층도를 보여준다.
- cgroup 디렉토리의 계층 구조
- task_group 에서의 계층 구조
다음 그림은 태스크 그룹에 태스크 및 스케줄 엔티티가 포함된 모습을 보여준다.
다음 그림은 cfs 런큐들이 cpu 만큼 있음을 보여준다.
다음 그림은 스케줄 엔티티의 부모 관계를 보여준다.
다음 그림은 스케줄 엔티티의 cfs_rq 및 my_q가 어떤 cfs_rq를 가리키는지 보여준다.
태스크 그룹 생성 – (1)
cpu_cgroup_css_alloc()
kernel/sched/core.c
static struct cgroup_subsys_state *
cpu_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
{
struct task_group *parent = css_tg(parent_css);
struct task_group *tg;
if (!parent) {
/* This is early initialization for the top cgroup */
return &root_task_group.css;
}
tg = sched_create_group(parent);
if (IS_ERR(tg))
return ERR_PTR(-ENOMEM);
return &tg->css;
}
요청한 cpu cgroup에 연결된 태스크 그룹의 하위에 새 태스크 그룹을 생성한다.
- 코드 라인 4에서 요청한 cpu cgroup에 연결된 태스크 그룹을 알아온다.
- 코드 라인 7~10에서 태스크 그룹이 null인 경우 루트 태스크 그룹을 반환한다.
- 코드 라인 12~14에서 태스크 그룹의 child에 새 태스크 그룹을 생성하고 태스크 그룹 내부의 cfs 스케줄 그룹과 rt 스케줄 그룹을 초기화한다.
cpu cgroup 서브시스템이 설정된 커널인 경우 커널이 초기화되면서 cgroup_init_subsys() 함수에서 루트 태스크 그룹은 초기화된다. 그 밑으로 새 태스크 그룹을 생성할 때 다음과 같이 디렉토리를 생성하는 것으로 새 태스크 그룹이 생성된다.
/$ cd /sys/fs/cgroup/cpu /sys/fs/cgroup/cpu$ sudo mkdir A /sys/fs/cgroup/cpu$ ls cgroup.clone_children cpu.rt_runtime_us cpuacct.stat cpuacct.usage_percpu_user cgroup.procs cpu.shares cpuacct.usage cpuacct.usage_sys cpu.cfs_period_us cpu.stat cpuacct.usage_all cpuacct.usage_user cpu.cfs_quota_us cpu.uclamp.max cpuacct.usage_percpu notify_on_release cpu.rt_period_us cpu.uclamp.min cpuacct.usage_percpu_sys tasks
위의 주요 설정 항목들은 다음과 같다. cgroup 공통 항목들의 설명은 제외한다.
- cpu.cfs_periods_us
- cfs 밴드위드의 기간(periods)을 설정한다.
- 디폴트 값은 100,000 us 이고, 최대 값은 1,000,000 us(1초)이다.
- cpu.cfs_quota_us
- cfs 밴드위드의 quota를 설정한다.
- 디폴트 값은 -1로 이는 동작하지 않는 상태이다.
- cpu.rt_period_us
- rt 밴드위드의 기간(periods)를 설정한다.
- 디폴트 값은 100,000 us이다.
- cpu.rt_runtime_us
- rt 밴드위드의 런타임을 설정한다.
- 디폴트 값은 0으로 동작하지 않는 상태이다.
- cpu.shares
- cfs 스케줄러에서 사용하는 shares 비율이다.
- 디폴트 값은 nice-0의 로드 weight에 해당하는 1024 이다. 이 값이 클 수록 cpu 유틸을 높일 수 있다.
- cpu.stat
- 다음과 같은 rt 밴드위드 statistics 값 들을 보여준다.
- nr_periods, nr_throttled, throttled_time
- 다음과 같은 rt 밴드위드 statistics 값 들을 보여준다.
- cpu.uclamp.max
- cpu 유틸 값을 상한을 제한하는 용도인 uclamp 최대 값이다.
- 서로 다른 여러 개의 core를 가진 시스템에서 사용된다. 이 태스크 그룹에 동작하는 태스크들은 아무리 높은 cpu 유틸을 기록해도 이 제한 값을 초과하지 못하므로 low performance cpu에서 동작할 확률이 높아진다.
- 디폴트 값은 max(100%)이다.
- cpu.uclamp.min
- cpu 유틸 값의 하한을 제한하는 용도인 uclamp 최소 값이다.
- 서로 다른 여러 개의 core를 가진 시스템에서 사용된다. 이 태스크 그룹에 동작하는 태스크들은 일을 거의 하지 않아도 이 제한 값을 넘기게 되므로 high performance cpu에서 동작할 확률이 높아진다.
- 이 값이 높아질 수록 이 태스크 그룹에 해당하는 태스크들은 high performance cpu에서 동작하게 된다.
- 디폴트 값은 0이다.
다음 그림은 sched_create_group() 함수의 호출 관계를 보여준다.
sched_create_group()
kernel/sched/core.c
/* allocate runqueue etc for a new task group */
struct task_group *sched_create_group(struct task_group *parent)
{
struct task_group *tg;
tg = kmem_cache_alloc(task_group_cache, GFP_KERNEL | __GFP_ZERO);
if (!tg)
return ERR_PTR(-ENOMEM);
if (!alloc_fair_sched_group(tg, parent))
goto err;
if (!alloc_rt_sched_group(tg, parent))
goto err;
alloc_uclamp_sched_group(tg, parent);
return tg;
err:
sched_free_group(tg);
return ERR_PTR(-ENOMEM);
}
요청한 cpu cgroup의 child에 태스크 그룹을 생성하고 그 태스크 그룹에 cfs 스케줄 그룹과 rt 스케줄 그룹을 할당하고 초기화한다.
- 코드 라인 6~8에서 태스크 그룹 구조체를 할당한다.
- 코드 라인 10~11에서 태스크 그룹에 cfs 스케줄 그룹을 할당하고 초기화한다.
- 코드 라인 13~14에서 태스크 그룹에 rt 스케줄 그룹을 할당하고 초기화한다.
- 코드 라인 16에서 태스크 그룹에 uclamp 디폴트 값을 할당한다.
- 코드 라인 18에서 생성하고 초기화한 태스크 그룹을 반환한다.
다음 그림은 sched_create_group() 함수를 호출하여 태스크 그룹을 생성할 때 태스크 그룹에 연결되는 cfs 런큐, 스케줄 엔티티, rt 런큐, rt 스케줄 엔티티를 보여준다.
태스크 그룹 생성 – (2) CFS 스케줄 그룹 할당
alloc_fair_sched_group()
kernel/sched/core.c
int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent)
{
struct cfs_rq *cfs_rq;
struct sched_entity *se;
int i;
tg->cfs_rq = kzalloc(sizeof(cfs_rq) * nr_cpu_ids, GFP_KERNEL);
if (!tg->cfs_rq)
goto err;
tg->se = kzalloc(sizeof(se) * nr_cpu_ids, GFP_KERNEL);
if (!tg->se)
goto err;
tg->shares = NICE_0_LOAD;
init_cfs_bandwidth(tg_cfs_bandwidth(tg));
for_each_possible_cpu(i) {
cfs_rq = kzalloc_node(sizeof(struct cfs_rq),
GFP_KERNEL, cpu_to_node(i));
if (!cfs_rq)
goto err;
se = kzalloc_node(sizeof(struct sched_entity),
GFP_KERNEL, cpu_to_node(i));
if (!se)
goto err_free_rq;
init_cfs_rq(cfs_rq);
init_tg_cfs_entry(tg, cfs_rq, se, i, parent->se[i]);
init_entity_runnable_average(se);
}
return 1;
err_free_rq:
kfree(cfs_rq);
err:
return 0;
}
태스크 그룹에 cfs 스케줄 그룹을 할당하고 초기화한다. 성공인 경우 1을 반환한다.
- 코드 라인 7~9에서 tg->cfs_rq에 cpu 수 만큼 cfs 런큐를 가리키는 포인터를 할당한다.
- 코드 라인 10~12에서 tg->se에 cpu 수 만큼 스케줄 엔티티를 가리키는 포인터를 할당한다.
- 코드 라인 14에서 shares 값으로 기본 nice 0의 load weight 값인 NICE_0_LOAD(1024)를 대입한다.
- 64비트 시스템에서는 조금 더 정밀도를 높이기 위해 2^10 scale을 적용하여 NICE_0_LOAD 값으로 1K(1024) * 1K(1024) = 1M (1048576)를 사용한다.
- 코드 라인 16에서 cfs 대역폭을 초기화한다.
- 코드 라인 18~27에서 cpu 수 만큼 루프를 돌며 cfs 런큐 및 스케줄 엔티티를 할당받는다.
- 코드 라인 29에서 할당받은 cfs 런큐를 초기화한다.
- 코드 라인 30에서 태스크 그룹에 할당받은 cfs 런큐와 cfs 스케줄 엔티티를 연결시키고 cfs 엔트리들을 초기화한다.
- 코드 라인 31에서 엔티티 러너블 평균을 초기화한다.
- 코드 라인 34에서 성공 값 1을 반환한다.
다음 그림은 alloc_rt_sched_group() 함수를 통해 태스크 그룹이 이 함수에서 생성한 cfs 런큐와 스케줄 엔티티가 연결되고 초기화되는 모습을 보여준다.
다음 그림은 CFS 런큐 <-> 태스크 그룹 <-> 스케줄 엔티티간의 연관 관계를 보여준다.
- 하위 태스크 그룹 하나가 스케줄 엔티티 하나에 대응하고 다른 태스크의 스케줄 엔티티와 동등하게 cfs 런큐에 큐잉되어 있음을 알 수 있다.
태스크 그룹의 cfs 스케줄 엔티티 초기화
init_tg_cfs_entry()
kernel/sched/fair.c
void init_tg_cfs_entry(struct task_group *tg, struct cfs_rq *cfs_rq,
struct sched_entity *se, int cpu,
struct sched_entity *parent)
{
struct rq *rq = cpu_rq(cpu);
cfs_rq->tg = tg;
cfs_rq->rq = rq;
init_cfs_rq_runtime(cfs_rq);
tg->cfs_rq[cpu] = cfs_rq;
tg->se[cpu] = se;
/* se could be NULL for root_task_group */
if (!se)
return;
if (!parent) {
se->cfs_rq = &rq->cfs;
se->depth = 0;
} else {
se->cfs_rq = parent->my_q;
se->depth = parent->depth + 1;
}
se->my_q = cfs_rq;
/* guarantee group entities always have weight */
update_load_set(&se->load, NICE_0_LOAD);
se->parent = parent;
}
태스크 그룹에 cfs 런큐 및 cfs 스케줄 엔티티를 연결시키고 cfs 엔트리들을 초기화한다.
- 코드 라인 7~8에서 cfs 런큐의 태스크 그룹 및 런큐를 지정한다.
- 코드 라인 11에서 cfs 런큐의 스로틀링 runtime을 초기화한다.
- 코드 라인 12에서 태스크 그룹의 cfs 런큐 및 스케줄링 엔티티를 지정한다.
- 코드 라인 15~16에서 스케줄링 엔티티가 지정되지 않은 경우 함수를 빠져나간다.
- 디폴트 그룹 초기화 호출 시에는 스케줄링 엔티티가 null이다.
- 코드 라인 18~20에서 부모가 지정되지 않은 경우 스케줄링 엔티티의 cfs 런큐는 런큐의 cfs 런큐를 사용하고 depth를 0으로 한다.
- 코드 라인 21~24에서 부모가 지정된 경우 스케줄링 엔티티의 cfs 런큐는 부모의 my_q를 지정하고 depth 값은 부모 값보다 1 증가시켜 사용한다.
- 코드 라인 26에서 스케줄링 엔티티의 my_q에 cfs 런큐를 대입한다.
- 코드 라인 28에서 스케줄링 엔티티의 로드값을 일단 nice 0에 해당하는 로드 weight 값인 1024를 대입한다.
- 코드 라인 29에서 스케줄링 엔티티의 부모를 지정한다.
다음 그림은 루트 태스크 그룹부터 하위 태스크 그룹까지 init_tg_cfs_entry() 함수를 각각 호출할 때 서로 연결되는 모습을 보여준다.
- init_tg_cfs_entry() 함수와는 관계없지만 태스크 내부에 있는 스케줄 엔티티가 해당 태스크 그룹에 연결된 모습도 참고바란다.
- init_tg_cfs_entry() 함수 내부에서 다음 두 함수를 호출하여 처리하지만 그림에는 표현하지 않았다.
- init_cfs_rq_runtime() -> runtime_enable=0, throttled_list 초기화
- update_load_set() -> load.weight=1024, load.inv_weight=0으로 초기화
init_cfs_rq_runtime()
kernel/sched/fair.c
static void init_cfs_rq_runtime(struct cfs_rq *cfs_rq)
{
cfs_rq->runtime_enabled = 0;
INIT_LIST_HEAD(&cfs_rq->throttled_list);
}
cfs 런큐의 스로틀링 runtime을 초기화한다.
- 코드 라인 3에서 cfs 런큐의 runtime_enabled 값에 0을 대입하여 cfs 대역폭의 런타임 산출을 disable로 초기화한다.
- 코드 라인 4에서 throttled_list를 초기화한다.
update_load_set()
kernel/sched/fair.c
static inline void update_load_set(struct load_weight *lw, unsigned long w)
{
lw->weight = w;
lw->inv_weight = 0;
}
로드 weight 값을 설정한다. inv_weight 값은 0으로 일단 초기화한다.
태스크 그룹 생성 – (3) RT 스케줄 그룹 할당
alloc_rt_sched_group()
kernel/sched/core.c
int alloc_rt_sched_group(struct task_group *tg, struct task_group *parent)
{
struct rt_rq *rt_rq;
struct sched_rt_entity *rt_se;
int i;
tg->rt_rq = kzalloc(sizeof(rt_rq) * nr_cpu_ids, GFP_KERNEL);
if (!tg->rt_rq)
goto err;
tg->rt_se = kzalloc(sizeof(rt_se) * nr_cpu_ids, GFP_KERNEL);
if (!tg->rt_se)
goto err;
init_rt_bandwidth(&tg->rt_bandwidth,
ktime_to_ns(def_rt_bandwidth.rt_period), 0);
for_each_possible_cpu(i) {
rt_rq = kzalloc_node(sizeof(struct rt_rq),
GFP_KERNEL, cpu_to_node(i));
if (!rt_rq)
goto err;
rt_se = kzalloc_node(sizeof(struct sched_rt_entity),
GFP_KERNEL, cpu_to_node(i));
if (!rt_se)
goto err_free_rq;
init_rt_rq(rt_rq, cpu_rq(i));
rt_rq->rt_runtime = tg->rt_bandwidth.rt_runtime;
init_tg_rt_entry(tg, rt_rq, rt_se, i, parent->rt_se[i]);
}
return 1;
err_free_rq:
kfree(rt_rq);
err:
return 0;
}
태스크 그룹에 rt 스케줄 그룹을 할당하고 초기화한다. 성공인 경우 1을 반환한다.
- 코드 라인 7~9에서 tg->rt_rq에 cpu 수 만큼 rt 런큐를 가리키는 포인터를 할당한다.
- 코드 라인 10~12에서 tg->rt_se에 cpu 수 만큼 rt 스케줄 엔티티를 가리키는 포인터를 할당한다.
- 코드 라인 14~15에서 rt 대역폭을 초기화한다.
- 코드 라인 17~26에서 cpu 수 만큼 루프를 돌며 rt 런큐 및 rt 스케줄 엔티티를 할당받는다.
- 코드 라인 29에서 할당받은 rt 런큐를 초기화한다.
- 코드 라인 30에서 할당받은 rt 스케줄 엔티티를 초기화한다.
- 코드 라인 33에서 성공 값 1을 반환한다.
다음 그림은 alloc_rt_sched_group() 함수를 통해 태스크 그룹이 이 함수에서 생성한 rt 런큐와 rt 스케줄 엔티티가 연결되고 초기화되는 모습을 보여준다.
태스크 그룹의 rt 스케줄 엔티티 초기화
init_tg_rt_entry()
kernel/sched/rt.c
void init_tg_rt_entry(struct task_group *tg, struct rt_rq *rt_rq,
struct sched_rt_entity *rt_se, int cpu,
struct sched_rt_entity *parent)
{
struct rq *rq = cpu_rq(cpu);
rt_rq->highest_prio.curr = MAX_RT_PRIO;
rt_rq->rt_nr_boosted = 0;
rt_rq->rq = rq;
rt_rq->tg = tg;
tg->rt_rq[cpu] = rt_rq;
tg->rt_se[cpu] = rt_se;
if (!rt_se)
return;
if (!parent)
rt_se->rt_rq = &rq->rt;
else
rt_se->rt_rq = parent->my_q;
rt_se->my_q = rt_rq;
rt_se->parent = parent;
INIT_LIST_HEAD(&rt_se->run_list);
}
태스크 그룹에 rt 런큐 및 rt 스케줄 엔티티를 연결시키고 rt 엔트리들을 초기화한다.
- 코드 라인 7에서 rt 런큐의 highest_prio.curr에 MAX_RT_PRIO(100)으로 초기화한다.
- 코드 라인 8에서 rt_nr_boosted 값을 0으로 초기화한다.
- 코드 라인 9~10에서 rt 런큐의 태스크 그룹 및 런큐를 지정한다.
- 코드 라인 12~13에서 태스크 그룹의 rt 런큐 및 rt 스케줄링 엔티티를 지정한다.
- 코드 라인 15~16에서 rt 스케줄링 엔티티가 지정되지 않은 경우 함수를 빠져나간다.
- 디폴트 그룹 초기화 호출 시에는 rt 스케줄링 엔티티가 null이다.
- 코드 라인 18~21에서 부모가 지정되지 않은 경우 rt 스케줄링 엔티티의 rt 런큐는 런큐의 rt 런큐를 사용하고, 부모가 지정된 경우 부모의 my_q를 사용한다.
- 코드 라인 23에서 rt 스케줄링 엔티티의 my_q에 rt 런큐를 대입한다.
- 코드 라인 24에서 rt 스케줄링 엔티티의 부모를 지정한다.
- 코드 라인 25에서 rt 스케줄링 엔티티의 run_list를 초기화한다.
다음 그림은 루트 태스크 그룹부터 하위 태스크 그룹까지 init_tg_rt_entry() 함수를 각각 호출할 때 서로 연결되는 모습을 보여준다.
- init_tg_rt_entry() 함수와는 관계없지만 태스크 내부에 있는 스케줄 엔티티가 해당 태스크 그룹에 연결된 모습도 참고바란다.
CFS shares 설정
sched_group_set_shares()
kernel/sched/fair.c
int sched_group_set_shares(struct task_group *tg, unsigned long shares)
{
int i;
/*
* We can't change the weight of the root cgroup.
*/
if (!tg->se[0])
return -EINVAL;
shares = clamp(shares, scale_load(MIN_SHARES), scale_load(MAX_SHARES));
mutex_lock(&shares_mutex);
if (tg->shares == shares)
goto done;
tg->shares = shares;
for_each_possible_cpu(i) {
struct rq *rq = cpu_rq(i);
struct sched_entity *se;
struct rq_flags rf;
/* Propagate contribution to hierarchy */
raw_spin_lock_irqsave(&rq->lock, rf);
update_rq_clock(rq);
for_each_sched_entity(se) {
update_load_avg(cfs_rq_of(se), se, UPDATE_TG);
update_cfs_group(se);
}
raw_spin_unlock_irqrestore(&rq->lock, &rf);
}
done:
mutex_unlock(&shares_mutex);
return 0;
}
요청한 태스크 그룹의 cfs shares 값을 설정한다.
- 코드 라인 8~9에서 태스크 그룹의 첫 번째 스케줄 엔티티가 null인 경우 -EINVAL 에러를 반환한다.
- 루트 태스크그룹의 스케줄 엔티티 포인터들은 null로 설정되어 있다.
- 코드 라인 11~17에서 shares 값이 MIN_SHARES(2) ~ MAX_SHARES(256K) 범위에 들도록 조절하고 태스크 그룹에 설정한다. 만일 기존 shares 값에 변화가 없으면 변경 없이 그냥 성공(0)을 반환한다.
- 코드 라인 18~25에서 possible cpu 수 만큼 순회하며 런큐 및 태스크 그룹에서 스케줄 엔티티를 알아온 후 런큐 락을 획득한 후 런큐 클럭을 갱신한다.
- 코드 라인 26~29에서 계층 구조의 스케줄 엔티티들에 대해 현재 스케줄 엔티티부터 최상위 스케줄 엔티티까지 로드 평균 및 shares 값을 갱신하게 한다.
kernel/sched/sched.h
/* * A weight of 0 or 1 can cause arithmetics problems. * A weight of a cfs_rq is the sum of weights of which entities * are queued on this cfs_rq, so a weight of a entity should not be * too large, so as the shares value of a task group. * (The default weight is 1024 - so there's no practical * limitation from this.) */ #define MIN_SHARES (1UL << 1) #define MAX_SHARES (1UL << 18)
CFS shares 값 범위(2 ~ 256K)
다음 그림은 태스크 그룹에 설정한 shares 값이 스케줄 엔트리, cfs 런큐 및 런큐의 로드 weight 값에 재반영되는 모습을 보여준다.
구조체
task_group 구조체
kernel/sched/sched.h
/* Task group related information */
struct task_group {
struct cgroup_subsys_state css;
#ifdef CONFIG_FAIR_GROUP_SCHED
/* schedulable entities of this group on each CPU */
struct sched_entity **se;
/* runqueue "owned" by this group on each CPU */
struct cfs_rq **cfs_rq;
unsigned long shares;
#ifdef CONFIG_SMP
/*
* load_avg can be heavily contended at clock tick time, so put
* it in its own cacheline separated from the fields above which
* will also be accessed at each tick.
*/
atomic_long_t load_avg ____cacheline_aligned;
#endif
#endif
#ifdef CONFIG_RT_GROUP_SCHED
struct sched_rt_entity **rt_se;
struct rt_rq **rt_rq;
struct rt_bandwidth rt_bandwidth;
#endif
struct rcu_head rcu;
struct list_head list;
struct task_group *parent;
struct list_head siblings;
struct list_head children;
#ifdef CONFIG_SCHED_AUTOGROUP
struct autogroup *autogroup;
#endif
struct cfs_bandwidth cfs_bandwidth;
#ifdef CONFIG_UCLAMP_TASK_GROUP
/* The two decimal precision [%] value requested from user-space */
unsigned int uclamp_pct[UCLAMP_CNT];
/* Clamp values requested for a task group */
struct uclamp_se uclamp_req[UCLAMP_CNT];
/* Effective clamp values used for a task group */
struct uclamp_se uclamp[UCLAMP_CNT];
#endif
};
- css
- cgroup 인터페이스
- **se
- cpu 수 만큼의 스케줄링 엔티티들이다.
- cpu별 해당 태스크 그룹을 대표하는 스케줄링 엔티티이다.
- **cfs_rq
- cpu 수 만큼의 cfs 런큐들이다.
- cpu별 해당 태스크 그룹에 대한 cfs 런큐이다.
- shares
- 태스크 그룹에 소속된 cfs 태스크들이 다른 그룹과의 cpu 로드 점유 비율을 설정한다.
- 루트 태스크 그룹의 shares 값은 변경할 수 없다. (“/sys/fs/cgroup/cpu/cpu.shares”)
- 하위 태스크 그룹의 shares 값을 설정하여 사용한다.
- load_avg
- 로드 평균
- **rt_se
- cpu 수 만큼의 rt 스케줄링 엔티티들이다.
- cpu별 해당 태스크 그룹을 대표하는 스케줄링 엔티티이다.
- **rt_rq
- cpu 수 만큼의 rt 런큐들이다.
- cpu별 해당 태스크 그룹에 대한 rt 런큐이다.
- rt_bandwidth
- rt 밴드폭
- 디폴트로 rt 태스크가 최대 cpu 점유율의 95%를 사용할 수 있게한다.
- *parent
- 상위 태스크 그룹을 가리킨다.
- 루트 태스크 그룹에서는 null 값을 담는다.
- siblings
- 형재 태스크 그룹들을 담는다.
- children
- 하위 태스크 그룹을 담는다.
- *autogroup
- tty 로긴된 유저쉘에 대해 자동으로 태스크 그룹을 만들때 사용한다.
- cfs_bandwidth
- 태스크 그룹에 소속된 cfs 태스크들의 cpu 점유 비율을 결정하게 한다. (스로틀 등)
- uclamp_pct[]
- 유저가 요청한 clamp min, max의 백분률이 저장된다.
- ucmap_req[]
- 태스크 그룹을 위해 요청된 clamp 밸류들이다.
- uclamp[]
- 동작 중인 clamp min, max 설정 값이다.
참고
- Scheduler -1- (Basic) | 문c
- Scheduler -2- (Global Cpu Load) | 문c
- Scheduler -3- (PELT) | 문c
- Scheduler -4- (Group Scheduling) | 문c – 현재 글
- Scheduler -5- (Scheduler Core) | 문c
- Scheduler -6- (CFS Scheduler) | 문c
- Scheduler -7- (Preemption & Context Switch) | 문c
- Scheduler -8- (CFS Bandwidth) | 문c
- Scheduler -9- (RT Scheduler) | 문c
- Scheduler -10- (Deadline Scheduler) | 문c
- Scheduler -11- (Stop Scheduler) | 문c
- Scheduler -12- (Idle Scheduler) | 문c
- Scheduler -13- (Scheduling Domain 1) | 문c
- Scheduler -14- (Scheduling Domain 2) | 문c
- Scheduler -15- (Load Balance 1) | 문c
- Scheduler -16- (Load Balance 2) | 문c
- Scheduler -17- (Load Balance 3 NUMA) | 문c
- Scheduler -18- (Load Balance 4 EAS) | 문c
- Scheduler -19- (초기화) | 문c
- PID 관리 | 문c
- do_fork() | 문c
- cpu_startup_entry() | 문c
- 런큐 로드 평균(cpu_load[]) – v4.0 | 문c
- PELT(Per-Entity Load Tracking) – v4.0 | 문c












