[커널 18차] 106주차

2023.06.03 22:18

kkr 조회 수:65

EAS 완. select_task_rq_fair 진행중

 

git : https://github.com/iamroot18/5.10/commit/cfdfd1a007f3faf5d690aa6ceed651f6acd089b2

 

diff --git a/drivers/opp/of.c b/drivers/opp/of.c
index 6436c1a5a4f5..a32496cd9fab 100644
--- a/drivers/opp/of.c
+++ b/drivers/opp/of.c
@@ -1401,13 +1401,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_get_of_node);
  *            cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
  *        };
  *
- * - rk3399-opp.dtsi
- *         opp00 {
- *            opp-hz = /bits/ 64 <408000000>;
- *            opp-microvolt = <825000 825000 1250000>;
- *            clock-latency-ns = <40000>;
- *        };
- * - 
+ * - em_perf_state 참고
  */
 static int __maybe_unused _get_power(unsigned long *mW, unsigned long *kHz,
                      struct device *dev)
diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h
index 4d3cbda57c05..14db30078fab 100644
--- a/include/linux/energy_model.h
+++ b/include/linux/energy_model.h
@@ -27,6 +27,32 @@
  * 전력이 될 수 있습니다.
  * @cost: 에너지 계산 중에 사용되는 이 수준과 관련된 비용 계수입니다.
  * 같음: power * max_frequency / frequency
