[커널 18차] 88주차

2023.01.28 22:13

kkr 조회 수:55

__schdule() 끝

 

git log : https://github.com/iamroot18/5.10/commit/f49eb8f211658cf0dc26cc9b0bb04c2d4370a09f

 

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 57069bb47a93..9de76064b117 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -949,6 +949,11 @@ static inline bool system_uses_hw_pan(void)
         cpus_have_const_cap(ARM64_HAS_PAN);
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * @return true : sw pan을 써야되는 경우
+ * - PAN을 써야되는데 hw pan이 지원 여부 확인.
+ */
 static inline bool system_uses_ttbr0_pan(void)
 {
     return IS_ENABLED(CONFIG_ARM64_SW_TTBR0_PAN) &&
diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h
index 36a6b2863a2e..c29e1be0c5be 100644
--- a/arch/arm64/include/asm/mmu_context.h
+++ b/arch/arm64/include/asm/mmu_context.h
@@ -26,6 +26,13 @@
 
 extern bool rodata_full;
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - pid 저장용도.
+ * - CONTEXTIDR_EL1, Context ID Register (EL1) 
+ *   AArch64 상태에서 CONTEXTIDR_EL1은 ASID와 독립적이며 EL1&0 변환 체제의 
+ *   경우 TTBR0_EL1 또는 TTBR1_EL1이 ASID를 보유합니다.
+ */
 static inline void contextidr_thread_switch(struct task_struct *next)
 {
     if (!IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR))
@@ -278,12 +285,22 @@ enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
     update_saved_ttbr0(tsk, &init_mm);
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - next가 kernel : 교체안한다. ttbr0를 rserved로 set.
+ *   next가 user   : @next로 mm교체.
+ */
 static inline void __switch_mm(struct mm_struct *next)
 {
     /*
      * init_mm.pgd does not contain any user mappings and it is always
      * active for kernel addresses in TTBR1. Just set the reserved TTBR0.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - next가 kernel이면 kernel의 user접근을 막기위해
+ *   ttbr0를 비운다.
+ */
     if (next == &init_mm) {
         cpu_set_reserved_ttbr0();
         return;
@@ -292,6 +309,10 @@ static inline void __switch_mm(struct mm_struct *next)
     check_and_switch_context(next);
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - @next로 mm교체
+ */
 static inline void
 switch_mm(struct mm_struct *prev, struct mm_struct *next,
       struct task_struct *tsk)
@@ -305,6 +326,13 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
      * ASID has changed since the last run (following the context switch
      * of another thread of the same process).
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   이전 값이 아직 초기화되지 않았거나(activate_mm 호출자) 마지막 실행 
+ *   이후 ASID가 변경되었을 수 있으므로 예약된 작업의 저장된 TTBR0_EL1을 
+ *   업데이트합니다(동일한 프로세스의 다른 스레드의 컨텍스트 전환 후).
+ */
     update_saved_ttbr0(tsk, next);
 }
 
diff --git a/arch/arm64/include/asm/pointer_auth.h b/arch/arm64/include/asm/pointer_auth.h
index efb098de3a84..52879d7e23ef 100644
--- a/arch/arm64/include/asm/pointer_auth.h
+++ b/arch/arm64/include/asm/pointer_auth.h
@@ -125,6 +125,10 @@ static __always_inline void ptrauth_enable(void)
                          PR_PAC_ENABLED_KEYS_MASK);    \
     } while (0)
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - PASS
+ */
 #define ptrauth_thread_switch_user(tsk)                                        \
     ptrauth_keys_install_user(&(tsk)->thread.keys_user)
 
