[커널 18차] 95주차

2023.03.20 10:34

kkr 조회 수:119

do_idle 완

git : https://github.com/iamroot18/5.10/commit/5128910c59f87c424a4fac644a6efa77e88b80ce

diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c
index 74068742cef3..81a10393a9e3 100644
--- a/drivers/cpuidle/coupled.c
+++ b/drivers/cpuidle/coupled.c
@@ -172,6 +172,16 @@ void cpuidle_coupled_parallel_barrier(struct cpuidle_device *dev, atomic_t *a)
  *
  * Returns true if the target state is coupled with cpus besides this one
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   cpuidle_state_is_coupled - 상태가 결합 세트의 일부인지 확인합니다.
+ *   @drv: 플랫폼용 struct cpuidle_driver.
+ *   @state: drv->states에서 대상 상태의 인덱스 대상 상태가 이 이외의 
+ *   cpus와 결합된 경우 true를 반환합니다.
+ *
+ * @return true. CPUIDLE_FLAG_COUPLED 존재.(multiple cpu. cluster)
+ */
 bool cpuidle_state_is_coupled(struct cpuidle_driver *drv, int state)
 {
     return drv->states[state].flags & CPUIDLE_FLAG_COUPLED;
@@ -467,6 +477,30 @@ static bool cpuidle_coupled_any_pokes_pending(struct cpuidle_coupled *coupled)
  * interrupts while preparing for idle, and it will always return with
  * interrupts enabled.
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   cpuidle_enter_state_coupled - cpus가 연결된 상태로 들어가려고 시도합니다.
+ *   @dev: 현재 CPU에 대한 struct cpuidle_device.
+ *   @drv: 플랫폼용 struct cpuidle_driver.
+ *   @next_state: drv->states에서 요청된 상태의 인덱스.
+ *
+ *   결합된 cpus와 협력하여 대상 상태로 진입합니다. 이것은 2단계 
+ *   프로세스입니다. 첫 번째 단계에서 CPU는 독립적으로 작동하며 완전히 
+ *   다른 시간에 cpuidle_enter_state_coupled를 호출할 수 있습니다.
+ *   가능한 한 많은 전력을 절약하기 위해 이 함수를 호출하는 첫 번째 CPU는
+ *   중간 상태(cpuidle_device의 안전 상태)로 이동하고 다른 모든 CPU가 
+ *   이 함수를 호출할 때까지 기다립니다. 연결된 모든 CPU가 유휴 상태가 되면 
+ *   두 번째 단계가 시작됩니다. 연결된 각 CPU는 모든 CPU가 target_state를 
+ *   호출할 것이라고 보장할 때까지 회전합니다.
+ *
+ *   이 함수는 인터럽트를 비활성화한 상태에서 호출해야 합니다. 유휴 상태를
+ *   준비하는 동안 인터럽트를 활성화할 수 있으며 항상 인터럽트가 활성화된 
+ *   상태로 반환됩니다.
+ *
+ * - coupled된(power domain, cluster 단위의) cpu들을 더 깊게 잠들게 한다.
+ * - PASS
+ */
 int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
         struct cpuidle_driver *drv, int next_state)
 {
@@ -502,6 +536,14 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
      * exiting the waiting state due to an interrupt and
      * decrementing waiting_count, see comment below.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   이것이 대기 상태로 들어가는 마지막 CPU인 경우 다른 모든 CPU를 대기 
+ *   상태에서 빼내어 더 깊은 상태로 들어갈 수 있도록 합니다. 이것은 
+ *   인터럽트로 인해 대기 상태를 종료하는 CPU 중 하나와 Waiting_count 감소와 
+ *   경쟁할 수 있습니다. 아래 설명을 참조하십시오.
+ */
     if (w == coupled->online_count) {
         cpumask_set_cpu(dev->cpu, &cpuidle_coupled_poked);
         cpuidle_coupled_poke_others(dev->cpu, coupled);
@@ -516,6 +558,14 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
      * but the first of the two to arrive could skip the loop without
      * processing the pokes from the last to arrive.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   단일 CPU에 허용되는 가장 깊은 상태를 사용하여 결합된 모든 CPU가 유휴 
+ *   상태가 될 때까지 기다립니다. 이것이 Poking CPU가 아닌 경우, 두 개의 
+ *   CPU가 동시에 대기 루프에 도착할 수 있는 경쟁을 피하기 위해 떠나기 전에 
+ *   최소한 한 번의 Poke를 기다리십시오. 마지막부터 도착.
+ */
     while (!cpuidle_coupled_cpus_waiting(coupled) ||
             !cpumask_test_cpu(dev->cpu, &cpuidle_coupled_poked)) {
         if (cpuidle_coupled_clear_pokes(dev->cpu))
@@ -546,6 +596,12 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
      * Make sure final poke status for this cpu is visible before setting
      * cpu as ready.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   설정하기 전에 이 CPU의 최종 poke 상태가 보이는지 확인하십시오. 
+ *   cpu가 준비되었습니다.
+ */
     smp_wmb();
 
     /*
@@ -556,7 +612,16 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
      * spin until either all cpus have incremented the ready counter, or
      * another cpu leaves idle and decrements the waiting counter.
      */
-
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   연결된 모든 CPU는 아마도 유휴 상태일 것입니다. 다른 CPU 중 하나가 방금 
+ *   활성화되었을 가능성이 적습니다. 준비 카운트를 증가시키고 연결된 모든 
+ *   CPU가 카운터를 증가시킬 때까지 회전합니다. CPU가 준비 카운터를 
+ *   증가시키면 유휴를 중단할 수 없으며 모든 CPU가 준비 카운터를 
+ *   증가시키거나 다른 CPU가 유휴 상태를 유지하고 대기 카운터를 감소시킬 
+ *   때까지 회전해야 합니다.
+ */
     cpuidle_coupled_set_ready(coupled);
     while (!cpuidle_coupled_cpus_ready(coupled)) {
         /* Check if any other cpus bailed out of idle. */
@@ -570,6 +635,11 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
     /*
      * Make sure read of all cpus ready is done before reading pending pokes
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   보류 중인 pokes를 읽기 전에 모든 CPU 준비 읽기가 완료되었는지 확인하십시오.
+ */
     smp_rmb();
 
     /*
@@ -582,6 +652,17 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
      * it, and it's too late to turn on interrupts here, so reset the
      * coupled idle state of all cpus and retry.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   이 CPU가 모든 CPU가 대기 중임을 확인한 후 CPU가 유휴 상태를 떠났다가 
+ *   다시 들어갈 가능성이 적습니다. 유휴 상태로 다시 들어간 CPU는 이 CPU에 
+ *   찌르기를 보냈을 것이며 이는 준비 루프 이후에 여전히 보류 중일 것입니다. 
+ *   보류 중인 인터럽트는 깊은 유휴 상태에 들어갈 때 인터럽트 컨트롤러에 
+ *   의해 손실될 수 있습니다. 인터럽트를 켜고 처리하지 않고 보류 중인 
+ *   인터럽트를 지우는 것은 불가능하며 여기에서 인터럽트를 켜기에는 너무 
+ *   늦었으므로 모든 CPU의 연결된 유휴 상태를 재설정하고 다시 시도하십시오.
+ */
     if (cpuidle_coupled_any_pokes_pending(coupled)) {
         cpuidle_coupled_set_done(dev->cpu, coupled);
         /* Wait for all cpus to see the pending pokes */
@@ -611,6 +692,21 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
      * interrupts disabled, but won't cause problems for drivers that
      * exit with interrupts enabled.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   일반 cpuidle 상태는 irqs가 활성화된 상태로 반환될 것으로 예상됩니다.
+ *   이는 유휴 상태에서 벗어나게 하는 인터럽트를 수신하는 CPU가 유휴 입력 
+ *   기능을 종료하고 ready_count를 감소시키기 전에 해당 인터럽트를 처리하는 
+ *   비효율성을 초래합니다. 다른 모든 CPU는 인터럽트를 처리하는 CPU를 
+ *   기다리며 회전해야 합니다. 드라이버가 인터럽트가 비활성화된 상태로 
+ *   돌아오면 다른 모든 CPU는 회전하지 않고 안전한 유휴 상태로 되돌아가 
+ *   전력을 절약합니다.
+ *
+ *   여기에서 local_irq_enable을 호출하면 인터럽트가 비활성화된 상태로 
+ *   결합된 상태가 반환될 수 있지만 인터럽트가 활성화된 상태에서 종료되는 
+ *   드라이버에는 문제가 발생하지 않습니다.
+ */
     local_irq_enable();
 
     /*
@@ -618,6 +714,13 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
      * a cpu exits and re-enters the ready state because this cpu has
      * already decremented its waiting_count.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   연결된 모든 CPU가 유휴 상태에서 벗어날 때까지 기다리십시오. 이 CPU는 
+ *   이미 wait_count를 줄였기 때문에 CPU가 종료했다가 다시 준비 상태로 
+ *   들어갈 위험이 없습니다.
+ */
     while (!cpuidle_coupled_no_cpus_ready(coupled))
         cpu_relax();
 
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 93db6bd336ce..64037eabbf43 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -74,6 +74,18 @@ int cpuidle_play_dead(void)
     return -ENODEV;
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * @forbidden_flags 해당 flag가 지정되면 건너 뛴다.
+ * @return 0    : 조건에 맞는 C state 못찾음
+ *         != 0 : 조건에 맞는 C state index.
+ *
+ * - 인자 조건에 맞는 최대 exit_latency_ns를 구해서 해당 C state index를
+ *   return 한다.
+ *   max_latency_ns값이 U64_MAX가 아니라면 < max_latency_ns의 이내의 범위에서
+ *   최대 값을 찾는다.
+ * - s2idle이 true라면 s2idle에서 사용할수있는 C state를 찾는다.
+ */
 static int find_deepest_state(struct cpuidle_driver *drv,
                   struct cpuidle_device *dev,
                   u64 max_latency_ns,
@@ -136,6 +148,12 @@ void cpuidle_use_deepest_state(u64 latency_limit_ns)
  *
  * Return: the index of the deepest available idle state.
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * @return 0    : 조건에 맞는 C state 못찾음
+ *         != 0 : 조건에 맞는 C state index.
+ * - @latency_limit_ns 이내의 C state idx를 구한다.
+ */
 int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
                    struct cpuidle_device *dev,
                    u64 latency_limit_ns)
@@ -144,6 +162,12 @@ int cpuidle_find_deepest_state(struct cpuidle_driver *drv,
 }
 
 #ifdef CONFIG_SUSPEND
+/*
+ * IAMROOT, 2023.03.18:
+ * - @index의 cpudile state를 가져와 enter_s2idle(deep sleep)을 수행한다.
+ * - deel sleep전후로 sched timer를 off / on(or system suspend, resume)한다.
+ * - 깨어난 이후에는 deep sleep의 기간누적시키고 발생 빈도를 증가시킨다.
+ */
 static void enter_s2idle_proper(struct cpuidle_driver *drv,
                 struct cpuidle_device *dev, int index)
 {
@@ -161,6 +185,10 @@ static void enter_s2idle_proper(struct cpuidle_driver *drv,
     stop_critical_timings();
     if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE))
         rcu_idle_enter();
+/*
+ * IAMROOT, 2023.03.18:
+ * - 여기서 deepsleep에 들어간다.
+ */
     target_state->enter_s2idle(dev, drv, index);
     if (WARN_ON_ONCE(!irqs_disabled()))
         local_irq_disable();
@@ -193,7 +221,10 @@ static void enter_s2idle_proper(struct cpuidle_driver *drv,
  *   ->enter_s2idle 콜백이 있는 상태가 있는 경우 가장 깊은 상태를 찾아 고정된
  *   틱으로 입력합니다.
  *
- * - ING
+ * - @return 0    : s2idle로 동작하는 C state를 못찾음.
+ *   @return != 0 : s2idle로 동작하는 C state중에서 최대 latency ms state.
+ * - s2idle로 동작할 수 있는 최대 latency ms를 가진 C state찾는다.
+ *   찾은 경우 deep sleep을 하고 마친 후에는 irq를 enable한다.
  */
 int cpuidle_enter_s2idle(struct cpuidle_driver *drv, struct cpuidle_device *dev)
 {
@@ -225,6 +256,12 @@ int cpuidle_enter_s2idle(struct cpuidle_driver *drv, struct cpuidle_device *dev)
  * @drv: cpuidle driver for this cpu
  * @index: index into the states table in @drv of the state to enter
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - c state @index에 해당하는 idle을 수행하고 통계를 계산한다.
+ * - broadcast인 경우 wakeup oneshot device에 맡기는걸 시도하여
+ *   CPUIDLE_FLAG_TIMER_STOP이 없는 c state index를 새로 찾아본다.
+ */
 int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
             int index)
 {
@@ -239,9 +276,28 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
      * local timer will be shut down.  If a local timer is used from another
      * CPU as a broadcast timer, this call may fail if it is not available.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   로컬 타이머가 종료되므로 브로드캐스트 타이머로 전환하도록 시간
+ *   프레임워크에 알립니다. 로컬 타이머가 다른 CPU에서 브로드캐스트
+ *   타이머로 사용되는 경우 이 호출을 사용할 수 없으면 이 호출이 실패할 
+ *   수 있습니다.
+ *
+ * - broadcast라면, timer stop을 하고 oneshot wakeup device or
+ *   broadcast devie에 this cpu를 next_event에 깨우도록 요청한다.
+ */
     if (broadcast && tick_broadcast_enter()) {
+/*
+ * IAMROOT, 2023.03.18:
+ * - CPUIDLE_FLAG_TIMER_STOP가 제외된 exit_latency_ns이내의 c state를 찾는다.
+ */
         index = find_deepest_state(drv, dev, target_state->exit_latency_ns,
                        CPUIDLE_FLAG_TIMER_STOP, false);
+/*
+ * IAMROOT, 2023.03.18:
+ * - 못찾앗으면 default idle로 동작하고 끝낸다.
+ */
         if (index < 0) {
             default_idle_call();
             return -EBUSY;
@@ -262,6 +318,11 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
     stop_critical_timings();
     if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE))
         rcu_idle_enter();
+
+/*
+ * IAMROOT, 2023.03.18:
+ * - c state index에 따른 idle상태에 진입한다.
+ */
     entered_state = target_state->enter(dev, drv, index);
     if (!(target_state->flags & CPUIDLE_FLAG_RCU_IDLE))
         rcu_idle_exit();
@@ -272,8 +333,17 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
     trace_cpu_idle(PWR_EVENT_EXIT, dev->cpu);
 
     /* The cpu is no longer idle or about to enter idle. */
+
+/*
+ * IAMROOT, 2023.03.18:
+ * - 이제 idle이 끝났으므로 null로 설정한다.
+ */
     sched_idle_set_state(NULL);
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - broadcast였지만 위에서 전환이 실패한경우.
+ */
     if (broadcast) {
         if (WARN_ON_ONCE(!irqs_disabled()))
             local_irq_disable();
@@ -284,6 +354,10 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
     if (!cpuidle_state_is_coupled(drv, index))
         local_irq_enable();
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - idle이 끝난후, idle이 동장했던 entered_state에 대한 통계처리를 진행한다.
+ */
     if (entered_state >= 0) {
         s64 diff, delay = drv->states[entered_state].exit_latency_ns;
         int i;
@@ -324,6 +398,10 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
             }
         }
     } else {
+/*
+ * IAMROOT, 2023.03.18:
+ * - 실패 통계 처리
+ */
         dev->last_residency_ns = 0;
         dev->states_usage[index].rejected++;
     }
@@ -344,6 +422,24 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
  * 'false' boolean value if the scheduler tick should not be stopped before
  * entering the returned state.
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   cpuidle_select - 유휴 상태를 선택하도록 cpuidle 프레임워크에 요청합니다.
+ *   @drv: cpuidle 드라이버.
+ *   @dev: cpuidle 장치.
+ *   @stop_tick: 틱 중지 여부 표시.
+ *
+ *   유휴 상태의 인덱스를 반환합니다. 반환 값은 음수가 아니어야 합니다.
+ *
+ *   반환된 상태에 들어가기 전에 스케줄러 틱이 중지되지 않아야 하는 경우
+ *   @stop_tick이 가리키는 메모리 위치는 'false' 부울 값으로 기록될 것으로 예상됩니다.
+ *
+ * - curr governor에서 cpuidle을 고른다. 주석에 따르면 schedule tick이 중지되지
+ *   않아야되는 경우 stop_tick은 false로 업데이트 된다.
+ * - curr governor에서 cpuidle state를 골라서 return한다.
+ * - ex) menu_select
+ */
 int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
            bool *stop_tick)
 {
@@ -360,6 +456,10 @@ int cpuidle_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
  * Returns the index in the idle state, < 0 in case of error.
  * The error code depends on the backend driver
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - c state index해 당하는 idle을 수행한다.
+ */
 int cpuidle_enter(struct cpuidle_driver *drv, struct cpuidle_device *dev,
           int index)
 {
@@ -371,13 +471,33 @@ int cpuidle_enter(struct cpuidle_driver *drv, struct cpuidle_device *dev,
      * useful for consumers outside cpuidle, we rely on that the governor's
      * ->select() callback have decided, whether to stop the tick or not.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   먼저 만료되는 것이 무엇이든 다음 틱 또는 다음 타이머 이벤트가 되는 
+ *   다음 hrtimer를 저장합니다. 또한 이 데이터를 cpuidle 외부의 
+ *   소비자에게 유용하게 만들기 위해 우리는 거버너의 ->select() 콜백이 틱 
+ *   중지 여부를 결정했는지에 의존합니다.
+ *
+ * - 가장 먼저 완료될 시간을 dev->next_hrtimer에 저장한다.
+ *   idle을 중에 next_hrtimer가 oneshot wakeup device나 braodcast들에 의해 
+ *   next_hrtimer에 this cpu가 깨어나어 처리하게 할 것이다.
+ */
     WRITE_ONCE(dev->next_hrtimer, tick_nohz_get_next_hrtimer());
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - c state index에 해당하는 idle을 수행하고 통계를 작성한다.
+ */
     if (cpuidle_state_is_coupled(drv, index))
         ret = cpuidle_enter_state_coupled(dev, drv, index);
     else
         ret = cpuidle_enter_state(dev, drv, index);
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - 깨어나면 next_timer을 초기화한다.
+ */
     WRITE_ONCE(dev->next_hrtimer, 0);
     return ret;
 }
@@ -390,6 +510,12 @@ int cpuidle_enter(struct cpuidle_driver *drv, struct cpuidle_device *dev,
  * @index: the index in the idle state table
  *
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - curr governor에서 reflect callback을 호출한다.
+ *   idle 끝난 직후 기록 및 처리.
+ *   ex) menu_reflect
+ */
 void cpuidle_reflect(struct cpuidle_device *dev, int index)
 {
     if (cpuidle_curr_governor->reflect && index >= 0)
diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c
index 29acaf48e575..0ff722cc46ab 100644
--- a/drivers/cpuidle/governor.c
+++ b/drivers/cpuidle/governor.c
@@ -19,6 +19,66 @@
 char param_governor[CPUIDLE_NAME_LEN];
 
 LIST_HEAD(cpuidle_governors);
+
+/*
+ * IAMROOT, 2023.03.18:
+ * --- chat openai ----
+ * - governor
+ *   CPUIdle 거버너는 전력 소비를 최적화하기 위해 CPU의 전원 상태 전환을 관리하는 
+ *   Linux 커널의 소프트웨어 구성 요소입니다. 거버너는 현재 워크로드 및 시스템 활동에 
+ *   따라 CPU를 저전력 상태로 전환할 시기를 결정합니다. 거버너는 CPU의 유휴 시간을 
+ *   모니터링하고 유휴 시간이 특정 임계값에 도달하면 전환할 적절한 유휴 상태를 
+ *   선택합니다. 사용 가능한 유휴 상태는 특정 프로세서 및 하드웨어 플랫폼에 따라 
+ *   다르지만 일반적으로 C0(활성), C1(정지), C2(저전력 상태) 등과 같은 여러 수준의 
+ *   유휴 상태를 포함합니다. 거버너는 또한 처리가 필요한 들어오는 작업이 있는 경우 
+ *   저전력 상태에서 CPU를 깨우도록 결정할 수 있습니다. CPUIdle 거버너는 Linux 커널 
+ *   전원 관리 프레임워크의 중요한 구성 요소로, 에너지 소비를 줄이고 모바일 장치 및 
+ *   랩톱의 배터리 수명을 연장하는 데 도움이 됩니다. 
+ * ---------------------
+ *
+ * - cpuidle governor
+ *   cpuidle에서 사용하는 governor는 다음과 같습니다.
+ *
+ *   menu governor : 최소한의 전력 소비를 위해 가능한한 적은 C-state으로 
+ *   CPU를 유지하고, 사용자 요청이 있을 때 빠르게 복귀합니다.
+ *
+ *   ladder governor : 시스템 부하에 따라서 다른 C-state으로 이동합니다. 
+ *   부하가 낮을 때는 더 깊은 C-state으로 이동하여 전력 소비를 최소화하고, 부하가 
+ *   높을 때는 더 얕은 C-state으로 이동하여 빠른 응답성을 유지합니다.
+ *
+ *   menu-ladder governor : menu와 ladder governor의 조합입니다. 일반적으로 
+ *   ladder보다 더 나은 전력 절약을 제공합니다. 
+ *
+ *   power aware governor : Intel의 P-state 기능을 활용하여 CPU의 주파수와 전압을 
+ *   동적으로 조절하면서, 전력 소비를 최소화합니다. 
+ *
+ *   conservative governor : CPU 사용률이 낮을 때는 더 깊은 C-state으로 이동하여
+ *   전력 소비를 최소화하고, 사용률이 높을 때는 더 얕은 C-state으로 이동하여 빠른 
+ *   응답성을 유지합니다.
+ *
+ *   performance governor : CPU를 항상 최대 주파수에서 동작하도록 유지합니다.
+ *   이 governor는 전력 소비를 최소화하지 않으며, CPU 성능을 우선시하는 경우에
+ *   사용됩니다.
+ *
+ *   ondemand governor : CPU 사용률에 따라 C-state을 선택합니다. 사용률이 높을 때는
+ *   더 얕은 C-state으로 이동하여 빠른 응답성을 유지하고, 사용률이 낮을 때는 더 깊은
+ *   C-state으로 이동하여 전력 소비를 최소화합니다.
+ *
+ *   따라서 cpuidle에서는 총 7가지의 governor가 있습니다.
+ *
+ * - sysfss
+ *   1. 
+ *   cat /sys/devices/system/cpu/cpuidle/available_governors 
+ *   menu 
+ *   cat /sys/devices/system/cpu/cpuidle/current_governors 
+ *   menu
+ *
+ *   2.
+ *   cat /sys/devices/system/cpu/cpuidle/available_governors 
+ *   ladder menu teo haltpoll
+ *   cat /sys/devices/system/cpu/cpuidle/current_governors 
+ *   menu
+ */
 struct cpuidle_governor *cpuidle_curr_governor;
 struct cpuidle_governor *cpuidle_prev_governor;
 
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 5b8f418d8b99..793451bd7e0e 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -60,7 +60,8 @@ enum clock_event_state {
 /*
  * IAMROOT, 2022.12.03:
  * - C3
- *   clock 절전기능. 전원은 끄지 않고 clock만 멈추는 기능.
+ *   struct cpuidle_state 주석 참고
+ *   clock 절전.
  */
 # define CLOCK_EVT_FEAT_C3STOP        0x000008
 /*
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index ea436c764c19..162703c17e98 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -47,6 +47,38 @@ struct cpuidle_state_usage {
 
 /*
  * IAMROOT, 2023.03.11:
+ * ----- c state -------
+ *  Intel의 C State
+ *
+ *  Intel에서 제조한 프로세서는 절전 모드에서 세 가지 C-state (C1, C2, C3)를 
+ *  지원합니다.
+ *
+ *  C1 상태는 "Auto Halt" 또는 "MWAIT"라고도 불리며, 프로세서가 대기하면서 
+ *  최소한의 전력을 소비하도록 하는 가장 간단한 절전 모드입니다. 프로세서는 
+ *  일시 중지되어 있지만, 빠른 복귀를 위해 기다리고 있는 시스템 이벤트를 
+ *  감지합니다.
+ *
+ *  C2 상태는 "Stop-Clock" 또는 "HALT"라고도 불리며, 프로세서의 클럭을 
+ *  중지하고 캐시를 비우는 것을 포함하여 C1보다 더 많은 전력을 절약합니다. 
+ *  프로세서는 일시 중지 상태이지만, C1보다 더 많은 시간을 소비하므로 
+ *  기다리고 있는 이벤트를 탐지하기 위해 더 많은 시간이 걸립니다.
+ *
+ *  C3 상태는 "Deep Sleep" 또는 "Sleep"라고도 불리며, 프로세서의 코어 전압과 
+ *  클럭을 낮추어서 더 많은 전력을 절약합니다. C3 상태는 대개 C2보다 더 깊은
+ *  수면 상태이며, 프로세서는 기다리고 있는 이벤트를 탐지하기 위해 C2보다
+ *  더 많은 시간이 걸립니다.
+ *
+ *  이 세 가지 C-state는 프로세서가 실행되는 로드와 같은 여러 가지 요소에 
+ *  따라 다릅니다. 예를 들어, 높은 로드를 처리하는 경우 C1 상태가 더 많이
+ *  사용됩니다. 그러나 낮은 로드를 처리하는 경우에는 C3 상태가 더 많이
+ *  사용됩니다.
+ *
+ *  - C1 : core 정지 
+ *    C2 : c1 + cache clear
+ *    C3 : C2 + 전압 다운. option으로 timer off. 최대 절전
+ *    C5 : core 전원 off
+ * ---------------------
+ *
  * - 디바이스 트리에서 아래 변수를 가져옮.
  *   1. "entry-latency-us" + "exit-latency-us" => idle_state->exit_latency
  *      또는 "wakeup-latency-us" => idle_state->exit_latency
@@ -102,7 +134,17 @@ struct cpuidle_state {
 /* Idle State Flags */
 #define CPUIDLE_FLAG_NONE           (0x00)
 #define CPUIDLE_FLAG_POLLING        BIT(0) /* polling state */
+/*
+ * IAMROOT, 2023.03.18:
+ * - cluster로 묶은 cpu.
+ */
 #define CPUIDLE_FLAG_COUPLED        BIT(1) /* state applies to multiple cpus */
+
+/*
+ * IAMROOT, 2023.03.18:
+ * - dt 
+ *   local-timer-stop prop
+ */
 #define CPUIDLE_FLAG_TIMER_STOP     BIT(2) /* timer is stopped on this state */
 #define CPUIDLE_FLAG_UNUSABLE        BIT(3) /* avoid using this state */
 #define CPUIDLE_FLAG_OFF        BIT(4) /* disable this state by default */
@@ -121,6 +163,10 @@ struct cpuidle_device {
     ktime_t            next_hrtimer;
 
     int            last_state_idx;
+/*
+ * IAMROOT, 2023.03.18:
+ * - 마지막에 했던 idle시간. 실패했을 경우 0
+ */
     u64            last_residency_ns;
     u64            poll_limit_ns;
     u64            forced_idle_latency_limit_ns;
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 3b20d1554c38..a387dd127aee 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -96,10 +96,23 @@ static inline void tick_broadcast_force(void)
 {
     tick_broadcast_control(TICK_BROADCAST_FORCE);
 }
+
+/*
+ * IAMROOT, 2023.03.18:
+ * @return 0   : 성공
+ *         < 0 : c3 stop 미지원이나 못한 경우.
+ * - tick device에서 c3 stop을 지원한다면 tick deviec를 정지시키고 
+ *   oneshot wakeup device에서 해당 cpu를 깨우게 맡긴다.
+ */
 static inline int tick_broadcast_enter(void)
 {
     return tick_broadcast_oneshot_control(TICK_BROADCAST_ENTER);
 }
+
+/*
+ * IAMROOT, 2023.03.18:
+ * - braodcast에서 exit.
+ */
 static inline void tick_broadcast_exit(void)
 {
     tick_broadcast_oneshot_control(TICK_BROADCAST_EXIT);
@@ -191,6 +204,11 @@ static inline bool tick_nohz_full_enabled(void)
  * the cpu expression (typically smp_processor_id()) _after_ the static
  * key.
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - nohz full이 enable이 되있고, @_cpu가 tick_nohz_full_mask에 포함된다면
+ *   return true.
+ */
 #define tick_nohz_full_cpu(_cpu) ({                    \
     bool __ret = false;                        \
     if (tick_nohz_full_enabled())                    \
diff --git a/kernel/pid.c b/kernel/pid.c
index efe87db44683..3ecc8a0c29ef 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -45,6 +45,10 @@
 #include <net/sock.h>
 #include <uapi/linux/pidfd.h>
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - numbers를 tag찍고 들어가면 struct pid가 보인다.
+ */
 struct pid init_struct_pid = {
     .count        = REFCOUNT_INIT(1),
     .tasks        = {
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index d04237de9672..296103876142 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -83,9 +83,7 @@ static DECLARE_SWAIT_QUEUE_HEAD(s2idle_wait_head);
  *
  * S2idle 상태는 저전력 유휴 상태로, 시스템이 전력을 절약하면서 사용자 입력에
  * 일정 수준의 응답성을 유지합니다. 이 상태에서 시스템은 사용자 활동에 응답하여
- * 전체 전원 모드로 빠르게 다시 전환할 수 있습니다. 이것은 suspend-to-RAM 또는
- * suspend-to-disk와 같은 더 깊은 유휴 상태와는 대조적으로, 깨우고 정상 작동을
- * 재개하는 데 더 오랜 시간이 필요합니다.
+ * 전체 전원 모드로 빠르게 다시 전환할 수 있습니다.
  *
  * S2Idle(suspend-to-idle) 기능의 세 가지 가능한 상태를 정의합니다.
  * 이 기능은 웨이크업 시간이 빠른 최신 시스템에 최적화된 저전력 절전
@@ -107,8 +105,104 @@ static DECLARE_SWAIT_QUEUE_HEAD(s2idle_wait_head);
  * 나가는 적절한 작업을 수행할 수 있을 뿐만 아니라 시스템이 S2Idle 상태에
  * 있는 동안 발생하는 인터럽트 및 기타 이벤트를 처리할 수 있습니다.
  *
+ * ---- Documentation/admin-guide/pm/sleep-states.rst ----
+ * - s2idle (suspend-to-idle)
+ *   이는 일반, 순수 소프트웨어, 시스템 일시 중단의 경량 
+ *   변형입니다(S2I 또는 S2Idle이라고도 함). 사용자 공간을 동결하고 시간 
+ *   기록을 중단하고 모든 I/O 장치를 저전력 상태(작동 상태에서 사용 가능한 
+ *   것보다 더 낮은 전력)로 전환하여 런타임 유휴 상태에 비해 더 많은 
+ *   에너지를 절약할 수 있습니다. 시스템이 일시 중단된 동안 가장 깊은 
+ *   유휴 상태에 있는 시간입니다.
+ *
+ *   시스템은 대역 내 인터럽트에 의해 이 상태에서 깨어나므로 이론적으로 
+ *   작동 상태에서 인터럽트를 생성할 수 있는 모든 장치를 S2Idle용 웨이크업 
+ *   장치로 설정할 수 있습니다. 
+ *
+ *   이 상태는 :ref:`standby <standby>` 또는 :ref:`suspend-to-RAM <s2ram>`을 
+ *   지원하지 않는 플랫폼에서 사용할 수 있습니다. 재개 대기 시간 감소를 
+ *   제공합니다. :c:macro:`CONFIG_SUSPEND` 커널 구성 옵션이 설정되어 있으면 
+ *   항상 지원됩니다.
+ *
+ * - s2ram (suspend-to-ram)
+ *   이 상태(STR 또는 S2RAM이라고도 함)는 지원되는 경우 메모리를 제외하고 
+ *   시스템의 모든 것이 저전력 상태로 전환되므로 상당한 에너지 절감 효과를 
+ *   제공합니다. 내용물. 대기 <대기>'에 들어갈 때 수행되는 모든 단계는 
+ *   S2RAM으로 전환하는 동안에도 수행됩니다. 플랫폼 기능에 따라 추가 작업이 
+ *   발생할 수 있습니다. 특히, ACPI 기반 시스템에서 커널은 S2RAM 전환 중 
+ *   마지막 단계로 플랫폼 펌웨어(BIOS)에 제어권을 넘기고 그 결과 일반적으로 
+ *   커널이 직접 제어하지 않는 일부 하위 수준 구성 요소의 전원이 꺼집니다.
+ *
+ *   장치 및 CPU의 상태는 메모리에 저장되고 유지됩니다. 모든 장치가 일시 
+ *   중단되고 저전력 상태로 전환됩니다. 많은 경우에 모든 주변 장치 버스는 
+ *   S2RAM에 진입할 때 전력이 손실되므로 장치는 "켜짐" 상태로의 전환을 
+ *   처리할 수 있어야 합니다.  
+ *
+ *   ACPI 기반 시스템에서 S2RAM은 플랫폼 펌웨어에서 시스템을 재개하기 위해 
+ *   최소한의 부트스트래핑 코드가 필요합니다. 다른 플랫폼에서도 마찬가지일 
+ *   수 있습니다.
+ *
+ *   S2RAM에서 시스템을 깨울 수 있는 장치 세트는 일반적으로 일시 중지에서 
+ *   유휴 <s2idle>` 및 대기 <standby>`에 비해 줄어들며 플랫폼에 의존해야 할 
+ *   수도 있습니다. 웨이크업 기능을 적절하게 설정하기 위해.
+ *
+ *   S2RAM은 :c:macro:`CONFIG_SUSPEND` 커널 구성 옵션이 설정되고 이에 대한 
+ *   지원이 코어 시스템 일시 중지 하위 시스템이 있는 플랫폼에서 등록된 경우 
+ *   지원됩니다. ACPI 기반 시스템에서는 ACPI에서 정의한 S3 시스템 상태에 
+ *   매핑됩니다. 
+ *
+ * - standby
+ *   지원되는 경우 이 상태는 작동 상태로의 비교적 간단한 전환을 제공하면서 
+ *   중간 정도의 실질적인 에너지 절감 효과를 제공합니다. 작동 상태가 
+ *   손실되지 않으므로(시스템 코어 로직이 전원을 유지함) 시스템이 중단된
+ *   위치로 충분히 쉽게 돌아갈 수 있습니다.  사용자 공간 정지, 시간 기록 
+ *   일시 중단 및 모든 I/O 장치를 저전력 상태로 전환하는 것 외에도 유휴 
+ *   일시 중단 <s2idle>`에 대해서도 수행되며 부팅되지 않는 CPU는 오프라인 
+ *   상태가 되며 모두 로우 상태가 됩니다. -레벨 시스템 기능은 이 상태로 
+ *   전환하는 동안 일시 중지됩니다. 이러한 이유로 일시 중단에서 유휴
+ *   <s2idle>`에 비해 더 많은 에너지를 절약할 수 있어야 하지만 재개 대기
+ *   시간은 일반적으로 해당 상태보다 큽니다.
+ *
+ *   이 상태에서 시스템을 깨울 수 있는 장치 집합은 일반적으로
+ *   'suspend-to-idle <s2idle>'에 비해 줄어들며 깨우기 기능을 적절하게
+ *   설정하기 위해 플랫폼에 의존해야 할 수도 있습니다.
+ *
+ *   이 상태는 :c:macro:`CONFIG_SUSPEND` 커널 구성 옵션이 설정되고 이에 
+ *   대한 지원이 코어 시스템 일시 중지 하위 시스템이 있는 플랫폼에서 등록된
+ *   경우에 지원됩니다. ACPI 기반 시스템에서 이 상태는 ACPI에서 정의한 S1 
+ *   시스템 상태에 매핑됩니다. 
+ *
+ * - 절전 진입 및 복귀 속도 
+ *   s2idle > standby > s2ram > s2disk
+ * ---  sysfs -------
+ * - sysfs에서 확인 및 진입방법
+ *   - s2idle
+ *        /sys/power/state        freeze
+ *        /sys/power/mem_sleep    s2idle 로 변경 후 /sys/power/state mem 입력.
+ *   - standby
+ *        /sys/power/state        standby
+ *        /sys/power/mem_sleep    shallow 로 변경 후 /sys/power/state mem 입력.
+ *   - s2ram
+ *        /sys/power/mem_sleep    deep 로 변경후 /sys/power/state mem 입력.
+ *   - s2disk
+ *      /sys/power/state        disk 
+ *      /sys/power/disk에 선택된 설정이 동작한다.
+ *      (shutdown, reboot, suspend, test_resume)
+ * - 사용예 
+ *  1. 
+ *   KVM /sys/power$ echo reboot > disk 
+ *   KVM /sys/power$ cat disk 
+ *   shutdown [reboot] suspend test_resume
+ *  2. 
+ *  KVM /sys/power$ echo disk > state 
+ *  [   87.915123] PM: hibernation: hibernation entry
+ *
+ *  3. 
+ *  KVM /sys/power$ cat mem_sleep 
+ *  [s2idle] 
+ *  KVM /sys/power$ echo mem > state 
+ *  [  153.478136] PM: suspend entry (s2idle)
+ * ----------------------------------------------------------
  *
- * --------------------
  */
 enum s2idle_states __read_mostly s2idle_state;
 static DEFINE_RAW_SPINLOCK(s2idle_lock);
diff --git a/kernel/sched/clock.c b/kernel/sched/clock.c
index e5d41fee25f9..7feadd0fb4d2 100644
--- a/kernel/sched/clock.c
+++ b/kernel/sched/clock.c
@@ -441,6 +441,10 @@ EXPORT_SYMBOL_GPL(sched_clock_idle_sleep_event);
 /*
  * We just idled; resync with ktime.
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - arm64는 stable clock이다. return.
+ */
 void sched_clock_idle_wakeup_event(void)
 {
     unsigned long flags;
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 30960a642312..5ecb977702d6 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7228,6 +7228,20 @@ EXPORT_SYMBOL(schedule);
  * schedule_idle() is similar to schedule_preempt_disable() except that it
  * never enables preemption because it does not call sched_submit_work().
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   synchronize_rcu_tasks()는 모든 작업이 실행 대기열을 떠났거나 사용자
+ *   공간으로 이동했는지 확인하여 어떤 작업도 선점된 상태(비자발적으로
+ *   예약됨)에 걸리지 않도록 합니다.
+ *   유휴 작업은 어느 쪽도 수행하지 않으므로 선점되어서는 안 
+ *   됩니다(비자발적으로 스케줄 아웃).
+ *
+ *   schedule_idle()은 sched_submit_work()를 호출하지 않기 때문에 선점을 
+ *   활성화하지 않는다는 점을 제외하면 schedule_preempt_disable()과 유사합니다.
+ *
+ * - 자발적 schedule을 뜻하는 SM_NONE을 들고 schedule한다.
+ */
 void __sched schedule_idle(void)
 {
     /*
@@ -7237,6 +7251,14 @@ void __sched schedule_idle(void)
      * current task can be in any other state. Note, idle is always in the
      * TASK_RUNNING state.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   이것은 작업이 TASK_RUNNING 상태일 때 해당 함수가 nop이기 때문에 유휴 
+ *   작업이 수행하는 sched_submit_work() 호출을 건너뛰기 때문에 현재 작업이 
+ *   다른 상태에 있을 수 있는 곳에서 사용되지 않는지 확인하세요. 유휴 상태는 
+ *   항상 TASK_RUNNING 상태입니다.
+ */
     WARN_ON_ONCE(current->__state);
     do {
         __schedule(SM_NONE);
diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
index 202a61e9a1ab..687882b8f330 100644
--- a/kernel/sched/idle.c
+++ b/kernel/sched/idle.c
@@ -17,6 +17,10 @@ extern char __cpuidle_text_start[], __cpuidle_text_end[];
  * sched_idle_set_state - Record idle state for the current CPU.
  * @idle_state: State to record.
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - this rq의 현재 idle state를 @idle_state로 설정한다.
+ */
 void sched_idle_set_state(struct cpuidle_state *idle_state)
 {
     idle_set_state(this_rq(), idle_state);
@@ -55,6 +59,10 @@ void sched_idle_set_state(struct cpuidle_state *idle_state)
  */
 static int __read_mostly cpu_idle_force_poll;
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - cpuidle을 poll force 하기 위한 enalbe / disable
+ */
 void cpu_idle_poll_ctrl(bool enable)
 {
     if (enable) {
@@ -66,6 +74,10 @@ void cpu_idle_poll_ctrl(bool enable)
 }
 
 #ifdef CONFIG_GENERIC_IDLE_POLL_SETUP
+/*
+ * IAMROOT, 2023.03.18:
+ * - cpuidle을 poll force 시킨다.
+ */
 static int __init cpu_idle_poll_setup(char *__unused)
 {
     cpu_idle_force_poll = 1;
@@ -74,6 +86,10 @@ static int __init cpu_idle_poll_setup(char *__unused)
 }
 __setup("nohlt", cpu_idle_poll_setup);
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - cpuidle의 poll force를 disable 한다.
+ */
 static int __init cpu_idle_nopoll_setup(char *__unused)
 {
     cpu_idle_force_poll = 0;
@@ -111,6 +127,11 @@ void __weak arch_cpu_idle_prepare(void) { }
 void __weak arch_cpu_idle_enter(void) { }
 void __weak arch_cpu_idle_exit(void) { }
 void __weak arch_cpu_idle_dead(void) { }
+
+/*
+ * IAMROOT, 2023.03.18:
+ * - idle을 한다해도 deep sleep 하지 않기 위한 방식. 
+ */
 void __weak arch_cpu_idle(void)
 {
     cpu_idle_force_poll = 1;
@@ -204,7 +225,8 @@ void __cpuidle default_idle_call(void)
 
 /*
  * IAMROOT, 2023.03.17:
- * - ING
+ * - reschedule 요청있으면 return busy.
+ *   그게 아니면 deep sleep을 수행한다.
  */
 static int call_cpuidle_s2idle(struct cpuidle_driver *drv,
                    struct cpuidle_device *dev)
@@ -215,6 +237,11 @@ static int call_cpuidle_s2idle(struct cpuidle_driver *drv,
     return cpuidle_enter_s2idle(drv, dev);
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - reschedule 요청이 있으면 잠들지 않고 return busy.
+ *   @next_state해 해당하는 idle을 수행한다.
+ */
 static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev,
               int next_state)
 {
@@ -222,6 +249,10 @@ static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev,
      * The idle task must be scheduled, it is pointless to go to idle, just
      * update no idle residency and return.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - reschedule 요청이 있으면 return busy
+ */
     if (current_clr_polling_and_test()) {
         dev->last_residency_ns = 0;
         local_irq_enable();
@@ -233,6 +264,16 @@ static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev,
      * This function will block until an interrupt occurs and will take
      * care of re-enabling the local interrupts
      */
+
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   governor 결정에 의해 이전에 반환된 유휴 상태를 입력합니다.
+ *   이 기능은 인터럽트가 발생할 때까지 차단되며 로컬 인터럽트를 다시
+ *   활성화합니다. 
+ *
+ * - @next_state해 해당하는 idle을 수행한다.
+ */
     return cpuidle_enter(drv, dev, next_state);
 }
 
@@ -257,6 +298,7 @@ static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev,
  */
 /*
  * IAMROOT, 2023.03.11:
+ * - devicetree/bindings/arm/idle-states.yaml 참고
  * - min-residency-us : 최소 상주 시간. 켜진후 꺼지기 전까지 최소 유지해야할 시간
  * - rk3399.rtsi
  *   idle-states {
@@ -281,6 +323,14 @@ static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev,
  *            };
  *        };
  *
+ * - 1. resched 요청이 있으면 irq enable후 return.
+ *   2. cpuidle driver가 없으면 default idle(wfi) 수행후 return.
+ *   3. suspend-to-idle상황인 경우 s2idle을 지원하는 cpuidle state를 선택해서
+ *      idle 수행.
+ *   4. forced_idle_latency_limit_ns가 있는 경우 이 값을 max로 하여 cpuidle state
+ *      를 선택해서 idle 수행.
+ *   5. 일반적인 경우(윗 상황 들이 아닌 경우) curr governor를 통해서 cpuidle state
+ *      를 찾아서 idle 수행.
  */
 static void cpuidle_idle_call(void)
 {
@@ -313,7 +363,7 @@ static void cpuidle_idle_call(void)
      * - google-translate
      *   RCU 프레임워크는 우리가 유휴 섹션에 들어가고 있다는 것을 알려야 합니다. 따라서
      *   rcu는 더 이상 중요한 섹션을 읽지 않고 유예 기간에 한 단계 더 있습니다.
-     * - cpuidle이 활성화 안된경우 wfi만 한번하고 끝낸다.
+     * - cpuidle이 활성화 안됫거나 driver가 없는경우 wfi만 한번하고 끝낸다.
      */
 
     if (cpuidle_not_available(drv, dev)) {
@@ -354,17 +404,31 @@ static void cpuidle_idle_call(void)
 
         if (idle_should_enter_s2idle()) {
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - deep sleep을 수행한다. 수행이 됬으면 goto exit_idle.
+ *   그게 아니면 최대 sleep으로 cpuidle state를 검색한다.
+ */
             entered_state = call_cpuidle_s2idle(drv, dev);
             if (entered_state > 0)
                 goto exit_idle;
 
             max_latency_ns = U64_MAX;
         } else {
+
+/*
+ * IAMROOT, 2023.03.18:
+ * - forced_idle_latency_limit_ns이하의 cpuidle state로 검색한다.
+ */
             max_latency_ns = dev->forced_idle_latency_limit_ns;
         }
 
         tick_nohz_idle_stop_tick();
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - max_latency_ns이내의 c state를 골라서 idle을 수행한다.
+ */
         next_state = cpuidle_find_deepest_state(drv, dev, max_latency_ns);
         call_cpuidle(drv, dev, next_state);
     } else {
@@ -373,6 +437,12 @@ static void cpuidle_idle_call(void)
         /*
          * Ask the cpuidle framework to choose a convenient idle state.
          */
+
+/*
+ * IAMROOT, 2023.03.18:
+ * - curr governor에서 c state를 구해온다. 만약 tick을 멈추지 말아야되면 stop_tick
+ *   이 false로 update되있을 것이다.
+ */
         next_state = cpuidle_select(drv, dev, &stop_tick);
 
         if (stop_tick || tick_nohz_tick_stopped())
@@ -380,6 +450,10 @@ static void cpuidle_idle_call(void)
         else
             tick_nohz_idle_retain_tick();
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - governor에서 선택된 state로 cpuidle을 수행한다.
+ */
         entered_state = call_cpuidle(drv, dev, next_state);
         /*
          * Give the governor an opportunity to reflect on the outcome
@@ -408,6 +482,14 @@ static void cpuidle_idle_call(void)
  *   일반 유휴 루프 구현
  *
  *   폴링이 지워진 상태로 호출됩니다.
+ *
+ * - 0. resched 요청이 있으면 idle에 진입안하고 자발적 schedule을 수행하러간다.,
+ *   1. cpu가 offline이라면 cpu die로 진입한다.
+ *   2. polling을 해야된다면 cpu_relax()를 polling을 해야되는 원인이 풀릴때까지 
+ *      수행한다.
+ *   3. 그게 아니면 cpuidle driver를 사용해서 idle을 수행한다.
+ *   4. idle이 끝난후 pending된것들을 처리한다.
+ *   5. 그 후 자발적 reschedule한다.
  */
 static void do_idle(void)
 {
@@ -481,6 +563,10 @@ static void do_idle(void)
         if (cpu_idle_force_poll || tick_check_broadcast_expired()) {
             tick_nohz_idle_restart_tick();
             cpu_idle_poll();
+/*
+ * IAMROOT, 2023.03.18:
+ * - poll이 아니면 cpuidle state를 선택해 idle을 수행한다.
+ */
         } else {
             cpuidle_idle_call();
         }
@@ -501,6 +587,8 @@ static void do_idle(void)
  *   것을 알고 이를 PREEMPT_NEED_RESCHED로 전파합니다.
  *
  *   이는 유휴 루프를 폴링하기 위해 상태를 접을 IPI가 없기 때문에 필요합니다.
+ *
+ * - idle이 끝나서 resched을 한번 한다.
  */
     preempt_set_need_resched();
     tick_nohz_idle_exit();
@@ -511,12 +599,25 @@ static void do_idle(void)
      * need_resched() is set while polling is set. That means that clearing
      * polling needs to be visible before doing these things.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   폴링이 설정되어 있는 동안 need_resched()가 설정되면 sched_ttwu_pending()을 
+ *   호출하고 일정을 변경할 것을 약속합니다. 이는 이러한 작업을 수행하기 전에 폴링 
+ *   지우기가 표시되어야 함을 의미합니다.
+ */
     smp_mb__after_atomic();
 
     /*
      * RCU relies on this call to be done outside of an RCU read-side
      * critical section.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papgo 
+ *   RCU는 RCU 읽기측 중요 섹션 외부에서 수행되는 이 호출에 의존합니다.
+ * - 여러 pending에 대해(softirq등) 처리한다.
+ */
     flush_smp_call_function_from_idle();
     schedule_idle();
 
@@ -587,6 +688,8 @@ EXPORT_SYMBOL_GPL(play_idle_precise);
  * - boot up 마지막에서 호출된다.
  *   cpu 0 : start_kernel -> arch_call_rest_init -> rest_init 에서 호출
  *   그외 cpu : secondary_start_kernel 에서 호출
+ * - idle로 진입전 online이 되기 위한 @state처리를 하고 idle을 수행하며
+ *   resched을 기다린다.
  */
 void cpu_startup_entry(enum cpuhp_state state)
 {
@@ -601,6 +704,7 @@ void cpu_startup_entry(enum cpuhp_state state)
  */
 
 #ifdef CONFIG_SMP
+
 static int
 select_task_rq_idle(struct task_struct *p, int cpu, int flags)
 {
@@ -634,6 +738,14 @@ static void set_next_task_idle(struct rq *rq, struct task_struct *next, bool fir
 }
 
 #ifdef CONFIG_SMP
+
+/*
+ * IAMROOT, 2023.03.18:
+ * - start_kernel()->rest_init()->kernel_init thread생성
+ *   kernel_init -> kernel_init_freeable() -> smp_init()-> 
+ *   idle_threads_init()->idle_init() - cpu for돌면서 fork_idle()->init_idle()에서
+ *   idle이 설정됬다. 즉 booting cpu에 의해 각 cpu마다 idle task가 한개씩 생성된다.
+ */
 static struct task_struct *pick_task_idle(struct rq *rq)
 {
     return rq->idle;
diff --git a/kernel/smp.c b/kernel/smp.c
index 73b0ed941f05..a4ce3363b00f 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -681,6 +681,11 @@ static void flush_smp_call_function_queue(bool warn_cpu_offline)
               smp_processor_id(), CFD_SEQ_HDLEND);
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - softirq가 pending되있었다면 실행한다.
+ * - TODO
+ */
 void flush_smp_call_function_from_idle(void)
 {
     unsigned long flags;
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 4832c3532528..48bd75228e8a 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1302,6 +1302,10 @@ void clock_was_set_delayed(void)
  * or in the case of s2idle from tick_unfreeze() to ensure that the
  * hrtimers are up to date.
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - hrtimer retrigger
+ */
 void hrtimers_resume_local(void)
 {
     lockdep_assert_irqs_disabled();
diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c
index c8dbdf6b0888..7d9b11e55ae9 100644
--- a/kernel/time/sched_clock.c
+++ b/kernel/time/sched_clock.c
@@ -405,6 +405,8 @@ void __init generic_sched_clock_init(void)
  *   이 함수는 sched_clock()의 크리티컬 섹션에서만 호출해야 합니다.
  *   'epoch_cyc'의 올바른 복사본을 관찰하기 위해 중요한 섹션 끝에 있는
  *   read_seqcount_retry()에 의존합니다.
+ *
+ * - suspend시 사용하는 clock read.
  */
 static u64 notrace suspended_sched_clock_read(void)
 {
@@ -413,6 +415,11 @@ static u64 notrace suspended_sched_clock_read(void)
     return cd.read_data[seq & 1].epoch_cyc;
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - sched clock timer를 멈추면서 callback을 suspended_sched_clock_read로
+ *   바꾼다.
+ */
 int sched_clock_suspend(void)
 {
     struct clock_read_data *rd = &cd.read_data[0];
@@ -424,6 +431,11 @@ int sched_clock_suspend(void)
     return 0;
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - sched clock timer를 다시 동작시키면서 callback을
+ *   cd.actual_read_sched_clock로 변경한다.
+ */
 void sched_clock_resume(void)
 {
     struct clock_read_data *rd = &cd.read_data[0];
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index cfab35393753..78a11fc4f26c 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -1003,6 +1003,10 @@ static void broadcast_shutdown_local(struct clock_event_device *bc,
     clockevents_switch_state(dev, CLOCK_EVT_STATE_SHUTDOWN);
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - TODO
+ */
 static int ___tick_broadcast_oneshot_control(enum tick_broadcast_state state,
                          struct tick_device *td,
                          int cpu)
@@ -1141,6 +1145,16 @@ static int ___tick_broadcast_oneshot_control(enum tick_broadcast_state state,
     return ret;
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * @return < 0 : @td나 wd둘중하나이상이 oneshot이 아니다.
+ *         0   : 아래 주석 참고
+ * - TICK_BROADCAST_ENTER
+ *   @dev의 oneshot은 정지, @wd는 oneshot으로 하여 next_event로 program한다.
+ *   즉 @dev의 next_event시간에 @cpu를 깨우두록 @wd에서 요청을 한다.
+ * - TICK_BROADCAST_EXIT
+ *   @wd가 oneshot이 아닌지만 확인한다.
+ */
 static int tick_oneshot_wakeup_control(enum tick_broadcast_state state,
                        struct tick_device *td,
                        int cpu)
@@ -1170,14 +1184,31 @@ static int tick_oneshot_wakeup_control(enum tick_broadcast_state state,
     return 0;
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * @return 0 : 성공
+ *
+ * - @state가 TICK_BROADCAST_ENTER일 경우 this cpu가 next_event에 일어나도록
+ *   oneshot wakeup device에 맡겨 깨우도록 한다.
+ *   wakeup device가 없거나 oneshot이 아닌 경우 braodcast를 통해서 시도해본다.
+ */
 int __tick_broadcast_oneshot_control(enum tick_broadcast_state state)
 {
     struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
     int cpu = smp_processor_id();
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - @state가 TICK_BROADCAST_ENTER인 경우 wakeup device에 next_event에 
+ *   this cpu가 깨우도록 한다.
+ */
     if (!tick_oneshot_wakeup_control(state, td, cpu))
         return 0;
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - 위에서 실행이 안된경우. 즉 oneshot이 아닌 경우 braodcast로 동작한다.
+ */
     if (tick_broadcast_device.evtdev)
         return ___tick_broadcast_oneshot_control(state, td, cpu);
 
@@ -1185,6 +1216,10 @@ int __tick_broadcast_oneshot_control(enum tick_broadcast_state state)
      * If there is no broadcast or wakeup device, tell the caller not
      * to go into deep idle.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - broadcast도 아니고 wakeup oneshot device도 아닌 경우.
+ */
     return -EBUSY;
 }
 
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 9da300c1e1cf..37896f5c3358 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -664,6 +664,21 @@ void tick_check_new_device(struct clock_event_device *newdev)
  * required here because the local clock event device cannot go away
  * under us.
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *  tick_broadcast_oneshot_control - 브로드캐스트 원샷 모드 시작/종료 
+ *  @state: 대상 상태(들어가기/나가기) 시스템은 영향을 받는 장치가 중지될 
+ *  수 있는 상태에 들어가거나 나갑니다. 성공 시 0을 반환하고, CPU가 웨이크업을 
+ *  브로드캐스트하는 데 사용되는 경우 -EBUSY를 반환합니다.
+ *
+ *  인터럽트가 비활성화된 상태에서 호출되므로 로컬 시계 이벤트 장치가 우리 
+ *  아래에서 사라질 수 없기 때문에 clockevents_lock이 필요하지 않습니다.
+ *
+ *  - @state가 TICK_BROADCAST_ENTER이라면 C3STOP을 지원 한다면 정지를 시킨후 
+ *  oneshot wakeup device에 next_event에 this cpu를 깨우도록 맡긴다. 
+ *  그게 아니면 braodcast에서 맡겨 본다.
+ */
 int tick_broadcast_oneshot_control(enum tick_broadcast_state state)
 {
     struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
@@ -721,6 +736,10 @@ void tick_shutdown(unsigned int cpu)
  *
  * No locks required. Nothing can change the per cpu device.
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - tick device를 멈춘다.
+ */
 void tick_suspend_local(void)
 {
     struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
@@ -735,12 +754,21 @@ void tick_suspend_local(void)
  *
  * No locks required. Nothing can change the per cpu device.
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - tick device enable.
+ */
 void tick_resume_local(void)
 {
     struct tick_device *td = this_cpu_ptr(&tick_cpu_device);
     bool broadcast = tick_resume_check_broadcast();
 
     clockevents_tick_resume(td->evtdev);
+/*
+ * IAMROOT, 2023.03.18:
+ * - tick device는 처음에 periodic으로 동작하다 oneshot으로 변경된다.
+ *   그에 따른 처리들.
+ */
     if (!broadcast) {
         if (td->mode == TICKDEV_MODE_PERIODIC)
             tick_setup_periodic(td->evtdev, 0);
@@ -798,11 +826,32 @@ static unsigned int tick_freeze_depth;
  * Call with interrupts disabled.  Must be balanced with %tick_unfreeze().
  * Interrupts must not be enabled before the subsequent %tick_unfreeze().
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   tick_freeze - 로컬 틱 및 (아마도) 시간 기록을 중지합니다.
+ *
+ *   이것이 기능을 실행하는 마지막 온라인 CPU인지 확인하고 그렇다면 
+ *   시간 기록을 일시 중단합니다. 그렇지 않으면 로컬 틱을 일시 중지합니다.
+ *
+ *   인터럽트가 비활성화된 상태에서 호출합니다. %tick_unfreeze()로 균형을 
+ *   맞춰야 합니다.
+ *
+ *   후속 %tick_unfreeze() 전에 인터럽트를 활성화하면 안 됩니다.
+ *
+ *  - 기본적으로 local tick device를 멈춰 sched tick을 정지시킨다.
+ *    만약 모든 cpu가 멈추게되면 system을 suspend한다.
+ */
 void tick_freeze(void)
 {
     raw_spin_lock(&tick_freeze_lock);
 
     tick_freeze_depth++;
+/*
+ * IAMROOT, 2023.03.18:
+ * - tick freez가 전체 cpu인경우 system을 suspend한다. 그게 아니면
+ *   local cpu만 suspend한다.
+ */
     if (tick_freeze_depth == num_online_cpus()) {
         trace_suspend_resume(TPS("timekeeping_freeze"),
                      smp_processor_id(), true);
@@ -825,6 +874,11 @@ void tick_freeze(void)
  * Call with interrupts disabled.  Must be balanced with %tick_freeze().
  * Interrupts must not be enabled after the preceding %tick_freeze().
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - 기본적으로 local tick device를 resume 하여 sched tick을 다시 start한다.
+ *   만약 모든 cpu가 freeze였으면 system resume한다.
+ */
 void tick_unfreeze(void)
 {
     raw_spin_lock(&tick_freeze_lock);
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 82570425f7b7..47a0975b0eeb 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -725,12 +725,23 @@ static void tick_nohz_update_jiffies(ktime_t now)
 /*
  * Updates the per-CPU time idle statistics counters
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - @ts->idle_active에 iowait상황에 따른 시간 가산후 idle_entrytime을 갱신한다.
+ */
 static void
 update_ts_time_stats(int cpu, struct tick_sched *ts, ktime_t now, u64 *last_update_time)
 {
     ktime_t delta;
 
     if (ts->idle_active) {
+/*
+ * IAMROOT, 2023.03.18:
+ * - iowait cpu 
+ *   before idle entrytime을 iowait_sleeptime에 가산
+ * - 그게 아니면
+ *   before idle entrytime을 idle_sleeptime에 가산
+ */
         delta = ktime_sub(now, ts->idle_entrytime);
         if (nr_iowait_cpu(cpu) > 0)
             ts->iowait_sleeptime = ktime_add(ts->iowait_sleeptime, delta);
@@ -744,6 +755,10 @@ update_ts_time_stats(int cpu, struct tick_sched *ts, ktime_t now, u64 *last_upda
 
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - nohz 시스템에서 stop idle에 대한 사후 처리를 한다.
+ */
 static void tick_nohz_stop_idle(struct tick_sched *ts, ktime_t now)
 {
     update_ts_time_stats(smp_processor_id(), ts, now, NULL);
@@ -845,6 +860,10 @@ u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time)
 }
 EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us);
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - tick nohz timer  cancle후 restart.
+ */
 static void tick_nohz_restart(struct tick_sched *ts, ktime_t now)
 {
     hrtimer_cancel(&ts->sched_timer);
@@ -864,6 +883,11 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now)
      * Reset to make sure next tick stop doesn't get fooled by past
      * cached clock deadline.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   다음 틱 중지가 캐시된 클록 데드라인을 지나서 속지 않도록 재설정하십시오.
+ */
     ts->next_tick = 0;
 }
 
@@ -1035,6 +1059,10 @@ static void tick_nohz_stop_tick(struct tick_sched *ts, int cpu)
     }
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - timer stop 
+ */
 static void tick_nohz_retain_tick(struct tick_sched *ts)
 {
     ts->timer_expires_base = 0;
@@ -1050,6 +1078,10 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts, int cpu)
 }
 #endif /* CONFIG_NO_HZ_FULL */
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - @now로 tick을 update 및 tick_nohz_restart.
+ */
 static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now)
 {
     /* Update jiffies first */
@@ -1070,6 +1102,10 @@ static void tick_nohz_restart_sched_tick(struct tick_sched *ts, ktime_t now)
     tick_nohz_restart(ts, now);
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - 기본 config에 NO HZ FULL이 포함되잇진 않는다.
+ */
 static void __tick_nohz_full_update_tick(struct tick_sched *ts,
                      ktime_t now)
 {
@@ -1231,6 +1267,10 @@ void tick_nohz_idle_stop_tick(void)
     __tick_nohz_idle_stop_tick(this_cpu_ptr(&tick_cpu_sched));
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - tick nohz idle 에서 tick을 유지한다.
+ */
 void tick_nohz_idle_retain_tick(void)
 {
     tick_nohz_retain_tick(this_cpu_ptr(&tick_cpu_sched));
@@ -1310,6 +1350,15 @@ bool tick_nohz_idle_got_tick(void)
  *
  * Called from power state control code with interrupts disabled
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   tick_nohz_get_next_hrtimer - 먼저 만료되는 hrtimer 또는 틱의 다음
+ *   만료 시간을 반환합니다. 틱이 중지된 경우 다음 hrtimer를 반환합니다.
+ *   인터럽트가 비활성화된 전원 상태 제어 코드에서 호출됩니다. 
+ *
+ * - 가장 먼저 완료될 시간을 알아온다.
+ */
 ktime_t tick_nohz_get_next_hrtimer(void)
 {
     return __this_cpu_read(tick_cpu_device.evtdev)->next_event;
@@ -1383,6 +1432,10 @@ unsigned long tick_nohz_get_idle_calls(void)
     return ts->idle_calls;
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - idle이 종료되는 시각을 기록한다.
+ */
 static void tick_nohz_account_idle_time(struct tick_sched *ts,
                     ktime_t now)
 {
@@ -1420,6 +1473,10 @@ void tick_nohz_idle_restart_tick(void)
     }
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - tick nohz restart를 수행한다.
+ */
 static void tick_nohz_idle_update_tick(struct tick_sched *ts, ktime_t now)
 {
     if (tick_nohz_full_cpu(smp_processor_id()))
@@ -1437,6 +1494,16 @@ static void tick_nohz_idle_update_tick(struct tick_sched *ts, ktime_t now)
  * This also exit the RCU extended quiescent state. The CPU
  * can use RCU again after this function is called.
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   tick_nohz_idle_exit - 유휴 작업에서 유휴 틱을 다시 시작합니다.
+ *   CPU가 유휴 상태에서 깨어날 때 유휴 틱을 다시 시작합니다. 
+ *   이것은 또한 RCU 확장 정지 상태를 종료합니다. CPU는 이 함수가 
+ *   호출된 후 RCU를 다시 사용할 수 있습니다.
+ *
+ * - idle이 끝나면서 nohz에서 해야될일을 수행한다.
+ */
 void tick_nohz_idle_exit(void)
 {
     struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 74502c14b49c..9f69e82c96c9 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1780,6 +1780,11 @@ void timekeeping_inject_sleeptime64(const struct timespec64 *delta)
 /**
  * timekeeping_resume - Resumes the generic timekeeping subsystem.
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - linux timer enable
+ * - PASS`
+ */
 void timekeeping_resume(void)
 {
     struct timekeeper *tk = &tk_core.timekeeper;
@@ -1842,6 +1847,11 @@ void timekeeping_resume(void)
     timerfd_resume();
 }
 
+/*
+ * IAMROOT, 2023.03.18:
+ * - linux system이 관리하는 time을 멈춘다.
+ * - PASS
+ */
 int timekeeping_suspend(void)
 {
     struct timekeeper *tk = &tk_core.timekeeper;
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 1d2eb8409a90..2207154bed40 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -2267,6 +2267,10 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem)
  *
  * Called with interrupts disabled
  */
+/*
+ * IAMROOT, 2023.03.18:
+ * - standard의 idle을 false로 하여 nohz를 푼다.
+ */
 void timer_clear_idle(void)
 {
     struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);
@@ -2277,6 +2281,13 @@ void timer_clear_idle(void)
      * sending the IPI a few instructions smaller for the cost of taking
      * the lock in the exit from idle path.
      */
+/*
+ * IAMROOT, 2023.03.18:
+ * - papago
+ *   우리는 이것을 잠금 해제합니다. 최악의 결과는 무의미한 IPI를 보내는 원격 
+ *   인큐(enqueue)이지만, 잠금을 사용하면 유휴 경로에서 종료할 때 잠금을 사용하는 
+ *   비용에 비해 IPI를 보내는 데 필요한 몇 가지 명령이 더 작아집니다. 
+ */
     base->is_idle = false;
 }
 #endif

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 617
202 [커널 18차] 106주차 kkr 2023.06.03 59
201 [커널 20차] 3주차 김희찬 2023.06.03 69
200 [커널 19차] 52 ~ 53 주차 Min 2023.05.27 54
199 [커널 20차] 2주차 김희찬 2023.05.20 131
198 [커널 19차] 51 주차 Min 2023.05.13 45
197 [커널 20차] 1주차 김희찬 2023.05.13 182
196 [커널 18차] 102주차 kkr 2023.05.07 70
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 82
191 [커널 18차] 99주차 kkr 2023.04.16 75
190 [커널 19차] 47 주차 Min 2023.04.15 41
189 [커널 19차] 45, 46 주차 Min 2023.04.10 59
188 [커널 19차] 43, 44 주차 이태백 2023.03.26 184
» [커널 18차] 95주차 kkr 2023.03.20 119
186 [커널 19차] 41 주차 이태백 2023.03.04 100
185 [커널 18차] 93주차 kkr 2023.03.04 53
184 [커널 18차] 91주차 kkr 2023.02.18 94
183 [커널 19차] 39 주차 Min 2023.02.18 53
XE Login