+ *
+ * - cost 사용은 em_cpu_energy() 참고 
+ *
+ * - cost 계산은 _get_power(), em_create_perf_table() 함수 참고
+ * ------- ex --------
+ * - rk3399-opp.dtsi
+ *         opp00 {
+ *            opp-hz = /bits/ 64 <408000000>;
+ *            opp-microvolt = <825000 825000 1250000>;
+ *        };
+ *        ..
+ *        opp05 {
+ *            opp-hz = /bits/ 64 <1416000000>;
+ *            opp-microvolt = <1125000 1125000 1250000>;
+ *        };
+ *        
+ * - 가정 첫번째 408MHZ에 대한 opp를 산출
+ *   1. power 계산 예. power(mW) = (100 * mV * mV * MHZ)
+ *   100 * 825 * 825 * (408000000/1000000) = 27769500000
+ *   27769500000 / 1000000000 = 27.7695 = 27
+ *
+ *   2. frequency(kHZ) 계산 예
+ *   408000000 / 1000 = 408000
+ *
+ *   3. cost. cost = fMAX(kHZ) * power(uW) / dst_f(kHZ) 
+ *   1416000 * 27000 / 408000 = 93705.8823529 =  93705
  */
 struct em_perf_state {
     unsigned long frequency;
@@ -154,6 +180,29 @@ void em_dev_unregister_perf_domain(struct device *dev);
  * Return: the sum of the energy consumed by the CPUs of the domain assuming
  * a capacity state satisfying the max utilization of the domain.
  */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   em_cpu_energy() - 성능 도메인의 CPU가 소비하는 에너지를 추정합니다.
+ *
+ *   @pd: 에너지를 추정해야 하는 성능 영역
+ *   @max_util: 도메인의 CPU 중 가장 사용률이 높음
+ *   @sum_util: 도메인의 모든 CPU 사용률 합계
+ *   @allowed_cpu_cap: 감소된 주파수를 반영할 수 있는 @pd의 최대 허용 CPU 용량(열로 인해)
+ *
+ *   이 기능은 CPU 장치에만 사용해야 합니다. 유효성 검사가 없습니다. 즉, 
+ *   EM이 CPU 유형이고 cpumask가 할당된 경우입니다. 스케줄러 코드에서 꽤 
+ *   자주 호출되기 때문에 검사가 없습니다.
+ *
+ *   Return: 도메인의 최대 사용률을 충족하는 용량 상태를 가정하여 도메인의
+ *   CPU에서 소비한 에너지의 합계입니다.
+ *
+ * @max_util max freq model 값
+ * @sum_util energy model 합값
+ * @allowed_cpu_cap 온도가 고려된 max cpu capa
+ *
+ * - @pd의 energy 소비량 추정. 수식결과는 아래 주석 참고.
+ */
 static inline unsigned long em_cpu_energy(struct em_perf_domain *pd,
                 unsigned long max_util, unsigned long sum_util,
                 unsigned long allowed_cpu_cap)
@@ -173,10 +222,30 @@ static inline unsigned long em_cpu_energy(struct em_perf_domain *pd,
      * max utilization to the allowed CPU capacity before calculating
      * effective frequency.
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   성능 상태를 예측하기 위해 성능 영역에서 가장 많이 사용되는 CPU의 
+ *   사용률을 schedutil과 같이 요청된 빈도에 매핑합니다. 실제 주파수가 
+ *   더 낮게 설정될 수 있다는 점도 고려하십시오(열 캡핑으로 인해). 
+ *   따라서 유효 주파수를 계산하기 전에 최대 사용률을 허용된 CPU 용량으로 
+ *   고정합니다.
+ *
+ * - 최대 freq를 가르키는 ps를 가져온다.
+ */
     cpu = cpumask_first(to_cpumask(pd->cpus));
     scale_cpu = arch_scale_cpu_capacity(cpu);
     ps = &pd->table[pd->nr_perf_states - 1];
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - 125%증가를 한후 온도가 고려된 cpu capa와 min비교를 하여 max_utll
+ *   로 결과값을 내고, 계산된 결과값의 본래 cpu capa비율만큼 ps->frequency를
+ *   줄인 값을 freq에 저장한다.
+ *
+ * - ex) max_util = 215, scale_cpu = 430, ps->frequency = 1.8G
+ *   freq = 900M
+ */
     max_util = map_util_perf(max_util);
     max_util = min(max_util, allowed_cpu_cap);
     freq = map_util_freq(max_util, ps->frequency, scale_cpu);
@@ -185,6 +254,14 @@ static inline unsigned long em_cpu_energy(struct em_perf_domain *pd,
      * Find the lowest performance state of the Energy Model above the
      * requested frequency.
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   요청된 주파수보다 높은 에너지 모델의 가장 낮은 성능 상태를 찾습니다.
+ *
+ * - freq랑 제일 높은쪽으로 가까운 ps를 찾는다.
+ *   ex) freq = 900M, ps0 = 890, ps1 = 910 일때 ps1를 고른다.
+ */
     for (i = 0; i < pd->nr_perf_states; i++) {
         ps = &pd->table[i];
         if (ps->frequency >= freq)
@@ -233,6 +310,49 @@ static inline unsigned long em_cpu_energy(struct em_perf_domain *pd,
      *   pd_nrg = ------------------------                       (4)
      *                  scale_cpu
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   performance state(ps)에서 도메인의 CPU 용량은 다음과 같이 계산할 수 있습니다.
+ *             ps->freq * scale_cpu
+ *   ps->cap = --------------------                          (1)
+ *                 cpu_max_freq
+ *
+ *  따라서 유휴 상태 비용(EM에서는 사용할 수 없음)을 무시하면 해당 성능 
+ *  상태에서 이 CPU가 소비하는 에너지는 다음과 같이 추정됩니다.
+ *  (nrg : energy)
+ *
+ *             ps->power * cpu_util
+ *   cpu_nrg = --------------------                          (2)
+ *                   ps->cap
+ *
+ *  'cpu_util / ps->cap'은 바쁜 시간의 백분율을 나타냅니다.
+ *
+ *  NOTE: 이 계산의 결과는 실제로 전력 단위이지만 일정 기간 동안 
+ *  일정하다고 가정하기 때문에 일정 기간 동안 에너지 값으로 조작할 수 있습니다.
+ *
+ *  (2)에 (1)을 삽입하면 'cpu_nrg'는 두 항의 곱으로 다시 표현할 수 있습니다.
+ *
+ *             ps->power * cpu_max_freq   cpu_util
+ *   cpu_nrg = ------------------------ * ---------          (3)
+ *                    ps->freq            scale_cpu
+ *            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ *                    ps->cost
+ *
+ *  첫 번째 용어는 정적이며 em_perf_state 구조체에 'ps->cost'로 저장됩니다.
+ *
+ *  도메인의 모든 CPU는 동일한 마이크로 아키텍처를 가지므로 동일한 'ps->cost'과 
+ *  동일한 CPU 용량을 공유합니다. 따라서 도메인의 총 에너지 
+ *  (모든 CPU 에너지의 단순 합)는 다음과 같이 분해할 수 있습니다.
+ *
+ *            ps->cost * \Sum cpu_util
+ *   pd_nrg = ------------------------                       (4)
+ *                  scale_cpu
+ *
+ * - ps : max_util의 값은 근전한 freq를 고를 때사용하여 ps를 골랐다.
+ *   sun_util : energy model 합산값.
+ *   scale_cpu : cpu최대성능
+ */
     return ps->cost * sum_util / scale_cpu;
 }
 
diff --git a/include/linux/sched/cpufreq.h b/include/linux/sched/cpufreq.h
index bdd31ab93bc5..13c7f6f041b4 100644
--- a/include/linux/sched/cpufreq.h
+++ b/include/linux/sched/cpufreq.h
@@ -23,12 +23,21 @@ void cpufreq_add_update_util_hook(int cpu, struct update_util_data *data,
 void cpufreq_remove_update_util_hook(int cpu);
 bool cpufreq_this_cpu_can_update(struct cpufreq_policy *policy);
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - util의 cap대비 비율만큼 freq를 증감한다.
+ *   ex) util이 cap의 90%면 freq를 90%로 줄인다.
+ */
 static inline unsigned long map_util_freq(unsigned long util,
                     unsigned long freq, unsigned long cap)
 {
     return freq * util / cap;
 }
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - return 125%
+ */
 static inline unsigned long map_util_perf(unsigned long util)
 {
     return util + (util >> 2);
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c
index 4ebcdd657def..d0376d0263b0 100644
--- a/kernel/power/energy_model.c
+++ b/kernel/power/energy_model.c
@@ -106,6 +106,7 @@ static void em_debug_remove_pd(struct device *dev) {}
 
 /*
  * IAMROOT, 2023.05.27:
+ * - em_perf_state 주석 참고
  * - opp table 값을 읽어서 @pd의 table 을 할당하고 구성한다(cost 포함)
  */
 static int em_create_perf_table(struct device *dev, struct em_perf_domain *pd,
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 58d7a042c59f..3002d77e5142 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1785,6 +1785,10 @@ uclamp_eff_get(struct task_struct *p, enum uclamp_id clamp_id)
     return uc_req;
 }
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - @p의 clamp_id에 대한 값을 가져온다.
+ */
 unsigned long uclamp_eff_value(struct task_struct *p, enum uclamp_id clamp_id)
 {
     struct uclamp_se uc_eff;
@@ -4448,7 +4452,7 @@ void wake_up_if_idle(int cpu)
 
 /*
  * IAMROOT, 2023.05.20:
- * - 두 cpu간 llc cache 를 공유하는가?
+ * - 두 cpu간 llc(last level cache) 를 공유하는가?
  */
 bool cpus_share_cache(int this_cpu, int that_cpu)
 {
@@ -8591,6 +8595,10 @@ int idle_cpu(int cpu)
  *
  * Return: 1 if the CPU is currently idle. 0 otherwise.
  */
+/*
+ * IAMROOT, 2023.06.03:
+ * - @cpu가 idle이면 return 1.
+ */
 int available_idle_cpu(int cpu)
 {
     if (!idle_cpu(cpu))
@@ -8634,6 +8642,34 @@ struct task_struct *idle_task(int cpu)
  * based on the task model parameters and gives the minimal utilization
  * required to meet deadlines.
  */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   이 함수는 주어진 선형 관계(f = u * f_max)에서 주파수 선택에 사용되는 
+ *   주어진 CPU의 유효 사용률을 계산합니다.
+ *
+ *   스케줄러는 다음 메트릭을 추적합니다.
+ *
+ *   cpu_util_{cfs,rt,dl,irq}()
+ *   cpu_bw_dl()
+ *
+ *   여기서 cfs,rt 및 dl util 번호는 동일한 메트릭 및 동기화 창으로 추적되므로
+ *   직접 비교할 수 있습니다.
+ *
+ *   cfs,rt,dl 사용률은 rq->clock_task로 측정한 실행 시간이며 IRQ 및 도용
+ *   시간과 같은 것을 제외합니다. 이러한 후자는 irq 사용률에서 발생합니다.
+ *
+ *   DL 대역폭 수 otoh는 측정된 메트릭이 아니라 작업 모델 매개변수를 기반으로
+ *   계산된 값이며 데드라인을 맞추는 데 필요한 최소한의 사용률을 제공합니다.
+ *
+ * @max max cpu capa
+ * - 1. uclamp 미사용, freq 산출, rt가 동작중일때는 return max
+ * - freq 고려
+ *   return clamp(cfs + rt) + dl_bw
+ *
+ * - energy 고려
+ *   return cfs + rt + dl
+ */
 unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
                  unsigned long max, enum cpu_util_type type,
                  struct task_struct *p)
@@ -8641,6 +8677,10 @@ unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
     unsigned long dl_util, util, irq;
     struct rq *rq = cpu_rq(cpu);
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - uclamp가 없는 상황에서, freq 산출목적이고 rt_rq가 runnable이면 return max
+ */
     if (!uclamp_is_used() &&
         type == FREQUENCY_UTIL && rt_rq_is_runnable(&rq->rt)) {
         return max;
@@ -8651,6 +8691,15 @@ unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
      * because of inaccuracies in how we track these -- see
      * update_irq_load_avg().
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   IRQ/steal time이 CPU를 포화 상태로 만드는지 확인하기 위한 조기 확인은
+ *   이러한 추적 방법이 부정확하기 때문일 수 있습니다. update_irq_load_avg()를
+ *   참조하십시오.
+ *
+ * - irq에서 사용했던 util이 max를 넘은거같다. return max.
+ */
     irq = cpu_util_irq(rq);
     if (unlikely(irq >= max))
         return max;
@@ -8667,10 +8716,29 @@ unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
      * When there are no CFS RUNNABLE tasks, clamps are released and
      * frequency will be gracefully reduced with the utilization decay.
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   RT/DL 작업에 소요된 시간은 CFS 작업에 '손실된' 시간으로 표시되고 동일한 
+ *   메트릭을 사용하여 유효 사용률을 추적하기 때문에(PELT 창은 동기화됨) 직접 
+ *   추가하여 CPU의 실제 사용률을 얻을 수 있습니다.
+ *
+ *   CFS 및 RT 활용은 현재 RUNNABLE 작업에서 요청한 활용 클램프 제약 조건에 
+ *   따라 강화되거나 제한될 수 있습니다.
+ *
+ *   CFS RUNNABLE 작업이 없으면 클램프가 해제되고 사용률 감소에 따라 빈도가 
+ *   점진적으로 감소합니다.
+ * - rt 작업시간을 보정후 freq 산정이라면 clamp.
+ *   dl은 빼고, rt까지만 고려해서 clamp를 해주는개념이다.
+ */
     util = util_cfs + cpu_util_rt(rq);
     if (type == FREQUENCY_UTIL)
         util = uclamp_rq_util_with(rq, util, p);
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - dl은 따로 가져와서 아래에서 clamp된 rt + dl로 max를 고려한다.
+ */
     dl_util = cpu_util_dl(rq);
 
     /*
@@ -8682,6 +8750,17 @@ unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
      * NOTE: numerical errors or stop class might cause us to not quite hit
      * saturation when we should -- something for later.
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   주파수 선택의 경우 나중에 cpu_bw_dl()을 사용하고 싶기 때문에 
+ *   cpu_util_dl()을 이 합계의 영구적인 부분으로 만들지는 않지만 CFS+RT+DL 
+ *   합계가 포화 상태인지(예: 유휴 시간 없음) 확인해야 합니다. 유휴 시간이 
+ *   없을 때 f_max를 선택합니다.
+ *
+ *   NOTE: 숫자 오류 또는 중지 클래스로 인해 채도에 도달해야 할 때 채도에 
+ *   도달하지 못할 수 있습니다. 나중에 설명하겠습니다.
+ */
     if (util + dl_util >= max)
         return max;
 
@@ -8689,6 +8768,13 @@ unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
      * OTOH, for energy computation we need the estimated running time, so
      * include util_dl and ignore dl_bw.
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   OTOH, 에너지 계산을 위해 예상 실행 시간이 필요하므로 util_dl을 포함하고 
+ *   dl_bw를 무시합니다.
+ * - energy 고려면, dl까지 util을 고려한다.
+ */
     if (type == ENERGY_UTIL)
         util += dl_util;
 
@@ -8701,6 +8787,14 @@ unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
      *   U' = irq + --------- * U
      *                 max
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   아직 유휴 시간이 있습니다. irq 메트릭을 사용하여 숫자를 더 향상시킵니다. 
+ *   IRQ/도용 시간은 태스크 클럭에서 숨겨지기 때문에 태스크 번호를 조정해야 합니다.
+ *
+ * - max에 대한 irq비율만큼 util을 scaling한다음에 irq를 더한다.
+ */
     util = scale_irq_capacity(util, irq, max);
     util += irq;
 
@@ -8714,6 +8808,20 @@ unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
      * bw_dl as requested freq. However, cpufreq is not yet ready for such
      * an interface. So, we only do the latter for now.
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   DEADLINE에 필요한 대역폭은 항상 부여되어야 하는 반면, FAIR 및 RT의 경우 
+ *   더 오랜 시간 동안 작업이 표시되지 않을 때 빈도를 우아하게 줄이기 위한 
+ *   메커니즘으로 IDLE CPU의 차단된 활용을 사용합니다.
+ *
+ *   이상적으로는 bw_dl을 최소/보장 주파수로 설정하고 util + bw_dl을 요청 
+ *   주파수로 설정하고 싶습니다. 그러나 cpufreq는 아직 이러한 인터페이스를 
+ *   사용할 준비가 되어 있지 않습니다. 따라서 지금은 후자만 수행합니다.
+ *
+ * - freq일경우 bw_dl에 대한 보정을한다. 주석에선 bw_dl <= return <= util + bw_dl을
+ *   하고 싶어하지만 불가능해서 util + bw_dl만 한다는 설명이다.
+ */
     if (type == FREQUENCY_UTIL)
         util += cpu_bw_dl(rq);
 
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index d6bc14d040e5..c236797379a1 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5171,6 +5171,11 @@ static inline void update_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *s
 }
 
 #ifndef CONFIG_64BIT
+/*
+ * IAMROOT, 2023.06.03:
+ * - load_last_update_time_copy와 last_update_time이 sync할때까지
+ *   맞춘다.
+ */
 static inline u64 cfs_rq_last_update_time(struct cfs_rq *cfs_rq)
 {
     u64 last_update_time_copy;
@@ -5195,6 +5200,10 @@ static inline u64 cfs_rq_last_update_time(struct cfs_rq *cfs_rq)
  * Synchronize entity load avg of dequeued entity without locking
  * the previous rq.
  */
+/*
+ * IAMROOT, 2023.06.03:
+ * - @se cfs_rq의 last_update_time으로 decay한다.
+ */
 static void sync_entity_load_avg(struct sched_entity *se)
 {
     struct cfs_rq *cfs_rq = cfs_rq_of(se);
@@ -7617,6 +7626,10 @@ static struct {
 
 #endif /* CONFIG_NO_HZ_COMMON */
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - return cfs load
+ */
 static unsigned long cpu_load(struct rq *rq)
 {
     return cfs_rq_load_avg(&rq->cfs);
@@ -7823,6 +7836,22 @@ static int wake_wide(struct task_struct *p)
  *              scheduling latency of the CPUs. This seems to work
  *              for the overloaded case.
  */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   wake_affine()의 목적은 우리가 가장 빨리 실행할 수 있는 CPU를 빠르게 
+ *   결정하는 것입니다. 속도를 위해 깨어 있는 CPU와 이전 CPU만 고려합니다.
+ *
+ *   wake_affine_idle() - '지금'만 고려하여 깨우는 CPU가 캐시 affine이고 
+ *   유휴 상태인지 확인합니다.
+ *
+ *   wake_affine_weight() - CPU의 평균 스케줄링 대기 시간을 반영하기 
+ *   위해 가중치를 고려합니다. 이것은 오버로드된 경우에 작동하는 것 같습니다.
+ *
+ * @sync WF_SYNC set여부. select_task_rq_fair() 참고
+ * - this_cpu, prev_cpu중에 cache affine cpu를 idle위주로 고려해서 선택한다.
+ *   둘다 대상이 없으면 return nr_cpumask_bits
+ */
 static int
 wake_affine_idle(int this_cpu, int prev_cpu, int sync)
 {
@@ -7838,9 +7867,32 @@ wake_affine_idle(int this_cpu, int prev_cpu, int sync)
      * a cpufreq perspective, it's better to have higher utilisation
      * on one CPU.
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   this_cpu가 유휴 상태이면 깨우기가 인터럽트 컨텍스트에서 발생했음을 
+ *   의미합니다. 캐시가 공유된 경우에만 이동을 허용하십시오. 그렇지 
+ *   않으면 인터럽트 집중 워크로드가 IO 토폴로지 또는 IRQ 선호도 설정에 
+ *   따라 모든 작업을 하나의 노드로 강제 실행할 수 있습니다.
+ *
+ *   prev_cpu가 유휴 상태이고 캐시 관련성이 있는 경우 마이그레이션을 
+ *   피하십시오. 인터럽트의 캐시 핫 데이터가 prev_cpu의 캐시 핫 데이터보다 
+ *   더 중요하다는 보장은 없으며 cpufreq 관점에서 볼 때 하나의 CPU에서 더 
+ *   높은 활용도를 갖는 것이 좋습니다.
+ *
+ * - this_cpu가 idle, prev_cpu와 cache share.
+ *   prev_cpu가 idle이면 prev_cpu를 우선으로 고르고, 아니면 this_cpu
+ * - prev_cpu가 idle일 경우 migrate를 안하고 기존 cpu에서 동작하는 것이
+ *   l1 cache의 이득을 조금더 볼수있다고 생각한다.
+ */
     if (available_idle_cpu(this_cpu) && cpus_share_cache(this_cpu, prev_cpu))
         return available_idle_cpu(prev_cpu) ? prev_cpu : this_cpu;
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - WF_SYNC참고. prev_cpu는 가능하면 sleep하러 가야된다. 그러므로 this_cpu에서
+ *   worker를 동작시켜도 되는 상황이다.
+ */
     if (sync && cpu_rq(this_cpu)->nr_running == 1)
         return this_cpu;
 
@@ -7850,6 +7902,12 @@ wake_affine_idle(int this_cpu, int prev_cpu, int sync)
     return nr_cpumask_bits;
 }
 
+/*
+ * IAMROOT, 2023.06.03:
+ * @sync WF_SYNC set여부. select_task_rq_fair() 참고
+ * - load 비율 계산을 하여 @this_cpu가 prev_cpu비해 더 여유로우면 this_cpu
+ *   결정. this_cpu를 사용못하면 return nr_cpumask_bits
+ */
 static int
 wake_affine_weight(struct sched_domain *sd, struct task_struct *p,
            int this_cpu, int prev_cpu, int sync)
@@ -7859,22 +7917,46 @@ wake_affine_weight(struct sched_domain *sd, struct task_struct *p,
 
     this_eff_load = cpu_load(cpu_rq(this_cpu));
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - sync가 있으면 곧 sleep을 할 예정이므로 load가 감소할 것이다.
+ *   그 보정을 취한다.
+ */
     if (sync) {
         unsigned long current_load = task_h_load(current);
-
+/*
+ * IAMROOT, 2023.06.03:
+ * - this cpu에 current task가 워낙 큰 load를 차지하고 있어
+ *   없어지면 thi_cpu 부하가 없는거랑 마찬가지가 되니 그냥
+ *   this_cpu로 선택한다.
+ */
         if (current_load > this_eff_load)
             return this_cpu;
 
         this_eff_load -= current_load;
     }
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - 새로 추가되는 @p에 대한 load를 더해본다.
+ */
     task_load = task_h_load(p);
 
     this_eff_load += task_load;
+/*
+ * IAMROOT, 2023.06.03:
+ * - WA_BIAS : default true. imbalance_pct - 100 의 절반을 보정하여 
+ *   계산한다.
+ *   ex) imbalance_pct = 117 -> 8을 더 보정한다.
+ */
     if (sched_feat(WA_BIAS))
         this_eff_load *= 100;
     this_eff_load *= capacity_of(prev_cpu);
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - 다른데로 옮겨갈 @p를 prev에서 빼준다.
+ */
     prev_eff_load = cpu_load(cpu_rq(prev_cpu));
     prev_eff_load -= task_load;
     if (sched_feat(WA_BIAS))
@@ -7887,24 +7969,57 @@ wake_affine_weight(struct sched_domain *sd, struct task_struct *p,
      * stacking the wakee on top of the waker if no other CPU is
      * idle.
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   동기화된 경우 prev_eff == this_eff인 경우 select_idle_sibling()이 
+ *   다른 CPU가 유휴 상태가 아닌 경우 웨이커 위에 웨이크를 쌓는 것을 
+ *   고려하도록 prev_eff_load의 가중치를 조정합니다.
+ * - 동일한 점수일때 this_cpu가 더 유리하도록 한다.
+ */
     if (sync)
         prev_eff_load += 1;
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - this_eff_load * prev_cpu_capa < prev_eff_load * this_cpu_capa
+ *   즉 this가 prev보다 비율적으로 덜 바쁘면 this를 선택한다.
+ *   그게 아니면 fail 처리.
+ */
     return this_eff_load < prev_eff_load ? this_cpu : nr_cpumask_bits;
 }
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - 1. idle로 우선 고려. prev / this / fail
+ *   2. load 비율 고려. this / fail
+ *   3. 그외 prev
+ */
 static int wake_affine(struct sched_domain *sd, struct task_struct *p,
                int this_cpu, int prev_cpu, int sync)
 {
     int target = nr_cpumask_bits;
-
+/*
+ * IAMROOT, 2023.06.03:
+ * - WA_IDLE default true
+ *   idle인 cpu를 우선으로해서 1차적으로 결정을 한다.
+ */
     if (sched_feat(WA_IDLE))
         target = wake_affine_idle(this_cpu, prev_cpu, sync);
-
+/*
+ * IAMROOT, 2023.06.03:
+ * - WA_IDLE이 없거나 있었어도 못찾았다. WA_WEIGHT default true.
+ *   위에서 못찾앗으면 load 비율을 따져 this_cpu가 prev보다 유리하면
+ *   this_cpu로 선택한다.
+ */
     if (sched_feat(WA_WEIGHT) && target == nr_cpumask_bits)
         target = wake_affine_weight(sd, p, this_cpu, prev_cpu, sync);
 
     schedstat_inc(p->se.statistics.nr_wakeups_affine_attempts);
+/*
+ * IAMROOT, 2023.06.03:
+ * - 못찾앗으면 prev_cpu
+ */
     if (target == nr_cpumask_bits)
         return prev_cpu;
 
@@ -8581,6 +8696,18 @@ static unsigned long cpu_util_without(int cpu, struct task_struct *p)
  * Predicts what cpu_util(@cpu) would return if @p was migrated (and enqueued)
  * to @dst_cpu.
  */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   @p가 @dst_cpu로 마이그레이션(및 대기열에 포함)된 경우 cpu_util(@cpu)이 반환할
+ *   항목을 예측합니다.
+ *
+ *  @cpu 평가 cpu
+ *  @dst_cpu 목적 cpu 
+ *
+ *  - migrate 했을때의(next 상황에서의) util 예상치를 계산한다.
+ *    util 과 util_est끼리 따로 계산해서 max값을 계산한다.
+ */
 static unsigned long cpu_util_next(int cpu, struct task_struct *p, int dst_cpu)
 {
     struct cfs_rq *cfs_rq = &cpu_rq(cpu)->cfs;
@@ -8592,11 +8719,27 @@ static unsigned long cpu_util_next(int cpu, struct task_struct *p, int dst_cpu)
      * the other cases, @cpu is not impacted by the migration, so the
      * util_avg should already be correct.
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   @p가 @cpu에서 다른 것으로 마이그레이션하는 경우 해당 기여를 제거합니다. 
+ *   또는 @p가 다른 CPU에서 @cpu로 마이그레이션하는 경우 기여도를 추가합니다.
+ *   다른 경우에는 @cpu가 마이그레이션의 영향을 받지 않으므로 util_avg가 이미
+ *   정확해야 합니다.
+ *  - cpu == dst_cpu 인경우는 자신(cpu)한테 이동해오는 개념이라 추가되는 개념.
+ *    cpu != dst_cpu 인경우는 cpu -> dst_cpu로 가는 개념이라 빼야된다.
+ */
     if (task_cpu(p) == cpu && dst_cpu != cpu)
         lsub_positive(&util, task_util(p));
     else if (task_cpu(p) != cpu && dst_cpu == cpu)
         util += task_util(p);
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - 증간된 util과 est를 비교해서 max로 보정한다.
+ *   est가 task가 적어도 이만큼은 동작을해야되는 추정치이므로 이에 대한 고려
+ *   (즉 저평가 방지)를 한다.
+ */
     if (sched_feat(UTIL_EST)) {
         util_est = READ_ONCE(cfs_rq->avg.util_est.enqueued);
 
@@ -8606,6 +8749,15 @@ static unsigned long cpu_util_next(int cpu, struct task_struct *p, int dst_cpu)
          * so just add it (if needed) to "simulate" what will be
          * cpu_util() after the task has been enqueued.
          */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   깨우는 동안 작업은 아직 대기열에 추가되지 않고 rq의 
+ *   cfs_rq->avg.util_est.enqueued에 표시되지 않으므로 필요한 경우 추가하여 
+ *   작업 후 cpu_util()이 될 것을 시뮬레이트합니다. 인큐되었습니다.
+ * - 저평가를 방지하는 개념이므로, 빼야되는 상황(dst_cpu != cpu)에 대한 처리는 안하고,
+ *   더해야되는 상황에서만 수행한다.
+ */
         if (dst_cpu == cpu)
             util_est += _task_util_est(p);
 
@@ -8622,6 +8774,17 @@ static unsigned long cpu_util_next(int cpu, struct task_struct *p, int dst_cpu)
  * to compute what would be the energy if we decided to actually migrate that
  * task.
  */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   compute_energy(): @p가 @dst_cpu로 마이그레이션된 경우 @pd가 소비할 
+ *   에너지를 추정합니다. compute_energy()는 작업 마이그레이션 후 @pd CPU의 
+ *   사용 환경을 예측하고 에너지 모델을 사용하여 해당 작업을 실제로 
+ *   마이그레이션하기로 결정한 경우 에너지가 무엇인지 계산합니다.
+ *
+ * - @p가 @dst_cpu로 migrate migrate후의 @pd에 대한 energy를 예측한다.
+ *   dst_cpu == -1이면 migrate없는 상황에서의 base값.
+ */
 static long
 compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
 {
@@ -8631,6 +8794,10 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
     unsigned long _cpu_cap = cpu_cap;
     int cpu;
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - 온도 capa보정
+ */
     _cpu_cap -= arch_scale_thermal_pressure(cpumask_first(pd_mask));
 
     /*
@@ -8642,6 +8809,21 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
      * If an entire pd is outside of the current rd, it will not appear in
      * its pd list and will not be accounted by compute_energy().
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   현재 rd의 CPU 용량 상태는 동일한 pd에 속한 경우 다른 rd의 CPU에 
+ *   의해 구동될 수 있습니다. 따라서 rd span 대신 cpu_online_mask로 pd를 
+ *   마스킹하여 이러한 CPU의 사용률도 고려하십시오. 
+ *
+ *   전체 pd가 현재 rd 밖에 있는 경우 pd 목록에 나타나지 않으며 
+ *   compute_energy()에서 계산되지 않습니다.
+ *
+ * - sum_util
+ *   energy model 산출 총합
+ * - max_util
+ *   max freq util model
+ */
     for_each_cpu_and(cpu, pd_mask, cpu_online_mask) {
         unsigned long util_freq = cpu_util_next(cpu, p, dst_cpu);
         unsigned long cpu_util, util_running = util_freq;
@@ -8656,6 +8838,17 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
          * while cpu_util_next is: max(cpu_util + task_util,
          *                   cpu_util_est + _task_util_est)
          */
+/*
+ * IAMROOT, 2023.06.03:
+ * - @p가 @cpu로 migrate되는(즉 증가되는 상황) cpu에 대해서의 처리.
+ * - cpu_util_next(cpu, p, -1) 
+ *   dst_cpu가 없은 예측값을 가져온다.(max(cpu_util, cpu_util_est))
+ * - task_util_est(p) 
+ *   max(task_util, _task_util_est) 
+ *
+ * - cpu_util_next에서 dst_cpu를 넣어서 계산하는 것은 task_util만
+ *   고려가 되지만, 이렇게 task_util_est를 해 좀더 load를 추가 해준다.
+ */
         if (cpu == dst_cpu) {
             tsk = p;
             util_running =
@@ -8668,9 +8861,19 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
          * is already enough to scale the EM reported power
          * consumption at the (eventually clamped) cpu_capacity.
          */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   바쁜 시간 계산: 비율(sum_util / cpu_capacity)이 (결국 고정된) 
+ *   cpu_capacity에서 EM 보고된 전력 소비를 확장하기에 이미 충분하기 
+ *   때문에 사용률 고정이 필요하지 않습니다.
+ */
         cpu_util = effective_cpu_util(cpu, util_running, cpu_cap,
                           ENERGY_UTIL, NULL);
-
+/*
+ * IAMROOT, 2023.06.03:
+ * - 계산된 util을 온도가 계산된 cpu_capa와 min 비교후 sum_util에 추가한다.
+ */
         sum_util += min(cpu_util, _cpu_cap);
 
         /*
@@ -8680,6 +8883,17 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
          * NOTE: in case RT tasks are running, by default the
          * FREQUENCY_UTIL's utilization can be max OPP.
          */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   Performance domain frequency: utilization 클램핑은 
+ *   Performance domain frequency 선택에 영향을 미치므로 반드시 
+ *   고려해야 합니다.
+ *   메모: RT 작업이 실행 중인 경우 기본적으로 FREQUENCY_UTIL의 
+ *   utilization는 최대 OPP가 될 수 있습니다.
+ *
+ * - freq 산출은 max_util로하여 max값을 갱신한다.
+ */
         cpu_util = effective_cpu_util(cpu, util_freq, cpu_cap,
                           FREQUENCY_UTIL, tsk);
         max_util = max(max_util, min(cpu_util, _cpu_cap));
@@ -8796,6 +9010,18 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
  *   2. driven DVFS : freq를 변경해서 해결거나 깨우거나 한다.
  * ---------------
  *  
+ * @prev_cpu sleep을 햇던 cpu
+ * - ex)
+ *    pd0          pd1(max 못찾음)  pd2         pd3(max 못찾음)
+ *    cpu0<-max1   cpu2<-prev       cpu4<-max2  cpu6
+ *    cpu1         cpu3             cpu5        cpu7
+ *    > max를 찾은 pd0, pd2과 prev가 있는 pd1만을 대상으로 base_energy_pd값을 계산
+ * - 전력이득이 있는 cpu를 고른다.
+ *    > prev가 있는 pd는 prev_delta를 산출하고, best_delta min비교해서 갱신한다.
+ *    > max값이 있는 pd는 best_delta와 현재 pd를 min비교해서 best_delta, 
+ *      best_energy_cpu를 min 비교 갱신한다.
+ *    > 최종적으로, 6%이상의 이득이 있으면 best_energy_cpu를 선택하고, 그게 아니면
+ *      prev_cpu로 유지한다.
  */
 static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 {
@@ -8816,6 +9042,10 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
      * from sd_asym_cpucapacity spanning over this_cpu and prev_cpu.
      */
     sd = rcu_dereference(*this_cpu_ptr(&sd_asym_cpucapacity));
+/*
+ * IAMROOT, 2023.06.03:
+ * - @prev_cpu가 포함된 sd를 parent로 올라가면서 찾는다.
+ */
     while (sd && !cpumask_test_cpu(prev_cpu, sched_domain_span(sd)))
         sd = sd->parent;
     if (!sd)
@@ -8823,16 +9053,32 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 
     target = prev_cpu;
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - 경과시간만큼 decay
+ */
     sync_entity_load_avg(&p->se);
+/*
+ * IAMROOT, 2023.06.03:
+ * - sleep전에 load가 없엇으면 out. EAS포기.
+ */
     if (!task_util_est(p))
         goto unlock;
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - pd 순회 -> pd에 속한 cpu순회
+ */
     for (; pd; pd = pd->next) {
         unsigned long cur_delta, spare_cap, max_spare_cap = 0;
         bool compute_prev_delta = false;
         unsigned long base_energy_pd;
         int max_spare_cap_cpu = -1;
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - pd, sd에 둘다 포함되는 cpu and @p에 허용된 cpu를 iterate 한다.
+ */
         for_each_cpu_and(cpu, perf_domain_span(pd), sched_domain_span(sd)) {
             if (!cpumask_test_cpu(cpu, p->cpus_ptr))
                 continue;
@@ -8840,6 +9086,10 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
             util = cpu_util_next(cpu, p, cpu);
             cpu_cap = capacity_of(cpu);
             spare_cap = cpu_cap;
+/*
+ * IAMROOT, 2023.06.03:
+ * - 예상 사용량(util)을 빼서, 남아있는 capa를 계산(spare_cap)한다.
+ */
             lsub_positive(&spare_cap, util);
 
             /*
@@ -8849,10 +9099,29 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
              * much capacity we can get out of the CPU; this is
              * aligned with sched_cpu_util().
              */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   capacity 요청을 충족할 수 없는 CPU는 건너뜁니다.
+ *   IOW, 거기에 작업을 배치하면 CPU가 과도하게 사용됩니다. uclamp를 
+ *   고려하여 CPU에서 얼마나 많은 용량을 얻을 수 있는지 확인하십시오. 
+ *   이것은 sched_cpu_util()과 일치합니다.
+ *
+ * - 가장 여유로은 pd를 찾고, 그 pd안에서 가장 여유로운 cpu를 찾는다.
+ * - @p가 uclamp를 사용할 경우 clamp 한다.
+ */
             util = uclamp_rq_util_with(cpu_rq(cpu), util, p);
+/*
+ * IAMROOT, 2023.06.03:
+ * - util을 1.2배 해 적합한지 판별한다.
+ */
             if (!fits_capacity(util, cpu_cap))
                 continue;
-
+/*
+ * IAMROOT, 2023.06.03:
+ * - 이전 cpu가 대상 cpu에도 포함되어 대상이 된경우, compute_prev_delta를 
+ *   true로 한다.
+ */
             if (cpu == prev_cpu) {
                 /* Always use prev_cpu as a candidate. */
                 compute_prev_delta = true;
@@ -8861,23 +9130,57 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
                  * Find the CPU with the maximum spare capacity
                  * in the performance domain.
                  */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   현재 순회중인 pd에서 최대 여유 용량이 있는 CPU를 찾습니다.
+ * - max값 갱신.
+ */
                 max_spare_cap = spare_cap;
                 max_spare_cap_cpu = cpu;
             }
+/*
+ * IAMROOT, 2023.06.03:
+ * - for문 종료
+ */
         }
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - pd, sd, @p->cpus와 겹치는 span의 cpus의 iterate가 끝낫는데 
+ *   max_spare_cap_cpu을 못찾은 pd는 skip한다. 단 prev_cpu가 있는 pd는
+ *   skip하지 않는다.
+ */
         if (max_spare_cap_cpu < 0 && !compute_prev_delta)
             continue;
 
         /* Compute the 'base' energy of the pd, without @p */
+/*
+ * IAMROOT, 2023.06.03:
+ * - base를 일단계산해 base끼리 합산을 한다.
+ */
         base_energy_pd = compute_energy(p, -1, pd);
         base_energy += base_energy_pd;
 
         /* Evaluate the energy impact of using prev_cpu. */
+/*
+ * IAMROOT, 2023.06.03:
+ * - prev cpu가 있는 pd. prev_cpu로 energy를 계산하는데,
+ *   migrate를 안하는게 이득이라고 판단하면, 완전 best를 찾으러 가는 것보다
+ *   prev_cpu로 그냥 한다.
+ */
         if (compute_prev_delta) {
             prev_delta = compute_energy(p, prev_cpu, pd);
+/*
+ * IAMROOT, 2023.06.03:
+ * - migrate를 하지 않는게 더 energy 이득이라면 종료한다.
+ */
             if (prev_delta < base_energy_pd)
                 goto unlock;
+/*
+ * IAMROOT, 2023.06.03:
+ * - prev_cpu가 현재 pd의 energy의 차이값을 best_delta에 min비교하여 저장한다.
+ */
             prev_delta -= base_energy_pd;
             best_delta = min(best_delta, prev_delta);
         }
@@ -8885,8 +9188,16 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
         /* Evaluate the energy impact of using max_spare_cap_cpu. */
         if (max_spare_cap_cpu >= 0) {
             cur_delta = compute_energy(p, max_spare_cap_cpu, pd);
+/*
+ * IAMROOT, 2023.06.03:
+ * - 여기서도 위에처럼 이득만 본다면 바로 out(예외처리 개념)
+ */
             if (cur_delta < base_energy_pd)
                 goto unlock;
+/*
+ * IAMROOT, 2023.06.03:
+ * - 전력량이 상승하는 상태. 최소한의 상승인것을 우선순위에한다.
+ */
             cur_delta -= base_energy_pd;
             if (cur_delta < best_delta) {
                 best_delta = cur_delta;
@@ -8900,6 +9211,25 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
      * Pick the best CPU if prev_cpu cannot be used, or if it saves at
      * least 6% of the energy used by prev_cpu.
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   prev_cpu를 사용할 수 없거나 prev_cpu에서 사용하는 에너지의 6% 이상을 절약하는 
+ *   경우 최상의 CPU를 선택합니다.
+. 
+ * - 여기 if문에서 target이 안바뀌면 prev_cpu가 target으로 된다.
+ * - prev_delta == ULONG_MAX. 즉 prev_cpu가 한번도 대상이 된적없음.
+ *   1. best_energy_cpu가 찾아졌었으면 그것이 cpu가 된다.
+ *   2. best_energy_cpu도 찾은적이 한번도 없으면 prev_cpu가 그냥 target이된다.
+ *
+ * - (prev_delta - best_delta) > ((prev_delta + base_energy) >> 4)
+ *   즉 prev_cpu가 찾아졌었다.
+ *   prev_cpu에서보다 에너지절약이 6%이상이 되는 경우 해당 target을 return한다.
+ * - prev_delta - best_delta
+ *   옮긴후의 이득되는 delta
+ * - (prev_delta + base_energy) >> 4
+ *   옮기기전의 energy 총합의 6%
+ */
     if ((prev_delta == ULONG_MAX) ||
         (prev_delta - best_delta) > ((prev_delta + base_energy) >> 4))
         target = best_energy_cpu;
@@ -8909,6 +9239,10 @@ static int find_energy_efficient_cpu(struct task_struct *p, int prev_cpu)
 unlock:
     rcu_read_unlock();
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - return prev_cpu
+ */
     return target;
 }
 
@@ -8971,7 +9305,10 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int wake_flags)
                 return new_cpu;
             new_cpu = prev_cpu;
         }
-
+/*
+ * IAMROOT, 2023.06.03:
+ * - cache 친화여부를 알아온다.
+ */
         want_affine = !wake_wide(p) && cpumask_test_cpu(cpu, p->cpus_ptr);
     }
 
@@ -8981,6 +9318,13 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int wake_flags)
          * If both 'cpu' and 'prev_cpu' are part of this domain,
          * cpu is a valid SD_WAKE_AFFINE target.
          */
+/*
+ * IAMROOT, 2023.06.03:
+ * - cache친화를 찾아볼려고 노력을 하는상황. sd도 affine을 지원하고,
+ *   prev_cpu도 포함되어있다. 즉 affine가능한 상태다.
+ *   이때 대상 cpu가 prev_cpu 아니라면, 대상 cpu로 결정할지 정한다.
+ *   new_cpu는 prev_cpu or cpu로 무조건 골라진다.
+ */
         if (want_affine && (tmp->flags & SD_WAKE_AFFINE) &&
             cpumask_test_cpu(prev_cpu, sched_domain_span(tmp))) {
             if (cpu != prev_cpu)
@@ -8990,12 +9334,22 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int wake_flags)
             break;
         }
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - sd_flag와 겹치는 sd를 찾아 계속 iterate를 수행한다.. 만약 
+ *   못찾았는데, want_affine조차 없엇으면 그냥 종료한다.
+ */
         if (tmp->flags & sd_flag)
             sd = tmp;
         else if (!want_affine)
             break;
     }
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - want_affine이 없었거나, affine flag가 있는 sd를 못찾았다.
+ *   ING
+ */
     if (unlikely(sd)) {
         /* Slow path */
         new_cpu = find_idlest_cpu(sd, p, cpu, prev_cpu, sd_flag);
diff --git a/kernel/sched/pelt.c b/kernel/sched/pelt.c
index 18930e71f741..2618d083052e 100644
--- a/kernel/sched/pelt.c
+++ b/kernel/sched/pelt.c
@@ -583,6 +583,10 @@ ___update_load_avg(struct sched_avg *sa, unsigned long load)
  *   load_avg = \Sum se->avg.load_avg
  */
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - @now의 시각으로 decay를 목적으로 진입한다.
+ */
 int __update_load_avg_blocked_se(u64 now, struct sched_entity *se)
 {
     if (___update_load_sum(now, &se->avg, 0, 0, 0)) {
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index c92ffd3166b3..08b94f411dfa 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -2627,6 +2627,10 @@ static inline int task_on_rq_migrating(struct task_struct *p)
  */
 #define WF_TTWU     0x08 /* Wakeup;            maps to SD_BALANCE_WAKE */
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - waker는 wakeup을 한 후 sleep을 하러 가야된다는 뜻.
+ */
 #define WF_SYNC     0x10 /* Waker goes to sleep after wakeup */
 #define WF_MIGRATED 0x20 /* Internal use, task got migrated */
 #define WF_ON_CPU   0x40 /* Wakee is on_cpu */
@@ -3654,6 +3658,25 @@ unsigned long uclamp_eff_value(struct task_struct *p, enum uclamp_id clamp_id);
  * will return the correct effective uclamp value of the task even if the
  * static key is disabled.
  */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   uclamp_rq_util_with - @rq 및 @p 유효 uclamp 값을 사용하여 @util을 클램프합니다.
+ *   @rq: 클램프할 rq입니다. NULL이 아니어야 합니다.
+ *   @util: 클램프할 util 값입니다.
+ *   @p: 클램프할 작업입니다. @rq만 고정하려는 경우 NULL이 될 수 있습니다.
+ *
+ *   전달된 @util을 최대(@rq, @p) 유효 uclamp 값으로 고정합니다.
+ *
+ *   sched_uclamp_used 정적 키가 비활성화된 경우 빠른 경로의 rq 수준에서 uclamp 
+ *   집계가 비활성화되어 이 작업을 NOP로 렌더링하므로 클램핑 없이 util을 반환합니다.
+ *
+ *   rq 수준에서 uclamp 값을 신경 쓰지 않는다면 uclamp_eff_value()를 사용하십시오. 
+ *   정적 키가 비활성화된 경우에도 작업의 올바른 유효 uclamp 값을 반환합니다.
+ *
+ * - 1. 1차적으로 UCLAMP_FLAG_IDLE이 있는 경우 @p의 min max를 사용한다.
+ *   2. 그게 아니면 @p와 @rq에 대한 min max를 비교해 최대값을 사용한다.
+ */
 static __always_inline
 unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
                   struct task_struct *p)
@@ -3672,6 +3695,12 @@ unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
          * Ignore last runnable task's max clamp, as this task will
          * reset it. Similarly, no need to read the rq's min clamp.
          */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   마지막으로 실행 가능한 작업의 최대 클램프를 무시합니다. 이 작업은 
+ *   이를 재설정합니다. 마찬가지로 rq의 최소 클램프를 읽을 필요가 없습니다.
+ */
         if (rq->uclamp_flags & UCLAMP_FLAG_IDLE)
             goto out;
     }
@@ -3684,6 +3713,12 @@ unsigned long uclamp_rq_util_with(struct rq *rq, unsigned long util,
      * RUNNABLE tasks with _different_ clamps, we can end up with an
      * inversion. Fix it now when the clamps are applied.
      */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   CPU의 {min,max}_util 클램프는 _다른_ 클램프가 있는 RUNNABLE 작업을 고려하여 MAX 
+ *   집계되므로 반전으로 끝날 수 있습니다. 클램프가 적용되면 지금 수정하십시오.
+ */
     if (unlikely(min_util >= max_util))
         return min_util;
 
@@ -3740,6 +3775,20 @@ static inline unsigned long capacity_orig_of(int cpu)
  * enum is used within effective_cpu_util() to differentiate the types of
  * utilization expected by the callers, and adjust the aggregation accordingly.
  */
+/*
+ * IAMROOT, 2023.06.03:
+ * - papago
+ *   enum cpu_util_type - CPU 사용 유형
+ *   @FREQUENCY_UTIL: 주파수 선택에 사용되는 utilization
+ *   @ENERGY_UTIL: 에너지 계산 시 사용되는 utilization
+ *
+ *   모든 스케줄링 클래스(CFS/RT/DL)의 활용 신호와 IRQ 시간은 utilization에 따라 다르게 
+ *   집계해야 합니다. 이 열거형은 effective_cpu_util() 내에서 호출자가 예상하는 
+ *   사용 유형을 구별하고 그에 따라 집계를 조정하는 데 사용됩니다.
+ *
+ * - FREQUENCY_UTIL : 주파수 설정목적
+ *   ENERGY_UTIL : 에너지 산출목적
+ */
 enum cpu_util_type {
     FREQUENCY_UTIL,
     ENERGY_UTIL,
@@ -3748,17 +3797,28 @@ enum cpu_util_type {
 unsigned long effective_cpu_util(int cpu, unsigned long util_cfs,
                  unsigned long max, enum cpu_util_type type,
                  struct task_struct *p);
-
+/*
+ * IAMROOT, 2023.06.03:
+ * - return dl bw 
+ */
 static inline unsigned long cpu_bw_dl(struct rq *rq)
 {
     return (rq->dl.running_bw * SCHED_CAPACITY_SCALE) >> BW_SHIFT;
 }
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - return dl util
+ */
 static inline unsigned long cpu_util_dl(struct rq *rq)
 {
     return READ_ONCE(rq->avg_dl.util_avg);
 }
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - return max(cfs util_avg, cfs util_est)
+ */
 static inline unsigned long cpu_util_cfs(struct rq *rq)
 {
     unsigned long util = READ_ONCE(rq->cfs.avg.util_avg);
@@ -3771,6 +3831,10 @@ static inline unsigned long cpu_util_cfs(struct rq *rq)
     return util;
 }
 
+/*
+ * IAMROOT, 2023.06.03:
+ * - return rt util_avg
+ */
 static inline unsigned long cpu_util_rt(struct rq *rq)
 {
     return READ_ONCE(rq->avg_rt.util_avg);
 

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 626
208 [커널20차] 8주차 이경재 2023.06.24 74
207 [커널20차] 7주차 이경재 2023.06.18 78
206 [커널 18차] 108주차 kkr 2023.06.17 50
205 [커널 20차] 4주차 김희찬 2023.06.12 79
204 [커널 19차] 55 주차 Min 2023.06.10 28
203 [커널 19차] 54 주차 Min 2023.06.03 34
» [커널 18차] 106주차 kkr 2023.06.03 65
201 [커널 20차] 3주차 김희찬 2023.06.03 73
200 [커널 19차] 52 ~ 53 주차 Min 2023.05.27 55
199 [커널 20차] 2주차 김희찬 2023.05.20 139
198 [커널 19차] 51 주차 Min 2023.05.13 45
197 [커널 20차] 1주차 김희찬 2023.05.13 193
196 [커널 18차] 102주차 kkr 2023.05.07 75
195 [커널 19차] 50 주차 Min 2023.05.07 31
194 [커널 19차] 49 주차 Min 2023.04.29 55
193 [커널 19차] 48 주차 Min 2023.04.23 83
192 [커널 18차] 100주차 kkr 2023.04.22 83
191 [커널 18차] 99주차 kkr 2023.04.16 77
190 [커널 19차] 47 주차 Min 2023.04.15 41
189 [커널 19차] 45, 46 주차 Min 2023.04.10 59
XE Login