diff --git a/arch/arm64/include/asm/preempt.h b/arch/arm64/include/asm/preempt.h
index 4529230e5f3a..30964b7f7b78 100644
--- a/arch/arm64/include/asm/preempt.h
+++ b/arch/arm64/include/asm/preempt.h
@@ -47,6 +47,10 @@ static inline void set_preempt_need_resched(void)
     current_thread_info()->preempt.need_resched = 0;
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - need_resched clear(1로 set).
+ */
 static inline void clear_preempt_need_resched(void)
 {
     current_thread_info()->preempt.need_resched = 1;
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index a9319d11a998..076f7c035f71 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -1447,6 +1447,17 @@ SYM_DATA_END(__entry_tramp_data_start)
  * Previous and next are guaranteed not to be the same.
  *
  */
+
+
+/*
+ * IAMROOT, 2023.01.28: 
+ * - x0 : prev, x1 : next (__switch_to() 참고)
+ * - 일부 레지스터만 prev에 backup / next에 restore.
+ *   thread.cpu_context에 backup한다.
+ * - sp_el0에 x1(next)가 등록된다.
+ *   ret을 통해 x0가(prev) return 된다.
+ */
+
 SYM_FUNC_START(cpu_switch_to)
     mov    x10, #THREAD_CPU_CONTEXT
     add    x8, x0, x10
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index c0b00522be2d..5a38a1f88680 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1035,6 +1035,11 @@ void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs)
                current);
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - PASS
+ * - fpsimd 관련 처리
+ */
 void fpsimd_thread_switch(struct task_struct *next)
 {
     bool wrong_task, wrong_cpu;
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 712e97c03e54..b2bec25dfc90 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -906,6 +906,11 @@ NOKPROBE_SYMBOL(reinstall_suspended_bps);
 /*
  * Context-switcher for restoring suspended breakpoints.
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - PASS
+ *   hw debug
+ */
 void hw_breakpoint_thread_switch(struct task_struct *next)
 {
     /*
diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index e5e801bc5312..f06bd14c5703 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -192,6 +192,11 @@ void mte_thread_init_user(void)
     set_mte_ctrl(current, 0);
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - PASS
+ * - MTE
+ */
 void mte_thread_switch(struct task_struct *next)
 {
     if (!system_supports_mte())
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 1129c5a80a96..d2291d4c267e 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -394,6 +394,12 @@ void tls_preserve_current_state(void)
     *task_user_tls(current) = read_sysreg(tpidr_el0);
 }
 
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - PASS
+ * - tls(thread local storage)
+ */
 static void tls_thread_switch(struct task_struct *next)
 {
     tls_preserve_current_state();
@@ -410,6 +416,11 @@ static void tls_thread_switch(struct task_struct *next)
  * Force SSBS state on context-switch, since it may be lost after migrating
  * from a CPU which treats the bit as RES0 in a heterogeneous system.
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - PASS
+ * - SSBS처리
+ */
 static void ssbs_thread_switch(struct task_struct *next)
 {
     /*
@@ -447,6 +458,10 @@ static void ssbs_thread_switch(struct task_struct *next)
  */
 DEFINE_PER_CPU(struct task_struct *, __entry_task);
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 동작할 task(next)를 __entry_task에 기록한다.
+ */
 static void entry_task_switch(struct task_struct *next)
 {
     __this_cpu_write(__entry_task, next);
@@ -459,6 +474,10 @@ static void entry_task_switch(struct task_struct *next)
  * - disable access when switching from a 64bit task to a 32bit task
  * - enable access when switching from a 32bit task to a 64bit task
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - PASS
+ */
 static void erratum_1418040_thread_switch(struct task_struct *prev,
                       struct task_struct *next)
 {
@@ -490,6 +509,16 @@ static void erratum_1418040_thread_switch(struct task_struct *prev,
  * sctlr_user must be made in the same preemption disabled block so that
  * __switch_to() does not see the variable update before the SCTLR_EL1 one.
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   __switch_to()는 current->thread.sctlr_user를 최적화로 확인합니다. 따라서 
+ *   이 함수는 선점을 비활성화한 상태에서 호출해야 하며 sctlr_user에 대한 
+ *   업데이트는 동일한 선점 비활성화 블록에서 수행해야 __switch_to()가 
+ *   SCTLR_EL1 이전에 변수 업데이트를 볼 수 없습니다.
+ *
+ *  - sctlr_el1을 수정하면 isb를 무조건해줘야한다.
+ */
 void update_sctlr_el1(u64 sctlr)
 {
     /*
@@ -505,6 +534,13 @@ void update_sctlr_el1(u64 sctlr)
 /*
  * Thread switching.
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - 1. __entry_task에 next기록한다.
+ *   2. dsb(ish)수행한다.
+ *   3. sctlr_el1이 변경됬으면 갱신한다.
+ *   4. cpu_switch_to 실행.
+ */
 __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
                 struct task_struct *next)
 {
@@ -525,6 +561,14 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
      * This full barrier is also required by the membarrier system
      * call.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   스레드가 다른 CPU로 마이그레이션되는 경우 이 CPU에서 보류 중인 TLB 또는 
+ *   캐시 유지 관리를 완료하십시오. 
+ *   이 전체 장벽은 membarrier 시스템 호출에도 필요합니다.
+ * - tlb cache등을 flush 한 경우에 완료될때까지 기다린다.
+ */
     dsb(ish);
 
     /*
@@ -534,6 +578,10 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
      */
     mte_thread_switch(next);
     /* avoid expensive SCTLR_EL1 accesses if no change */
+/*
+ * IAMROOT, 2023.01.28:
+ * - sctlr_user가 다르다면 sctlr_el1을 변경되는 sctlr_user로 바꾼다.
+ */
     if (prev->thread.sctlr_user != next->thread.sctlr_user)
         update_sctlr_el1(next->thread.sctlr_user);
 
diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c
index dce56dac76f9..e3047bae4c80 100644
--- a/arch/arm64/mm/context.c
+++ b/arch/arm64/mm/context.c
@@ -17,9 +17,21 @@
 #include <asm/smp.h>
 #include <asm/tlbflush.h>
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 8bit or 16bit
+ *   8bit일 경우 256
+ *   16bit일 경우 65536
+ */
 static u32 asid_bits;
 static DEFINE_RAW_SPINLOCK(cpu_asid_lock);
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 8bit일 경우
+ *   0 ~ 0x100, 0x200, 0x300..
+ * - base asid
+ */
 static atomic64_t asid_generation;
 static unsigned long *asid_map;
 
@@ -32,6 +44,11 @@ static unsigned long nr_pinned_asids;
 static unsigned long *pinned_asid_map;
 
 #define ASID_MASK        (~GENMASK(asid_bits - 1, 0))
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - asid 단위.
+ */
 #define ASID_FIRST_VERSION    (1UL << asid_bits)
 
 #define NUM_USER_ASIDS        ASID_FIRST_VERSION
@@ -76,6 +93,12 @@ void verify_cpu_asid_bits(void)
     }
 }
 
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - KPTI asid bits set.
+ *   0xaa로 @map을 채운다.
+ */
 static void set_kpti_asid_bits(unsigned long *map)
 {
     unsigned int len = BITS_TO_LONGS(NUM_USER_ASIDS) * sizeof(unsigned long);
@@ -85,9 +108,22 @@ static void set_kpti_asid_bits(unsigned long *map)
      * is set, then the ASID will map only userspace. Thus
      * mark even as reserved for kernel.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   KPTI 커널/사용자 ASID가 쌍으로 할당된 경우 하단 비트는 두 가지를 구분합니다.
+ *   설정되어 있으면 ASID는 사용자 공간만 매핑합니다. 따라서 커널용으로 예약된 
+ *   것으로 표시합니다.
+ */
     memset(map, 0xaa, len);
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - pinned_asid_map이 있다면 pinned_asid_map를 asid_map에 복사한다.
+ *   kpti를 사용하는경우 asid_map을 0xaa로 채운다.
+ *   그것도 아니라면 asid_map을 0로 clear한다.
+ */
 static void set_reserved_asid_bits(void)
 {
     if (pinned_asid_map)
@@ -98,9 +134,23 @@ static void set_reserved_asid_bits(void)
         bitmap_clear(asid_map, 0, NUM_USER_ASIDS);
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 세대(generation)이 바뀌었는지 확인ㄴ한다.
+ * - 앞자리가 바뀐지를 확인하는 개념.
+ * - ex) asid 0x503, asid_generation = 0x400, bit = 8bit
+ *   결과 false.
+ */
 #define asid_gen_match(asid) \
     (!(((asid) ^ atomic64_read(&asid_generation)) >> asid_bits))
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 1. asid_map clear
+ *   2. reserved_asids에 마지막에 사용했던 active_asids를 기록. 
+ *   3. 마지막 사용했던 asid를 asid_map에 기록.
+ *   4. 모든 cpu에 tlb flush pending 등록.
+ */
 static void flush_context(void)
 {
     int i;
@@ -109,6 +159,10 @@ static void flush_context(void)
     /* Update the list of reserved ASIDs and the ASID bitmap. */
     set_reserved_asid_bits();
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - pcpu active_asids를 0으로 clear하면서 이전값을 asid로 가져온다.
+ */
     for_each_possible_cpu(i) {
         asid = atomic64_xchg_relaxed(&per_cpu(active_asids, i), 0);
         /*
@@ -118,6 +172,15 @@ static void flush_context(void)
          * ASID, as this is the only trace we have of
          * the process it is still running.
          */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   이 CPU가 이미 롤오버를 겪었지만 그 동안 다른 작업을 실행하지 
+ *   않은 경우 예약된 ASID를 보존해야 합니다. 이것이 여전히 실행 
+ *   중인 프로세스에 대한 유일한 추적이기 때문입니다.
+ * - 롤오버가 된 경우 reserved_asids를 asid로 가져온다.
+ * - 맨 마지막의 asid를 reserved_asids로 등록한다.
+ */
         if (asid == 0)
             asid = per_cpu(reserved_asids, i);
         __set_bit(asid2idx(asid), asid_map);
@@ -128,9 +191,21 @@ static void flush_context(void)
      * Queue a TLB invalidation for each CPU to perform on next
      * context-switch
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - next context switch에 tlb flush가 되도록 모든 cpu에 설정한다.
+ *   해당 cpu들은 context switch일때 local tlb flush를 할것이다.
+ */
     cpumask_setall(&tlb_flush_pending);
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - pcpu reserved_asids에 @asid가 있다면 hit로 하고, newasid를 
+ *   reserved_asids로 등록한다.
+ *   버려지게 될 asid가 이미 reserved로 등록되있다면 바뀌게될
+ *   newasid로 전환해줘야하기때문이다.
+ */
 static bool check_update_reserved_asid(u64 asid, u64 newasid)
 {
     int cpu;
@@ -145,6 +220,16 @@ static bool check_update_reserved_asid(u64 asid, u64 newasid)
      * so could result in us missing the reserved ASID in a future
      * generation.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   일치를 찾는 예약된 ASID 세트를 반복합니다. 
+ *   하나를 찾으면 newasid(즉, 현재 세대의 동일한 ASID)를 사용하도록 
+ *   mm을 업데이트할 수 있지만 루프를 조기에 종료할 수는 없습니다. 
+ *   mm. 그렇게 하지 않으면 미래 세대에서 예약된 ASID가 누락될 수 
+ *   있습니다.
+. 
+ */
     for_each_possible_cpu(cpu) {
         if (per_cpu(reserved_asids, cpu) == asid) {
             hit = true;
@@ -155,19 +240,49 @@ static bool check_update_reserved_asid(u64 asid, u64 newasid)
     return hit;
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - asid를 generation을 붙여 newasid를 만든다.
+ *   1. newasid가 reserved_asid에 있으면 reserved_asids를 사용한다.
+ *   2. 요청한 asid가 asid_map에서 비어있는경우 해당자리를 사용한다.
+ *   3. 요청한 자리가 asid_map에서 이미 사용중인경우 cur_idx부터
+ *      빈자리를 찾아서 새로 asid를 구해온다.
+ *   4. asid_map이 full인경우 generation을 증가시키고 
+ *      모든 cpu에 대해 flush tlb pending후 asid_map을 새로 설정하여 다시 
+ *      asid를 가져온다.
+ */
 static u64 new_context(struct mm_struct *mm)
 {
     static u32 cur_idx = 1;
     u64 asid = atomic64_read(&mm->context.id);
     u64 generation = atomic64_read(&asid_generation);
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 최초가 아니면
+ */
     if (asid != 0) {
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - 세대(앞자리) + mask값.
+ *   ex) generation = 0x300, asid = 0x150인경우 
+ *       newasid = 0x350
+ */
         u64 newasid = generation | (asid & ~ASID_MASK);
 
         /*
          * If our current ASID was active during a rollover, we
          * can continue to use it and this was just a false alarm.
          */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   롤오버 중에 현재 ASID가 활성화된 경우 계속 사용할 수 있으며 
+ *   이는 잘못된 경보일 뿐입니다.
+ * - reserved_asids에 asid가 있는지 확인한다. asid가 있었다면 
+ *   newasid로 바뀌고 return한다.
+ */
         if (check_update_reserved_asid(asid, newasid))
             return newasid;
 
@@ -176,6 +291,13 @@ static u64 new_context(struct mm_struct *mm)
          * takes priority, because even if it is also pinned, we need to
          * update the generation into the reserved_asids.
          */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *  고정되어 있으면 계속 사용할 수 있습니다. reserved도 고정된 경우에도 
+ *  reserved_asids로 세대를 업데이트해야 하기 때문에 reserved가 우선 
+ *  순위입니다.
+ */
         if (refcount_read(&mm->context.pinned))
             return newasid;
 
@@ -183,8 +305,21 @@ static u64 new_context(struct mm_struct *mm)
          * We had a valid ASID in a previous life, so try to re-use
          * it if possible.
          */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   전생에 유효한 ASID가 있었으므로 가능하면 다시 사용하십시오.
+ * - asid_map에 asid에 이미 set되있었는지 검사하면서 set한다.
+ *   사용중이 아니라면 return newasid.
+ */
         if (!__test_and_set_bit(asid2idx(asid), asid_map))
             return newasid;
+    
+/*
+ * IAMROOT, 2023.01.28:
+ * -  이 부분까지왔다면 fork등의 이유로 누군가가 asid_map의 asid자리를
+ *    차지한 상태가된다.
+ */
     }
 
     /*
@@ -194,15 +329,34 @@ static u64 new_context(struct mm_struct *mm)
      * a reserved TTBR0 for the init_mm and we allocate ASIDs in even/odd
      * pairs.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   무료 ASID를 할당합니다. 찾을 수 없는 경우 현재 활성 ASID를 기록하고 
+ *   TLB를 플러시가 필요한 것으로 표시합니다. init_mm에 대해 예약된 TTBR0을
+ *   설정할 때 ASID #0을 사용하고 짝수/홀수 쌍으로 ASID를 할당하므로 
+ *   항상 ASID #2(색인 1)부터 계산합니다.
+ *
+ * - asid_map의 첫 zero를 찾는다. 찾아졌다면 return.
+ */
     asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, cur_idx);
     if (asid != NUM_USER_ASIDS)
         goto set_asid;
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - asid_map이 가득 찻다면 asid_generation을 update하고, asid_map을 새로
+ *   설정한다.
+ */
     /* We're out of ASIDs, so increment the global generation count */
     generation = atomic64_add_return_relaxed(ASID_FIRST_VERSION,
                          &asid_generation);
     flush_context();
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 새로설정된 asid_map에서 asid를 얻어온다.
+ */
     /* We have more ASIDs than CPUs, so this will always succeed */
     asid = find_next_zero_bit(asid_map, NUM_USER_ASIDS, 1);
 
@@ -212,6 +366,18 @@ static u64 new_context(struct mm_struct *mm)
     return idx2asid(asid) | generation;
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 상황에따라 fastpath / slowpath로 동작한다.
+ *   1. fastpath 조건.
+ *     - active_asids가 0이 아니다
+ *     - 세대가 같다.
+ *     - active_asids update가 성공.
+ *   2. fastpath 실패시 slowpath로 동작한다. 
+ *      실패 조건에따라 asid를 새로 얻어올수 있다.
+ *   3. tlb flush pending조건이 있으면 수행한다.
+ *   4. mm을 교체한다.
+ */
 void check_and_switch_context(struct mm_struct *mm)
 {
     unsigned long flags;
@@ -221,6 +387,11 @@ void check_and_switch_context(struct mm_struct *mm)
     if (system_supports_cnp())
         cpu_set_reserved_ttbr0();
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - asid + 가상주소로 물리주소를 매핑하는 식으로 사용한다.
+ *   pid를 특수한 방식으로 가공하여 asid를 만듣나.
+ */
     asid = atomic64_read(&mm->context.id);
 
     /*
@@ -237,24 +408,72 @@ void check_and_switch_context(struct mm_struct *mm)
      *   relaxed xchg in flush_context will treat us as reserved
      *   because atomic RmWs are totally ordered for a given location.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   여기서 메모리 순서는 미묘합니다.
+ *   active_asids가 0이 아니고 ASID가 현재 세대와 일치하는 경우 완화된 
+ *   cmpxchg로 active_asids 항목을 업데이트합니다. 동시 롤오버가 있는 
+ *   레이싱은 다음 중 하나를 의미합니다.
+ *
+ *   - 우리는 cmpxchg에서 0을 되찾고 잠금을 기다리게 됩니다. 잠금을 
+ *   해제하면 롤오버와 동기화되므로 업데이트된 세대를 확인해야 합니다.
+ *
+ *   - 우리는 cmpxchg에서 유효한 ASID를 다시 얻습니다. 이는 원자 RmW가 
+ *   주어진 위치에 대해 완전히 주문되기 때문에 flush_context의 완화된 
+ *   xchg가 우리를 예약된 것으로 취급함을 의미합니다.
+ *
+ * - fastpath mm 구간
+ */
     old_active_asid = atomic64_read(this_cpu_ptr(&active_asids));
+/*
+ * IAMROOT, 2023.01.28:
+ * - 세대가 같고, active_asids를 asid로 바꾸는데 성공했으면 
+ *   fastpath 성공
+ */
     if (old_active_asid && asid_gen_match(asid) &&
         atomic64_cmpxchg_relaxed(this_cpu_ptr(&active_asids),
                      old_active_asid, asid))
         goto switch_mm_fastpath;
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - slowpath
+ *   old_active_asid 0이던가, 세대가 바뀌었던가, asid를 넣는게 
+ *   실패했을때 진입.
+ */
     raw_spin_lock_irqsave(&cpu_asid_lock, flags);
     /* Check that our ASID belongs to the current generation. */
     asid = atomic64_read(&mm->context.id);
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - 세대비교가 실패하면 asid를 새로 생성한다.
+ */
     if (!asid_gen_match(asid)) {
         asid = new_context(mm);
+/*
+ * IAMROOT, 2023.01.28:
+ * - 새로만든 asid를 mm에 set해준다.
+ */
         atomic64_set(&mm->context.id, asid);
     }
 
     cpu = smp_processor_id();
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - tlb flush pending요청이 있으면 flush한다.
+ * - new_context()에서 현재 tlb flush pending요청을 했을경우
+ *   자기신의 경우엔 여기서 즉시 될것이다.
+ */
     if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending))
         local_flush_tlb_all();
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 바뀐 asid로 active_asids를 update한다.
+ */
     atomic64_set(this_cpu_ptr(&active_asids), asid);
     raw_spin_unlock_irqrestore(&cpu_asid_lock, flags);
 
@@ -266,6 +485,11 @@ void check_and_switch_context(struct mm_struct *mm)
      * Defer TTBR0_EL1 setting for user threads to uaccess_enable() when
      * emulating PAN.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - hw가 지원하면 여기서 cpu_switch_mm을 한다.
+ *   sw로 pan을 하는 경우엔 나중에(uaccess_enable()) 한다.
+ */
     if (!system_uses_ttbr0_pan())
         cpu_switch_mm(mm->pgd, mm);
 }
diff --git a/include/asm-generic/barrier.h b/include/asm-generic/barrier.h
index 626a7b38aaaf..7e47e3eaf10a 100644
--- a/include/asm-generic/barrier.h
+++ b/include/asm-generic/barrier.h
@@ -140,6 +140,11 @@ do {                                    \
 #define smp_mb__after_atomic()    __smp_mb__after_atomic()
 #endif
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - cpu간 memory 동기화가 필요할때, 단방향 barrier로 사용한다.
+ *   barrier중에서 가장빠른 barrier.
+ */
 #ifndef smp_store_release
 #define smp_store_release(p, v) __smp_store_release(p, v)
 #endif
diff --git a/include/asm-generic/switch_to.h b/include/asm-generic/switch_to.h
index 5897d100a6e6..9c9c89a6089e 100644
--- a/include/asm-generic/switch_to.h
+++ b/include/asm-generic/switch_to.h
@@ -18,6 +18,10 @@
 extern struct task_struct *__switch_to(struct task_struct *,
                        struct task_struct *);
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - next로 switch. arm64의 경우 last엔 prev가 위치한다.
+ */
 #define switch_to(prev, next, last)                    \
     do {                                \
         ((last) = __switch_to((prev), (next)));            \
diff --git a/include/linux/kcov.h b/include/linux/kcov.h
index 55dc338f6bcd..4ce51fbb904e 100644
--- a/include/linux/kcov.h
+++ b/include/linux/kcov.h
@@ -28,11 +28,20 @@ enum kcov_mode {
 void kcov_task_init(struct task_struct *t);
 void kcov_task_exit(struct task_struct *t);
 
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - debug.
+ */
 #define kcov_prepare_switch(t)            \
 do {                        \
     (t)->kcov_mode |= KCOV_IN_CTXSW;    \
 } while (0)
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - debug.
+ */
 #define kcov_finish_switch(t)            \
 do {                        \
     (t)->kcov_mode &= ~KCOV_IN_CTXSW;    \
diff --git a/include/linux/mmu_context.h b/include/linux/mmu_context.h
index b9b970f7ab45..edea22f2552f 100644
--- a/include/linux/mmu_context.h
+++ b/include/linux/mmu_context.h
@@ -6,6 +6,10 @@
 #include <asm/mmu.h>
 
 /* Architectures that care about IRQ state in switch_mm can override this. */
+/*
+ * IAMROOT, 2023.01.28:
+ * - @next로 mm교체.
+ */
 #ifndef switch_mm_irqs_off
 # define switch_mm_irqs_off switch_mm
 #endif
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 9b60bb89d86a..fd8aa57bf4b3 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1201,6 +1201,11 @@ static inline void perf_event_task_migrate(struct task_struct *task)
         task->sched_migrated = 1;
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - PASS
+ *   perf
+ */
 static inline void perf_event_task_sched_in(struct task_struct *prev,
                         struct task_struct *task)
 {
@@ -1214,6 +1219,10 @@ static inline void perf_event_task_sched_in(struct task_struct *prev,
     }
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - perf 
+ */
 static inline void perf_event_task_sched_out(struct task_struct *prev,
                          struct task_struct *next)
 {
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 25be07d054d9..fcfc1c7c1abb 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -365,10 +365,21 @@ extern struct root_domain def_root_domain;
 extern struct mutex sched_domains_mutex;
 #endif
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - sched_info_arrive(), sched_info_depart() 참고
+ */
 struct sched_info {
 #ifdef CONFIG_SCHED_INFO
     /* Cumulative counters: */
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - pcount    : cpu에 올라간 횟수.
+ *   run_delay : 대기queue에서 기다렸던 시간총합.
+ *   last_arrival : cpu에 마지막에 올라간 시각
+ *   last_queued  : cpu에서 마지막에 제거된 시각.
+ */
     /* # of times we have run on this CPU: */
     unsigned long            pcount;
 
@@ -2327,6 +2338,11 @@ static inline void set_tsk_need_resched(struct task_struct *tsk)
     set_tsk_thread_flag(tsk,TIF_NEED_RESCHED);
 }
 
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - TIF_NEED_RESCHED clear.
+ */
 static inline void clear_tsk_need_resched(struct task_struct *tsk)
 {
     clear_tsk_thread_flag(tsk,TIF_NEED_RESCHED);
@@ -2551,6 +2567,12 @@ static inline void rseq_signal_deliver(struct ksignal *ksig,
 }
 
 /* rseq_preempt() requires preemption to be disabled. */
+/*
+ * IAMROOT, 2023.01.28:
+ * - PASS
+ * - Gitblame 참고 (restartable sequences system call)
+ *   rseq systemcall을 위한것
+ */
 static inline void rseq_preempt(struct task_struct *t)
 {
     __set_bit(RSEQ_EVENT_PREEMPT_BIT, &t->rseq_event_mask);
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index 87cdc0af88cb..869eb27415e3 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -374,6 +374,10 @@ enum {
 #include <asm/membarrier.h>
 #endif
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - membarrier 처리.
+ */
 static inline void membarrier_mm_sync_core_before_usermode(struct mm_struct *mm)
 {
     if (current->mm != mm)
@@ -381,6 +385,11 @@ static inline void membarrier_mm_sync_core_before_usermode(struct mm_struct *mm)
     if (likely(!(atomic_read(&mm->membarrier_state) &
              MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE)))
         return;
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - arm64는 없어보인다.
+ */
     sync_core_before_usermode();
 }
 
diff --git a/include/linux/tick.h b/include/linux/tick.h
index bfd571f18cfd..3b20d1554c38 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -299,6 +299,10 @@ static inline void __tick_nohz_task_switch(void) { }
 static inline void tick_nohz_full_setup(cpumask_var_t cpumask) { }
 #endif
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - nohz full을 해제한다.
+ */
 static inline void tick_nohz_task_switch(void)
 {
     if (tick_nohz_full_enabled())
diff --git a/include/linux/vtime.h b/include/linux/vtime.h
index 3684487d01e1..e90a6ae3f54d 100644
--- a/include/linux/vtime.h
+++ b/include/linux/vtime.h
@@ -89,6 +89,10 @@ static inline bool vtime_accounting_enabled_this_cpu(void)
 
 extern void vtime_task_switch_generic(struct task_struct *prev);
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - vtime accounting
+ */
 static inline void vtime_task_switch(struct task_struct *prev)
 {
     if (vtime_accounting_enabled_this_cpu())
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index b9dcc5012c34..a1f91d4d2cdf 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2422,6 +2422,10 @@ static int __set_cpus_allowed_ptr(struct task_struct *p,
                   const struct cpumask *new_mask,
                   u32 flags);
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - @p를 SCA_MIGRATE_DISABLE 한다. RT를 위해서 잠깐 migrate disable을 한다는 의미인거같다.
+ */
 static void migrate_disable_switch(struct rq *rq, struct task_struct *p)
 {
     if (likely(!p->migration_disabled))
@@ -4871,6 +4875,10 @@ __fire_sched_out_preempt_notifiers(struct task_struct *curr,
         notifier->ops->sched_out(notifier, next);
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - cpu에서 switch 될때마다 notify해달라는 요청에 대한 처리.
+ */
 static __always_inline void
 fire_sched_out_preempt_notifiers(struct task_struct *curr,
                  struct task_struct *next)
@@ -4893,6 +4901,10 @@ fire_sched_out_preempt_notifiers(struct task_struct *curr,
 
 #endif /* CONFIG_PREEMPT_NOTIFIERS */
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - on_cpu set.
+ */
 static inline void prepare_task(struct task_struct *next)
 {
 #ifdef CONFIG_SMP
@@ -4902,10 +4914,24 @@ static inline void prepare_task(struct task_struct *next)
      *
      * See the ttwu() WF_ON_CPU case and its ordering comment.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   작업을 실행 중이라고 주장합니다. 실행 중인 모든 작업이 이 설정을 
+ *   갖도록 전환하기 전에 이 작업을 수행합니다. 
+ *
+ *   ttwu() WF_ON_CPU 사례 및 주문 설명을 참조하십시오.
+ */
     WRITE_ONCE(next->on_cpu, 1);
 #endif
 }
 
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - on_cpu clear
+ *   단방향 barrier를 사용하는게 보인다.
+ */
 static inline void finish_task(struct task_struct *prev)
 {
 #ifdef CONFIG_SMP
@@ -4920,6 +4946,18 @@ static inline void finish_task(struct task_struct *prev)
      *
      * Pairs with the smp_cond_load_acquire() in try_to_wake_up().
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   이것은 이 CPU에서 @prev에 대한 마지막 참조여야 합니다. p->on_cpu가 
+ *   지워지면 작업을 다른 CPU로 옮길 수 있습니다. 전환이 완전히 완료될 
+ *   때까지 이런 일이 발생하지 않도록 해야 합니다.
+ *
+ *   특히 finish_task_switch()에서 prev->state의 로드는 이보다 먼저 
+ *   일어나야 합니다.
+ *
+ *   try_to_wake_up()에서 smp_cond_load_acquire()와 쌍을 이룹니다.
+ */
     smp_store_release(&prev->on_cpu, 0);
 #endif
 }
@@ -4961,6 +4999,10 @@ static inline struct callback_head *splice_balance_callbacks(struct rq *rq)
     return head;
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - TODO
+ */
 static void __balance_callbacks(struct rq *rq)
 {
     do_balance_callbacks(rq, splice_balance_callbacks(rq));
@@ -4994,6 +5036,10 @@ static inline void balance_callbacks(struct rq *rq, struct callback_head *head)
 
 #endif
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - switch 직전 lock관련 처리. finish_lock_switch()와 한쌍이다.
+ */
 static inline void
 prepare_lock_switch(struct rq *rq, struct task_struct *next, struct rq_flags *rf)
 {
@@ -5003,6 +5049,13 @@ prepare_lock_switch(struct rq *rq, struct task_struct *next, struct rq_flags *rf
      * of the scheduler it's an obvious special-case), so we
      * do an early lockdep release here:
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   runqueue 잠금은 다음 작업에 의해 해제되기 때문에(유효하지 
+ *   않은 잠금 작업이지만 스케줄러의 경우에는 명백한 특수 사례임) 
+ *   여기에서 초기 lockdep 해제를 수행합니다.
+ */
     rq_unpin_lock(rq, rf);
     spin_release(&__rq_lockp(rq)->dep_map, _THIS_IP_);
 #ifdef CONFIG_DEBUG_SPINLOCK
@@ -5011,6 +5064,10 @@ prepare_lock_switch(struct rq *rq, struct task_struct *next, struct rq_flags *rf
 #endif
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - prepare_lock_switch()와 한쌍이다.
+ */
 static inline void finish_lock_switch(struct rq *rq)
 {
     /*
@@ -5035,6 +5092,12 @@ static inline void finish_lock_switch(struct rq *rq)
 # define finish_arch_post_lock_switch()    do { } while (0)
 #endif
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - KMAP
+ *   32bit에서 사용한다.
+ *   highmam을 mapping하기 위한 방식.
+ */
 static inline void kmap_local_sched_out(void)
 {
 #ifdef CONFIG_KMAP_LOCAL
@@ -5043,6 +5106,12 @@ static inline void kmap_local_sched_out(void)
 #endif
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - KMAP
+ *   32bit에서 사용한다.
+ *   highmam을 mapping하기 위한 방식.
+ */
 static inline void kmap_local_sched_in(void)
 {
 #ifdef CONFIG_KMAP_LOCAL
@@ -5064,6 +5133,23 @@ static inline void kmap_local_sched_in(void)
  * prepare_task_switch sets up locking and calls architecture specific
  * hooks.
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   prepare_task_switch - 작업 전환 준비
+ *   @rq: 전환을 준비하는 런큐 
+ *   @prev: 전환 중인 현재 작업 
+ *   @next: 전환할 작업.
+ *   이것은 rq 잠금이 유지되고 인터럽트가 꺼진 상태에서 호출됩니다. 
+ *   컨텍스트 전환 후 후속 finish_task_switch와 쌍을 이루어야 합니다.
+ *   prepare_task_switch는 잠금을 설정하고 아키텍처별 후크를 호출합니다.
+ *
+ * - 1. sched_info update.
+ *   2. kcov, perf등 debug 처리.
+ *   3. fire sched out등 notify 처리
+ *   4. rseq systemcall을 위한 처리.
+ *   5. on_cpu set.
+ */
 static inline void
 prepare_task_switch(struct rq *rq, struct task_struct *prev,
             struct task_struct *next)
@@ -5071,6 +5157,11 @@ prepare_task_switch(struct rq *rq, struct task_struct *prev,
     kcov_prepare_switch(prev);
     sched_info_switch(rq, prev, next);
     perf_event_task_sched_out(prev, next);
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - Gitblame 참고 (restartable sequences system call)
+ */
     rseq_preempt(prev);
     fire_sched_out_preempt_notifiers(prev, next);
     kmap_local_sched_out();
@@ -5097,6 +5188,27 @@ prepare_task_switch(struct rq *rq, struct task_struct *prev,
  * past. prev == current is still correct but we need to recalculate this_rq
  * because prev may have moved to another CPU.
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   finish_task_switch - 작업 전환 후 정리
+ *   @prev: 방금 전환한 스레드입니다.
+ *
+ *   finish_task_switch는 컨텍스트 전환 이후에 호출되어야 하며, 컨텍스트 전환 
+ *   전에는 prepare_task_switch 호출과 쌍을 이루어야 합니다.
+ *   finish_task_switch는 prepare_task_switch에 의해 설정된 잠금을 조정하고 
+ *   다른 아키텍처별 정리 작업을 수행합니다.
+ *
+ *   context_switch()에서 mm 삭제를 지연했을 수 있습니다. 그렇다면 실행 대기열
+ *   잠금 외부에서 여기에서 완료합니다. (잠금이 유지된 상태에서 작업을 
+ *   수행하면 교착 상태가 발생할 수 있습니다. 자세한 내용은 schedule()을 
+ *   참조하십시오.) 컨텍스트 스위치는 이전에 이 작업이 schedule()을 호출할 때 
+ *   저장된 로컬 변수를 복원했습니다. prev == current는 여전히 정확하지만 
+ *   prev가 다른 CPU로 이동했을 수 있으므로 this_rq를 다시 계산해야 합니다.
+ *
+ * - prev task에 대한 context 정리를 한다. prev task가 TASK_DEAD라면
+ *   자료구조까지 정리해준다.
+ */
 static struct rq *finish_task_switch(struct task_struct *prev)
     __releases(rq->lock)
 {
@@ -5133,10 +5245,28 @@ static struct rq *finish_task_switch(struct task_struct *prev)
      * running on another CPU and we could rave with its RUNNING -> DEAD
      * transition, resulting in a double drop.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   task 구조체에는 현재로 사용할 참조가 하나 있습니다.
+ *   task가 종료되면 tsk->state에서 TASK_DEAD를 설정하고 마지막으로 
+ *   schedule을 호출합니다. 일정 호출은 반환되지 않으며 예약된 작업은 
+ *   해당 참조를 삭제해야 합니다.
+ *
+ *   우리는 prev->on_cpu를 지우기 전에(finish_task에서) prev->state를 
+ *   관찰해야 합니다. 그렇지 않으면 동시 웨이크업이 다른 CPU에서 prev 
+ *   실행될 수 있고 우리는 RUNNING -> DEAD 전환으로 격찬하여 더블 
+ *   드롭을 초래할 수 있습니다.
+ */
     prev_state = READ_ONCE(prev->__state);
     vtime_task_switch(prev);
     perf_event_task_sched_in(prev, current);
     finish_task(prev);
+/*
+ * IAMROOT, 2023.01.28:
+ * - task가 switch가 됬다는게 nohz full이 아니라는 상태이므로 nohz
+ *   full이면 해제한다.
+ */
     tick_nohz_task_switch();
     finish_lock_switch(rq);
     finish_arch_post_lock_switch();
@@ -5163,10 +5293,20 @@ static struct rq *finish_task_switch(struct task_struct *prev)
      *   provided by mmdrop(),
      * - a sync_core for SYNC_CORE.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - prev mm이 존재하면 mm에대한 ref drop.
+ */
     if (mm) {
         membarrier_mm_sync_core_before_usermode(mm);
         mmdrop(mm);
     }
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - prev task가 완전히 죽으면서 context switch를 한상태다.
+ *   task_dead를 호출하여 prev를 current가 정리해주는 개념이다.
+ */
     if (unlikely(prev_state == TASK_DEAD)) {
         if (prev->sched_class->task_dead)
             prev->sched_class->task_dead(prev);
@@ -5178,6 +5318,10 @@ static struct rq *finish_task_switch(struct task_struct *prev)
         kprobe_flush_task(prev);
 
         /* Task is done with its stack. */
+/*
+ * IAMROOT, 2023.01.28:
+ * - prev stack제거
+ */
         put_task_stack(prev);
 
         put_task_struct_rcu_user(prev);
@@ -5214,6 +5358,12 @@ asmlinkage __visible void schedule_tail(struct task_struct *prev)
 /*
  * context_switch - switch to the new MM and the new thread's register state.
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - 1. mm switch
+ *      같은 가상주소를 사용하고있으면 할필요없지만 아닌경우 해야된다.
+ *   2. process context switch
+ */
 static __always_inline struct rq *
 context_switch(struct rq *rq, struct task_struct *prev,
            struct task_struct *next, struct rq_flags *rf)
@@ -5234,15 +5384,45 @@ context_switch(struct rq *rq, struct task_struct *prev,
      * kernel ->   user   switch + mmdrop() active
      *   user ->   user   switch
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - mm
+ *   유저 process인 경우 자신의 mm
+ *   유저 thread인 경우 해당 부모 프로세스의 mm
+ *   kernel thread : NULL
+ * - active_mm
+ *   유저 process인 경우 자신의 mm
+ *   유저 thread인 경우 해당 부모 프로세스의 mm
+ *   kernel thread : 이전 유전 프로세스의 mm을 전달받아 사용한다.
+ *
+ * - mm == NULL : kernel
+ *   mm != NULL : user
+ */
     if (!next->mm) {                                // to kernel
         enter_lazy_tlb(prev->active_mm, next);
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - prev -> next로 update. active_mm는 항상 user task mm이 들어가 있다.
+ *   인계하는 개념.
+ */
         next->active_mm = prev->active_mm;
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - prev가 user였으면 active_mm ref count를 증가시키고,
+ *   prev가 kernel이였으면 prev의 active_mm이
+ *   next로 active_mm으로 넘어갔으므로 prev active_mm을 지운다.
+ */
         if (prev->mm)                           // from user
             mmgrab(prev->active_mm);
         else
             prev->active_mm = NULL;
     } else {                                        // to user
+/*
+ * IAMROOT, 2023.01.28:
+ * - user공간에서는 mm간의 간섭을 막기위해 membarrier 처리를한다.
+ */
         membarrier_switch_mm(rq, prev->active_mm, next->mm);
         /*
          * sys_membarrier() requires an smp_mb() between setting
@@ -5252,8 +5432,24 @@ context_switch(struct rq *rq, struct task_struct *prev,
          * case 'prev->active_mm == next->mm' through
          * finish_task_switch()'s mmdrop().
          */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   sys_membarrier()는 rq->curr / membarrier_switch_mm() 설정과 사용자 
+ *   공간으로 돌아가는 사이에 smp_mb()가 필요합니다.
+ *
+ *   아래는 switch_mm()을 통해 또는 'prev->active_mm == next->mm'인 경우 
+ *   finish_task_switch()의 mmdrop()을 통해 이를 제공합니다.
+ *
+ * - @next로 mm을 교체한다.
+ */
         switch_mm_irqs_off(prev->active_mm, next->mm, next);
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - kernel 인경우 prev->active_mm을 rq->prev_mm으로 옮긴다.
+ *   prev->active_mm은 초기화한다.
+ */
         if (!prev->mm) {                        // from kernel
             /* will mmdrop() in finish_task_switch(). */
             rq->prev_mm = prev->active_mm;
@@ -5881,6 +6077,11 @@ static inline void schedule_debug(struct task_struct *prev, bool preempt)
     schedstat_inc(this_rq()->sched_count);
 }
 
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - TODO
+ */
 static void put_prev_task_balance(struct rq *rq, struct task_struct *prev,
                   struct rq_flags *rf)
 {
@@ -5908,7 +6109,8 @@ static void put_prev_task_balance(struct rq *rq, struct task_struct *prev,
  */
 /*
  * IAMROOT, 2023.01.27:
- * - ING
+ * - @prev가 cfs이고 @rq 소속이 전부 cfs라면 pick_next_task_fair로 next task를 선택한다.
+ *   그게 아니면 sched class 우선순위로 next task를 선택한다.
  */
 static inline struct task_struct *
 __pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
@@ -5950,6 +6152,11 @@ __pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
         if (unlikely(p == RETRY_TASK))
             goto restart;
 
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - next가 없는 즉 할게없는 상황. idle task를 선택한다.
+ */
         /* Assume the next prioritized class is idle_sched_class */
         if (!p) {
             put_prev_task(rq, prev);
@@ -5960,14 +6167,29 @@ __pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
     }
 
 restart:
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - load balancing
+ */
     put_prev_task_balance(rq, prev, rf);
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 우선순위별로 rt task 선택.
+ */
     for_each_class(class) {
         p = class->pick_next_task(rq);
         if (p)
             return p;
     }
 
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - dl, rt, cfs_rq, idle 등의 순으로 선택을해봤는데도 없는 경우는 존재하지 않는다 최소한 
+ *   idle이 선택되기때문이다.
+ */
     /* The idle class should always have a runnable task: */
     BUG();
 }
@@ -6487,7 +6709,7 @@ static inline void sched_core_cpu_dying(unsigned int cpu) {}
 
 /*
  * IAMROOT, 2023.01.27:
- * - ING
+ * - next task를 선택한다.
  */
 static struct task_struct *
 pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
@@ -6600,7 +6822,11 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
  *   - 인터럽트 핸들러에서 사용자 공간으로 복귀
  *
  *   경고: 선점을 비활성화한 상태로 호출해야 합니다!.
- * - TODO
+ * - 1. local irq disable
+ *   2. 자발적 / 비자발적유무에 따른 deactivate_task 처리
+ *   3. next task를 선택 및 설정한다.
+ *   4. mm switch 수행.
+ *   5. context switch 수행.
  */
 static void __sched notrace __schedule(unsigned int sched_mode)
 {
@@ -6765,6 +6991,10 @@ static void __sched notrace __schedule(unsigned int sched_mode)
     rq->last_seen_need_resched_ns = 0;
 #endif
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - @prev가 변경됬다는것이므로 switch가 이뤄졌다.
+ */
     if (likely(prev != next)) {
         rq->nr_switches++;
         /*
@@ -6786,6 +7016,18 @@ static void __sched notrace __schedule(unsigned int sched_mode)
          * - switch_to() for arm64 (weakly-ordered, spin_unlock
          *   is a RELEASE barrier),
          */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   membarrier 시스템 호출은 각 아키텍처가 rq->curr를 업데이트한 후 사용자 
+ *   공간으로 돌아가기 전에 전체 메모리 장벽을 갖도록 요구합니다.
+ *   다음은 다양한 아키텍처에 대한 장벽을 제공하는 체계입니다.
+ *
+ *   - mm ? switch_mm() : x86, s390, sparc, PowerPC용 mmdrop(). 
+ *   switch_mm()은 PowerPC의 membarrier_arch_switch_mm()에 의존합니다.
+ *   - spin_unlock이 전체 장벽인 weak order의 아키텍처에 대한 finish_lock_switch(),
+ *   - arm64에 대한 switch_to()(약한 순서, spin_unlock은 RELEASE 장벽임).
+ */
         ++*switch_count;
 
         migrate_disable_switch(rq, prev);
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index 013fc579ec54..d5c1549f97fd 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -761,6 +761,10 @@ void vtime_account_idle(struct task_struct *tsk)
     account_idle_time(get_vtime_delta(&tsk->vtime));
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - vtime(virtual time) accounting
+ */
 void vtime_task_switch_generic(struct task_struct *prev)
 {
     struct vtime *vtime = &prev->vtime;
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 10c2fdca813a..f97323486f3a 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -89,6 +89,16 @@ unsigned int sysctl_sched_child_runs_first __read_mostly;
  *
  * (default: 1 msec * (1 + ilog(ncpus)), units: nanoseconds)
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *  SCHED_OTHER 깨우기 세분성입니다.
+ *
+ *  이 옵션은 분리된 워크로드의 선점 효과를 지연시키고 과도한 스케줄링을 줄입니다. 
+ *  동기식 워크로드에는 여전히 즉각적인 깨우기/절전 대기 시간이 있습니다.
+ *
+ * (default: 1 msec * (1 + ilog(ncpus)), units: nanoseconds)
+ */
 unsigned int sysctl_sched_wakeup_granularity            = 1000000UL;
 static unsigned int normalized_sysctl_sched_wakeup_granularity    = 1000000UL;
 
@@ -537,6 +547,10 @@ static inline void assert_list_leaf_cfs_rq(struct rq *rq)
                  leaf_cfs_rq_list)
 
 /* Do the two (enqueued) entities belong to the same group ? */
+/*
+ * IAMROOT, 2023.01.28:
+ * - 같은 cfs_rq 소속인지 확인한다.
+ */
 static inline struct cfs_rq *
 is_same_group(struct sched_entity *se, struct sched_entity *pse)
 {
@@ -679,6 +693,10 @@ static inline u64 min_vruntime(u64 min_vruntime, u64 vruntime)
     return min_vruntime;
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - a가 b보다 vruntime이 작다면 return true;
+ */
 static inline bool entity_before(struct sched_entity *a,
                 struct sched_entity *b)
 {
@@ -787,11 +805,19 @@ static inline bool __entity_less(struct rb_node *a, const struct rb_node *b)
 /*
  * Enqueue an entity into the rb-tree:
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - cfs_rq에 넣는다.
+ */
 static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
     rb_add_cached(&se->run_node, &cfs_rq->tasks_timeline, __entity_less);
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - cfs_rq에서 제거한다.
+ */
 static void __dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
     rb_erase_cached(&se->run_node, &cfs_rq->tasks_timeline);
@@ -1158,6 +1184,10 @@ static void update_curr_fair(struct rq *rq)
     update_curr(cfs_rq_of(&rq->curr->se));
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - schedule stat 처리
+ */
 static inline void
 update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
@@ -1176,6 +1206,11 @@ update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
     __schedstat_set(se->statistics.wait_start, wait_start);
 }
 
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - stats 처리.
+ */
 static inline void
 update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
@@ -5218,6 +5253,10 @@ static inline int task_fits_capacity(struct task_struct *p, long capacity)
     return fits_capacity(uclamp_task_util(p), capacity);
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - TODO
+ */
 static inline void update_misfit_status(struct task_struct *p, struct rq *rq)
 {
     if (!static_branch_unlikely(&sched_asym_cpucapacity))
@@ -5281,6 +5320,10 @@ static inline void update_misfit_status(struct task_struct *p, struct rq *rq) {}
 
 #endif /* CONFIG_SMP */
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - debug.
+ */
 static void check_spread(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
 #ifdef CONFIG_SCHED_DEBUG
@@ -5622,9 +5665,22 @@ check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr)
         resched_curr(rq_of(cfs_rq));
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 1. @se에 대한 buddy정보를 다 지운다.
+ *   2. on_rq일시 cfs_rq에서 @se를 dequeue한다.
+ *   3. load avg재계산.
+ *   4. @se를 curr로 선택한다.
+ *   5. stats 및 debug처리.
+ *   6. prev_sum_exec_runtime update.
+ */
 static void
 set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
 {
+/*
+ * IAMROOT, 2023.01.28:
+ * - @se에 대한 정보를 다 지운다.
+ */
     clear_buddies(cfs_rq, se);
 
     /* 'current' is not kept within the tree. */
@@ -5647,6 +5703,12 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
      * least twice that of our own weight (i.e. dont track it
      * when there are only lesser-weight tasks around):
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   CPU 부하가 자체 무게의 두 배 이상인 경우 최대 슬라이스 길이를 추적합니다(즉, 주변에 더 
+ *   가벼운 작업만 있는 경우 추적하지 않음).
+ */
     if (schedstat_enabled() &&
         rq_of(cfs_rq)->cfs.load.weight >= 2*se->load.weight) {
         schedstat_set(se->statistics.slice_max,
@@ -5667,6 +5729,21 @@ wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se);
  * 3) pick the "last" process, for cache locality
  * 4) do not run the "skip" process, if something else is available
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   이러한 사항을 염두에 두고 다음 순서로 다음 프로세스를 선택합니다.
+ *
+ *   1) 프로세스/작업 그룹 간에 일을 공정하게 유지
+ *   2) 누군가가 실제로 실행하기를 원하기 때문에 다음 프로세스를 선택하십시오.
+ *   3) 캐시 지역성을 위해 마지막 프로세스를 선택합니다.
+ *   4) 다른 것을 사용할 수 있는 경우 건너뛰기 프로세스를 실행하지 마십시오.
+ *
+ * - @curr의 next를 고른다.
+ *   1. curr의 left인것을 찾는다.
+ *   2. next -> last -> skip고려 순으로 se를 선택한다.
+ *   3. 3개가 전부 없으면 left가 선택될것이다.
+ */
 static struct sched_entity *
 pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr)
 {
@@ -5677,6 +5754,14 @@ pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr)
      * If curr is set we have to see if its left of the leftmost entity
      * still in the tree, provided there was anything in the tree at all.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   curr이 설정되어 있으면 트리에 아무 것도 없는 경우 가장 왼쪽 엔터티의 왼쪽이 여전히 
+ *   트리에 있는지 확인해야 합니다.
+ *   
+ * - curr가 left보다 왼쪽인지 확인한다. 더 왼쪽이면 left = curr.
+ */
     if (!left || (curr && entity_before(curr, left)))
         left = curr;
 
@@ -5686,26 +5771,58 @@ pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr)
      * Avoid running the skip buddy, if running something else can
      * be done without getting too unfair.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   너무 불공평하지 않고 다른 것을 실행할 수 있다면 스킵 버디를 실행하지 마십시오.
+ * - skip 지정이 되있고, se가 skip에 해당된다면 차선책을 찾는다.
+ *   curr보다 이전인것을 고르려고 노력한다.
+ */
     if (cfs_rq->skip && cfs_rq->skip == se) {
         struct sched_entity *second;
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - se(skip)이 curr면은 가장작은것을 찾아 second로 고른다.
+ *   se이 curr가 아니면, se의 next를 고른다.
+ */
         if (se == curr) {
             second = __pick_first_entity(cfs_rq);
         } else {
             second = __pick_next_entity(se);
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - next를 골라봤는데도 불구하고, next가 없거나, curr가 next의 이전이라면
+ *   curr를 second를 사용한다.
+ */
             if (!second || (curr && entity_before(curr, second)))
                 second = curr;
         }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - second가 wakeup_gran보다 너무 앞서있는 경우만 아니면 se를 second로 선택한다.
+ *   최대한 이전을 골라봤는데도 앞서있을수있는데, wakeup_gran만큼은 허용한다는뜻이다.
+ */
         if (second && wakeup_preempt_entity(second, left) < 1)
             se = second;
     }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - next를 가장 높은 우선순위로 고려한다.
+ * - next가 left 보다 너무 앞서있는경우가 아니면 se를 next로 선택한다. 
+ */
     if (cfs_rq->next && wakeup_preempt_entity(cfs_rq->next, left) < 1) {
         /*
          * Someone really wants this to run. If it's not unfair, run it.
          */
         se = cfs_rq->next;
+/*
+ * IAMROOT, 2023.01.28:
+ * - last도 next처럼 고려한다.
+ */
     } else if (cfs_rq->last && wakeup_preempt_entity(cfs_rq->last, left) < 1) {
         /*
          * Prefer last buddy, try to return the CPU to a preempted task.
@@ -5718,12 +5835,25 @@ pick_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *curr)
 
 static bool check_cfs_rq_runtime(struct cfs_rq *cfs_rq);
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 1. @prev가 cfs_rq에 있으면 update_curr()
+ *   2. cfs_bandwidth처리
+ *   3. debug및 통계처리
+ *   4. cfs_rq에 enqueue.
+ *   5. load avg 재계산.
+ *   6. curr를 NULL로 update.
+ */
 static void put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev)
 {
     /*
      * If still on the runqueue then deactivate_task()
      * was not called and update_curr() has to be done:
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - rq에 들어가있엇으면 시간갱신을 해준다.
+ */
     if (prev->on_rq)
         update_curr(cfs_rq);
 
@@ -6677,6 +6807,10 @@ static void sync_throttle(struct task_group *tg, int cpu)
 }
 
 /* conditionally throttle active cfs_rq's from put_prev_entity() */
+/*
+ * IAMROOT, 2023.01.28:
+ * - cfs_bandwidth 미지원이면 return false.
+ */
 static bool check_cfs_rq_runtime(struct cfs_rq *cfs_rq)
 {
     if (!cfs_bandwidth_used())
@@ -6992,6 +7126,11 @@ static inline void unthrottle_offline_cfs_rqs(struct rq *rq) {}
  */
 
 #ifdef CONFIG_SCHED_HRTICK
+/*
+ * IAMROOT, 2023.01.28:
+ * - prev에서 slice만큼 동작했는지 확인한다. slice만큼 동작했고 p가 current라면 resched요청을
+ *   하고 그게 아니면 delta후에 hrtick이 동작하도록 조정한다.
+ */
 static void hrtick_start_fair(struct rq *rq, struct task_struct *p)
 {
     struct sched_entity *se = &p->se;
@@ -8536,6 +8675,10 @@ balance_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
 }
 #endif /* CONFIG_SMP */
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - @se의 weight를 적용한 gran값을 구한다.
+ */
 static unsigned long wakeup_gran(struct sched_entity *se)
 {
     unsigned long gran = sysctl_sched_wakeup_granularity;
@@ -8553,6 +8696,17 @@ static unsigned long wakeup_gran(struct sched_entity *se)
      * This is especially important for buddies when the leftmost
      * task is higher priority than the buddy.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   이제 curr가 실행되기 때문에 gran을 실시간에서 가상 시간으로 단위로 변환하십시오.
+ *
+ *   'curr' 대신 'se'를 사용하여 가벼운 작업에 페널티를 주어 더 쉽게 선점할 수 있습니다.
+ *   즉, 'se' < 'curr'이면 결과 gran이 더 커지므로 더 가벼운 작업에 페널티를 주고, 
+ *   otoh 'se' > 'curr'이면 결과 gran이 더 작아지므로 더 가벼운 작업에 페널티를 줍니다.
+ *
+ *   이것은 가장 왼쪽 작업이 버디보다 우선순위가 높을 때 버디에게 특히 중요합니다.
+ */
     return calc_delta_fair(gran, se);
 }
 
@@ -8570,6 +8724,22 @@ static unsigned long wakeup_gran(struct sched_entity *se)
  *  w(c, s3) =  1
  *
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - @return -1 : curr의 vruntime이 se vruntime 보다 작다
+ *            1 : @se gran값보다 diff가 크면, 즉 충분한 시간차가 있으면
+ *            0 : @se gran값보다 diff가 작으면, 즉 gran 이내의 시간이면(너무 짧은시간)
+ *
+ * ------------
+ *
+ * - curr |  se   : -1
+ *
+ * -      gran 
+ *   se |  curr | : 0
+ *
+ * -      gran 
+ *   se |      |  curr : 1
+ */
 static int
 wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se)
 {
@@ -8746,6 +8916,11 @@ static struct task_struct *pick_task_fair(struct rq *rq)
 }
 #endif
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - cfs_rq의 curr의 next를 선택한다. 선택이 되면 @prev를 put, 선택된 next를 curr로 계층구조로
+ *   순환하며 설정한다. 선택된 next의 task를 return한다.
+ */
 struct task_struct *
 pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
 {
@@ -8769,7 +8944,18 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf
      * Therefore attempt to avoid putting and setting the entire cgroup
      * hierarchy, only change the part that actually changes.
      */
-
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   dequeue_task_fair()의 set_next_buddy() 때문에 다음 작업이 현재 작업과 동일한 cgroup에서 
+ *   나올 가능성이 높습니다.
+ *
+ *   따라서 전체 cgroup 계층 구조를 넣거나 설정하는 것을 피하고 실제로 변경되는 부분만 
+ *   변경하십시오.
+ *
+ * - 계층구조로 내려가면서 curr의 next를 순회한다. 최종적으로 마지막 next로 선택된것을
+ *   se로 선택될것이고, 이것은 task가 된다.
+ */
     do {
         struct sched_entity *curr = cfs_rq->curr;
 
@@ -8779,7 +8965,19 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf
          * entity, update_curr() will update its vruntime, otherwise
          * forget we've ever seen it.
          */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   put_prev_entity()를 수행하지 않고 여기에 왔기 때문에 cfs_rq->curr도 고려해야 합니다. 
+ *   여전히 실행 가능한 엔터티인 경우 update_curr()는 vruntime을 업데이트하고, 그렇지 않으면 
+ *   우리가 본 적이 있다는 사실을 잊어버립니다.
+ */
         if (curr) {
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - curr entity가 rq에 안들어가있으면 null로 설정.
+ */
             if (curr->on_rq)
                 update_curr(cfs_rq);
             else
@@ -8791,6 +8989,14 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf
              * Therefore the nr_running test will indeed
              * be correct.
              */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   check_cfs_rq_runtime()에 대한 이 호출은 스로틀링을 수행하고 상위 항목의 대기열에서 
+ *   제외합니다.
+ *   따라서 nr_running 테스트는 실제로 정확합니다. 
+ * - throttle인지 확인한다.
+ */
             if (unlikely(check_cfs_rq_runtime(cfs_rq))) {
                 cfs_rq = &rq->cfs;
 
@@ -8812,23 +9018,83 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf
      * is a different task than we started out with, try and touch the
      * least amount of cfs_rqs.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   아직 put_prev_entity를 수행하지 않았고 선택한 작업이 시작과 다른 작업인 경우 최소량의 
+ *   cfs_rq를 터치해 봅니다.
+ *
+ * - 선택한 p(se)가 @prev가 다르다면 prev se를 put하고, 새로운 p(se)를 set한다.
+ */
     if (prev != p) {
         struct sched_entity *pse = &prev->se;
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - se, pse가 같은 cfs_rq소속일때까지 반복하며
+ *   pse를 cfs_rq에 enqueue, se를 cfs_rq에서 dequeue를 하고, se를 curr로 update한다.
+ *
+ *         O 
+ *        / \
+ *       O <----same_group
+ *      / \
+ *     O  se
+ *    / \
+ *  pse ..
+ */
         while (!(cfs_rq = is_same_group(se, pse))) {
             int se_depth = se->depth;
             int pse_depth = pse->depth;
 
+            p
+/*
+ * IAMROOT, 2023.01.28:
+ * - pse가 se보다 더 깊거나 같은 위치. pse를 put해준다.
+ * - ex)
+ *         O 
+ *        / \
+ *       O <----same_group
+ *      / \
+ *     O  se
+ *    / \
+ *  pse ..
+ */
             if (se_depth <= pse_depth) {
+/*
+ * IAMROOT, 2023.01.28:
+ * - prev se를 cfs_rq로 enqueue.
+ */
                 put_prev_entity(cfs_rq_of(pse), pse);
                 pse = parent_entity(pse);
             }
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - se가 pse보다 더 깊거나 같은 위치. curr를 update해준다.
+ * - ex)
+ *         O 
+ *        / \
+ *       O <----same_group
+ *      / \
+ *     O  pse
+ *    / \
+ *   se ..
+ */
             if (se_depth >= pse_depth) {
+/*
+ * prifri, 2023.01.28:
+ * - cfs_rq에 se를 dequeue하고 se를 curr로 설정한다.
+ */
                 set_next_entity(cfs_rq_of(se), se);
                 se = parent_entity(se);
             }
         }
 
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - 최종적으로 same_group에서 만낫을때. pse, se의 처리.
+ */
         put_prev_entity(cfs_rq, pse);
         set_next_entity(cfs_rq, se);
     }
@@ -8836,10 +9102,19 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf
     goto done;
 simple:
 #endif
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - simple인 경우는 계층구조 처리가 필요없어 간단히 처리하고 넘어간다.
+ */
     if (prev)
         put_prev_task(rq, prev);
 
     do {
+/*
+ * IAMROOT, 2023.01.28:
+ * - next를 pick하고 set한다.
+ */
         se = pick_next_entity(cfs_rq, NULL);
         set_next_entity(cfs_rq, se);
         cfs_rq = group_cfs_rq(se);
@@ -8854,6 +9129,11 @@ done: __maybe_unused;
      * the list, so our cfs_tasks list becomes MRU
      * one.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   다음 실행 작업을 목록의 맨 앞으로 이동하여 cfs_tasks 목록이 MRU 목록이 되도록 합니다.
+ */
     list_move(&p->se.group_node, &rq->cfs_tasks);
 #endif
 
@@ -8862,6 +9142,10 @@ done: __maybe_unused;
 
     update_misfit_status(p, rq);
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - next의 task가 return된다.
+ */
     return p;
 
 idle:
@@ -12247,6 +12531,11 @@ static inline void nohz_newidle_balance(struct rq *this_rq) { }
  *     0 - failed, no new tasks
  *   > 0 - success, new (fair) tasks present
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - TODO
+ *   다른 cpu에서 task를 가져온다.
+ */
 static int newidle_balance(struct rq *this_rq, struct rq_flags *rf)
 {
     unsigned long next_balance = jiffies + HZ;
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 2f3a9b38e115..a88d19125128 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -726,6 +726,13 @@ struct cfs_rq {
      * 'curr' points to currently running entity on this cfs_rq.
      * It is set to NULL otherwise (i.e when none are currently running).
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - set 함수 정리.
+ *   next : set_next_buddy(check_preempt_wakeup(), yield_to_task_fair(), dequeue_task_fair())
+ *   last : set_last_buddy(check_preempt_wakeup())
+ *   skip : set_skip_buddy(yield_to_task_fair())
+ */
     struct sched_entity    *curr;
     struct sched_entity    *next;
     struct sched_entity    *last;
@@ -1304,6 +1311,10 @@ struct rq {
     int            cpu;
     int            online;
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 현재 rq에서 runable하고있는 task들.
+ */
     struct list_head cfs_tasks;
 
     struct sched_avg    avg_rt;
@@ -1790,6 +1801,10 @@ static inline void assert_clock_updated(struct rq *rq)
     SCHED_WARN_ON(rq->clock_update_flags < RQCF_ACT_SKIP);
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - return clock
+ */
 static inline u64 rq_clock(struct rq *rq)
 {
     lockdep_assert_rq_held(rq);
@@ -2906,6 +2921,10 @@ static inline int hrtick_enabled(struct rq *rq)
     return hrtimer_is_hres_active(&rq->hrtick_timer);
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - sched HRTICK 지원 확인.
+ */
 static inline int hrtick_enabled_fair(struct rq *rq)
 {
     if (!sched_feat(HRTICK))
@@ -3501,15 +3520,33 @@ static inline bool sched_energy_enabled(void) { return false; }
  * - store to rq->membarrier_state and following user-space memory accesses.
  * In the same way it provides those guarantees around store to rq->curr.
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   - 스케줄러는 다음 사이에 membarrier에 필요한 메모리 배리어를 제공합니다.
+ *   - 이전 사용자 공간 메모리 액세스 및 rq->membarrier_state 저장,
+ *   - rq->membarrier_state에 저장하고 사용자 공간 메모리 액세스를 따릅니다.
+ *   같은 방식으로 저장소 주변에서 rq->curr에 대한 보증을 제공합니다.
+ *
+ * - user공간에서는 mm간의 간섭을 막기위해 membarrier 처리를한다.
+ */
 static inline void membarrier_switch_mm(struct rq *rq,
                     struct mm_struct *prev_mm,
                     struct mm_struct *next_mm)
 {
     int membarrier_state;
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - mm이 안바꼇으면 switch할필요없다.
+ */
     if (prev_mm == next_mm)
         return;
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - rq의 membarrier_state를 next로 갱신한다.
+ */
     membarrier_state = atomic_read(&next_mm->membarrier_state);
     if (READ_ONCE(rq->membarrier_state) == membarrier_state)
         return;
diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h
index fe22cb00d8f0..c160d4137b54 100644
--- a/kernel/sched/stats.h
+++ b/kernel/sched/stats.h
@@ -5,6 +5,10 @@
 /*
  * Expects runqueue lock to be held for atomicity of update
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - sched stats처리.
+ */
 static inline void
 rq_sched_info_arrive(struct rq *rq, unsigned long long delta)
 {
@@ -17,6 +21,10 @@ rq_sched_info_arrive(struct rq *rq, unsigned long long delta)
 /*
  * Expects runqueue lock to be held for atomicity of update
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - sched stats처리.
+ */
 static inline void
 rq_sched_info_depart(struct rq *rq, unsigned long long delta)
 {
@@ -130,6 +138,10 @@ static inline void psi_ttwu_dequeue(struct task_struct *p)
     }
 }
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - psi 처리
+ */
 static inline void psi_sched_switch(struct task_struct *prev,
                     struct task_struct *next,
                     bool sleep)
@@ -184,14 +196,31 @@ static inline void sched_info_dequeue(struct rq *rq, struct task_struct *t)
  * long it was waiting to run.  We also note when it began so that we
  * can keep stats on how long its timeslice is.
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   작업이 마침내 CPU에 도달하면 호출됩니다. 이제 실행 대기 시간을 
+ *   계산할 수 있습니다. 또한 타임슬라이스의 길이에 대한 통계를 유지할 
+ *   수 있도록 언제 시작되었는지 기록합니다.
+ * - 대기큐에 있다가 cpu로 올라가는상황. sched_info 정보를 기록한다.
+ */
 static void sched_info_arrive(struct rq *rq, struct task_struct *t)
 {
     unsigned long long now, delta = 0;
 
+/*
+ * IAMROOT, 2023.01.28:
+ * - 대기큐에 돌아갈때 set되엇을것이다.
+ */
     if (!t->sched_info.last_queued)
         return;
 
     now = rq_clock(rq);
+
+/*
+ * IAMROOT, 2023.01.28:
+ * - 기다렸던 시간.
+ */
     delta = now - t->sched_info.last_queued;
     t->sched_info.last_queued = 0;
     t->sched_info.run_delay += delta;
@@ -206,6 +235,14 @@ static void sched_info_arrive(struct rq *rq, struct task_struct *t)
  * the timestamp if it is already not set.  It's assumed that
  * sched_info_dequeue() will clear that stamp when appropriate.
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   작업이 마침내 CPU에 도달하면 호출됩니다. 이제 실행 대기 시간을 계산할 
+ *   수 있습니다. 또한 타임슬라이스의 길이에 대한 통계를 유지할 수 있도록 
+ *   언제 시작되었는지 기록합니다.
+ * - rq의 queueing했을대의 시각을 last_queued에 등록한다.
+ */
 static inline void sched_info_enqueue(struct rq *rq, struct task_struct *t)
 {
     if (!t->sched_info.last_queued)
@@ -220,8 +257,22 @@ static inline void sched_info_enqueue(struct rq *rq, struct task_struct *t)
  * sched_info_enqueue() to mark that it has now again started waiting on
  * the runqueue.
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   일반적으로 시간 조각 만료로 인해 프로세스가 비자발적으로 활성 실행 
+ *   프로세스가 되는 것을 중단할 때 호출됩니다(유휴 작업으로 전환할 때도 호출될 
+ *   수 있음). 이제 우리는 얼마나 오래 달렸는지 계산할 수 있습니다. 
+ *   또한 프로세스가 여전히 TASK_RUNNING 상태인 경우 sched_info_enqueue()를 
+ *   호출하여 이제 다시 실행 대기열에서 대기하기 시작했음을 표시합니다.
+ * - @t sched_info의 last_queued를 rq clock으로 update.
+ */
 static inline void sched_info_depart(struct rq *rq, struct task_struct *t)
 {
+/*
+ * IAMROOT, 2023.01.28:
+ * - delat는 대기큐에 있는동안의 시간이 될것이다.
+ */
     unsigned long long delta = rq_clock(rq) - t->sched_info.last_arrival;
 
     rq_sched_info_depart(rq, delta);
@@ -235,6 +286,14 @@ static inline void sched_info_depart(struct rq *rq, struct task_struct *t)
  * their time slice.  (This may also be called when switching to or from
  * the idle task.)  We are only called when prev != next.
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   작업이 일반적으로 타임 슬라이스 만료로 인해 비자발적으로 전환될 때 
+ *   호출됩니다. (유휴 작업으로 전환하거나 전환할 때 호출될 수도 있습니다.) 
+ *   prev != next일 때만 호출됩니다.
+ * - prev, next 각각의 cpu에서의 제거, 등록에 따른 sched_info를 기록한다.
+ */
 static inline void
 sched_info_switch(struct rq *rq, struct task_struct *prev, struct task_struct *next)
 {
@@ -243,6 +302,13 @@ sched_info_switch(struct rq *rq, struct task_struct *prev, struct task_struct *n
      * stats about how efficient we were at scheduling the idle
      * process, however.
      */
+/*
+ * IAMROOT, 2023.01.28:
+ * - papago
+ *   prev는 이제 CPU를 떠납니다. 그러나 유휴 프로세스를 예약하는 데 얼마나 
+ *   효율적이었는지에 대한 통계를 기록하는 것은 흥미롭지 않습니다.
+ * - prev, next가 idle task가 아니라면 해당 동작들을 한다.
+ */
     if (prev != rq->idle)
         sched_info_depart(rq, prev);
 
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index ed53d11a8dc5..234af0505042 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -577,6 +577,12 @@ void tick_nohz_dep_clear_signal(struct signal_struct *sig, enum tick_dep_bits bi
  * It might need the tick due to per task/process properties:
  * perf events, posix CPU timers, ...
  */
+/*
+ * IAMROOT, 2023.01.28:
+ * - nohz full은 보통 task가 한개일때의 얘기가 된다.
+ *   tick이 멈춰있는 상태이다.
+ * - nohz full을 해제한다.
+ */
 void __tick_nohz_task_switch(void)
 {
     struct tick_sched *ts;
 

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 623
185 [커널 18차] 93주차 kkr 2023.03.04 53
184 [커널 18차] 91주차 kkr 2023.02.18 95
183 [커널 19차] 39 주차 Min 2023.02.18 53
182 [커널 18차] 90주차 kkr 2023.02.13 63
181 [커널 19차] 38 주차 Min 2023.02.11 45
180 [커널 19차] 37 주차 Min 2023.02.04 478
179 [커널 19차] 36 주차 Min 2023.01.28 85
» [커널 18차] 88주차 kkr 2023.01.28 55
177 [커널 19차] 35 주차 Min 2023.01.14 93
176 [커널 17차] 120 ~ 121주차 ㅇㅇㅇ 2023.01.08 110
175 [커널 18차] 85주차 kkr 2023.01.07 53
174 [커널 19차] 34 주차 Min 2023.01.07 42
173 [커널 18차] 84주차 kkr 2022.12.31 104
172 [커널 19차] 33 주차 Min 2022.12.31 51
171 [커널 17차] 117 ~ 119주차 ㅇㅇㅇ 2022.12.25 61
170 [커널 19차] 31 주차 Min 2022.12.17 63
169 [커널 19차] 30 주차 Min 2022.12.10 61
168 [커널 17차] 112 ~ 116주차 ㅇㅇㅇ 2022.12.05 73
167 [커널 18차] 80주차 kkr 2022.12.03 156
166 [커널 19차] 28 ~ 29 주차 Min 2022.12.03 35
XE Login