[커널 18차] 66주차

2022.08.27 22:21

kkr 조회 수:76

clocksource, clockevents, timercounter, sched clock진행

 

git : https://github.com/iamroot18/5.10/commit/332a9ab0dc00a1bc2a967538827c1cb0260e624c

 

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index ae651007eca4..4dbb6c27703d 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -166,6 +166,10 @@ static inline u32 arch_timer_get_cntfrq(void)
     return read_sysreg(cntfrq_el0);
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - read cntkctl_el1
+ */
 static inline u32 arch_timer_get_cntkctl(void)
 {
     return read_sysreg(cntkctl_el1);
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 2b7de75a00e3..7d91d73c6166 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -71,6 +71,10 @@
 OUTPUT_ARCH(aarch64)
 ENTRY(_text)
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - jiffes 정의.
+ */
 jiffies = jiffies_64;
 
 #define HYPERVISOR_TEXT                    \
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 41815b33fdb5..4ade2757d06d 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -112,6 +112,11 @@ static enum vdso_clock_mode vdso_default = VDSO_CLOCKMODE_NONE;
 #endif /* CONFIG_GENERIC_GETTIMEOFDAY */
 
 static cpumask_t evtstrm_available = CPU_MASK_NONE;
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - config, early
+ */
 static bool evtstrm_enable __ro_after_init = IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM);
 
 static int __init early_evtstrm_cfg(char *buf)
@@ -180,6 +185,11 @@ u32 arch_timer_reg_read(int access, enum arch_timer_reg reg,
             break;
         }
     } else {
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - CP15
+ */
         val = arch_timer_reg_read_cp15(access, reg);
     }
 
@@ -680,6 +690,10 @@ static void arch_timer_check_ool_workaround(enum arch_timer_erratum_match_type t
         local ? "local" : "global", wa->desc);
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - read cntvct_el0
+ */
 static bool arch_timer_this_cpu_has_cntvct_wa(void)
 {
     return has_erratum_handler(read_cntvct_el0);
@@ -739,6 +753,10 @@ static irqreturn_t arch_timer_handler_virt_mem(int irq, void *dev_id)
     return timer_handler(ARCH_TIMER_MEM_VIRT_ACCESS, evt);
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - @access timer regiser 직접제어. disable.
+ */
 static __always_inline int timer_shutdown(const int access,
                       struct clock_event_device *clk)
 {
@@ -751,11 +769,19 @@ static __always_inline int timer_shutdown(const int access,
     return 0;
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - virt timer regiser 직접제어. disable.
+ */
 static int arch_timer_shutdown_virt(struct clock_event_device *clk)
 {
     return timer_shutdown(ARCH_TIMER_VIRT_ACCESS, clk);
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - phy timer regiser 직접제어. disable.
+ */
 static int arch_timer_shutdown_phys(struct clock_event_device *clk)
 {
     return timer_shutdown(ARCH_TIMER_PHYS_ACCESS, clk);
@@ -810,6 +836,10 @@ static int arch_timer_set_next_event_phys_mem(unsigned long evt,
     return 0;
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - @clk를 @type에 따라 초기화한다.
+ */
 static void __arch_timer_setup(unsigned type,
                    struct clock_event_device *clk)
 {
@@ -826,6 +856,11 @@ static void __arch_timer_setup(unsigned type,
         clk->rating = 450;
         clk->cpumask = cpumask_of(smp_processor_id());
         clk->irq = arch_timer_ppi[arch_timer_uses_ppi];
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - guest os일경우, virt 그외에 phy로 callback 함수를 등록한다.
+ */
         switch (arch_timer_uses_ppi) {
         case ARCH_TIMER_VIRT_PPI:
             clk->set_state_shutdown = arch_timer_shutdown_virt;
@@ -862,11 +897,28 @@ static void __arch_timer_setup(unsigned type,
         }
     }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - timer stop
+ */
     clk->set_state_shutdown(clk);
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - 15tick , 31bit로 clockevents의 최소 최대값을 설정한다.
+ *   (programming이 가능한 최소, 최대 틱)
+ */
     clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff);
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - divider를 EVNTI위치에 set. evt enable도 set한다.
+ * - ex) 19.2MHZ에서, eventi가 13일때(0b1101) 1초에 발생하는 event 횟수.
+ *   19200000 / 0x1000 = 4580
+ *   pulse가 raising edge에서만 동작한다고 했을때 4580 / 2 = 2343.
+ *   1초에 1171번 발생한다.
+ */
 static void arch_timer_evtstrm_enable(int divider)
 {
     u32 cntkctl = arch_timer_get_cntkctl();
@@ -880,6 +932,10 @@ static void arch_timer_evtstrm_enable(int divider)
     cpumask_set_cpu(smp_processor_id(), &evtstrm_available);
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - evt stream을 설정하고 enable한다.(wfe를 위한것.)
+ */
 static void arch_timer_configure_evtstream(void)
 {
     int evt_stream_div, lsb;
@@ -888,20 +944,44 @@ static void arch_timer_configure_evtstream(void)
      * As the event stream can at most be generated at half the frequency
      * of the counter, use half the frequency when computing the divider.
      */
+/*
+ * IAMROOT, 2022.08.27:
+ * - evt_stream_div = arch_timer_rate / 2000
+ *   arch_timer_rate = 19.2M이라고 했을대
+ *   evt_stream_div = 19200000 / 2000 = 9600
+ */
     evt_stream_div = arch_timer_rate / ARCH_TIMER_EVT_STREAM_FREQ / 2;
 
     /*
      * Find the closest power of two to the divisor. If the adjacent bit
      * of lsb (last set bit, starts from 0) is set, then we use (lsb + 1).
      */
+/*
+ * IAMROOT, 2022.08.27:
+ * - evt_stream_div & BIT(lsb - 1)
+ *   반올림 여부 판단.
+ *
+ * ex) evt_stream_div = 9600 = 0b10_0101_1000_0000
+ *                                ^반올림 체크
+ * fls(9600) = 14.
+ * lsb = 13 (반올림 안됨)
+ */
     lsb = fls(evt_stream_div) - 1;
     if (lsb > 0 && (evt_stream_div & BIT(lsb - 1)))
         lsb++;
 
     /* enable event stream */
+/*
+ * IAMROOT, 2022.08.27:
+ * - 최대 15bit까지만 가능.(ARCH_TIMER_EVT_TRIGGER_SHIFT 참고)
+ */
     arch_timer_evtstrm_enable(max(0, min(lsb, 15)));
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - ARCH_TIMER_USR_VCT_ACCESS_EN set이 가능한지 여부를 판단해 set한다.
+ */
 static void arch_counter_set_user_access(void)
 {
     u32 cntkctl = arch_timer_get_cntkctl();
@@ -939,6 +1019,10 @@ static bool arch_timer_has_nonsecure_ppi(void)
         arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - irq의 trigger flags를 얻어온다.
+ */
 static u32 check_ppi_trigger(int irq)
 {
     u32 flags = irq_get_trigger_type(irq);
@@ -952,6 +1036,14 @@ static u32 check_ppi_trigger(int irq)
     return flags;
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - arch_timer_register에서 CPUHP_AP_ARM_ARCH_TIMER_STARTING에서
+ *   call되는 함수.
+ *
+ * - ARCH_TIMER_TYPE_CP15 설정.
+ *   irq 설정.
+ */
 static int arch_timer_starting_cpu(unsigned int cpu)
 {
     struct clock_event_device *clk = this_cpu_ptr(arch_timer_evt);
@@ -959,9 +1051,19 @@ static int arch_timer_starting_cpu(unsigned int cpu)
 
     __arch_timer_setup(ARCH_TIMER_TYPE_CP15, clk);
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - arch_timer_uses_ppi에 대한 flags를 가져와서 percpu_irq를 등록한다.
+ */
     flags = check_ppi_trigger(arch_timer_ppi[arch_timer_uses_ppi]);
     enable_percpu_irq(arch_timer_ppi[arch_timer_uses_ppi], flags);
 
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - nonsecure_ppi가 있는경우 nonsecure_pp가 flags를 가져와서
+ *   percpu_irq를 등록한다.
+ */
     if (arch_timer_has_nonsecure_ppi()) {
         flags = check_ppi_trigger(arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI]);
         enable_percpu_irq(arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI],
@@ -969,6 +1071,10 @@ static int arch_timer_starting_cpu(unsigned int cpu)
     }
 
     arch_counter_set_user_access();
+/*
+ * IAMROOT, 2022.08.27:
+ * - default config enable.
+ */
     if (evtstrm_enable)
         arch_timer_configure_evtstream();
 
@@ -1080,6 +1186,10 @@ struct arch_timer_kvm_info *arch_timer_get_kvm_info(void)
 /*
  * IAMROOT, 2022.08.20:
  * @type arch_timers_present
+ * 1. clocksource
+ * 2. clockevents 
+ * 3. timercounter
+ * 4. sched clock
  */
 static void __init arch_counter_register(unsigned type)
 {
@@ -1123,7 +1233,8 @@ static void __init arch_counter_register(unsigned type)
 
 /*
  * IAMROOT, 2022.08.20:
- * - 
+ * - clocksource_counter에서 구한 mult, shift값으로 cyclecounter에 사용하고,
+ *   만들어진 cyclecounter를 arch_timer_kvm_info의 timecounter로 사용한다.
  */
     start_count = arch_timer_read_counter();
     clocksource_register_hz(&clocksource_counter, arch_timer_rate);
@@ -1133,6 +1244,10 @@ static void __init arch_counter_register(unsigned type)
              &cyclecounter, start_count);
 
     /* 56 bits minimum, so we assume worst case rollover */
+/*
+ * IAMROOT, 2022.08.27:
+ * - arch timer를 sched의 tick으로 사용하겠다는것.
+ */
     sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
 }
 
@@ -1386,6 +1501,10 @@ static bool __init arch_timer_needs_of_probing(void)
     return needs_probing;
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - timer common init.
+ */
 static int __init arch_timer_common_init(void)
 {
     arch_timer_banner(arch_timers_present);
@@ -1722,6 +1841,10 @@ static int __init arch_timer_mem_of_init(struct device_node *np)
     timer_mem->cntctlbase = res.start;
     timer_mem->size = resource_size(&res);
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - dts에서 정의된 frame_number를 가져와 각각의 number로 mem time을 설정한다.
+ */
     for_each_available_child_of_node(np, frame_node) {
         u32 n;
         struct arch_timer_mem_frame *frame;
@@ -1749,9 +1872,20 @@ static int __init arch_timer_mem_of_init(struct device_node *np)
             of_node_put(frame_node);
             goto out;
         }
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - register address 및 size설정
+ */
         frame->cntbase = res.start;
         frame->size = resource_size(&res);
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - virt irq, phys irq 설정. pcpu가 아닌 mem time이기 때문에 SPI를
+ *   (shared peri interrupt)
+ *   사용하는게 보인다.
+ */
         frame->virt_irq = irq_of_parse_and_map(frame_node,
                                ARCH_TIMER_VIRT_SPI);
         frame->phys_irq = irq_of_parse_and_map(frame_node,
diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h
index 300020ab4dca..cda340125cd4 100644
--- a/include/clocksource/arm_arch_timer.h
+++ b/include/clocksource/arm_arch_timer.h
@@ -56,14 +56,36 @@ enum arch_timer_spi_nr {
 #define ARCH_TIMER_MEM_MAX_FRAMES    8
 
 #define ARCH_TIMER_USR_PCT_ACCESS_EN    (1 << 0) /* physical counter */
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - el0(usere)에서 virtual counter로 직접 access가능하게 한다.
+ */
 #define ARCH_TIMER_USR_VCT_ACCESS_EN    (1 << 1) /* virtual counter */
 #define ARCH_TIMER_VIRT_EVT_EN        (1 << 2)
+
+/*
+ * IAMROOT, 2022.08.27:
+ * EVNTI, bits [7:4]
+ * Selects which bit of the counter register CNTVCT_EL0 is the trigger for the
+ * event stream generated from that counter, when that stream is enabled.
+ * If FEAT_ECV is implemented, and CNTKCTL_EL1.EVNTIS is 1, this field selects a
+ * trigger bit in the range 8 to 23 of the counter register CNTVCT_EL0.
+ * Otherwise, this field selects a trigger bit in the range 0 to 15 of
+ * the counter register.  The reset behavior of this field is:
+ * On a Warm reset, this field resets to an architecturally UNKNOWN value.
+ */
 #define ARCH_TIMER_EVT_TRIGGER_SHIFT    (4)
 #define ARCH_TIMER_EVT_TRIGGER_MASK    (0xF << ARCH_TIMER_EVT_TRIGGER_SHIFT)
 #define ARCH_TIMER_USR_VT_ACCESS_EN    (1 << 8) /* virtual timer registers */
 #define ARCH_TIMER_USR_PT_ACCESS_EN    (1 << 9) /* physical timer registers */
 
 #define ARCH_TIMER_EVT_STREAM_PERIOD_US    100
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - 1000000 / 100 = 1000
+ */
 #define ARCH_TIMER_EVT_STREAM_FREQ                \
     (USEC_PER_SEC / ARCH_TIMER_EVT_STREAM_PERIOD_US)
 
diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 8ae9a95ebf5b..27a4e3e69e12 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -189,6 +189,10 @@ extern void clockevents_config_and_register(struct clock_event_device *dev,
 
 extern int clockevents_update_freq(struct clock_event_device *ce, u32 freq);
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - mult, shift를 계산하여 알아온다.
+ */
 static inline void
 clockevents_calc_mult_shift(struct clock_event_device *ce, u32 freq, u32 maxsec)
 {
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 2b8c839c6768..5ce4c3706d18 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -93,7 +93,16 @@ struct module;
  * information you need you should consider to cache line align that
  * structure.
  */
+
 struct clocksource {
+/*
+ * IAMROOT, 2022.08.27:
+ * - __clocksource_update_freq_scale()에서
+ *   mask, mult, shift, max_idle_ns, maxadj, uncertainty_margin, max_cycles
+ *   이 초기화 된다.
+ * - clocks_calc_max_nsecs()를 사용하여 ns값을 계산한다.
+ *   ex) clocks_calc_max_nsecs(mult, shift, maxadj, mask, max_cycles)
+ */
     u64            (*read)(struct clocksource *cs);
     u64            mask;
     u32            mult;
@@ -105,6 +114,11 @@ struct clocksource {
     struct arch_clocksource_data archdata;
 #endif
     u64            max_cycles;
+/*
+ * IAMROOT, 2022.08.27:
+ * - struct clocksource정의시, rate, name, id, read, mask, flags등이 미리
+ *   정의된다.(arm_arch_timer.c clocksource_counter 참고)
+ */
     const char        *name;
     struct list_head    list;
     int            rating;
@@ -201,6 +215,11 @@ static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
  *
  * XXX - This could use some mult_lxl_ll() asm optimization
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - (from * mult) >> shift = to
+ * - cycles값을 nanosecond로 치환한다.
+ */
 static inline s64 clocksource_cyc2ns(u64 cycles, u32 mult, u32 shift)
 {
     return ((u64) cycles * mult) >> shift;
@@ -243,7 +262,8 @@ static inline int __clocksource_register(struct clocksource *cs)
 
 /*
  * IAMROOT, 2022.08.20:
- * - 
+ * - from * factor >> shift = to
+ *   to 값을 @hz로 사용해 factor를 구하고 @cs를 초기화한다.
  */
 static inline int clocksource_register_hz(struct clocksource *cs, u32 hz)
 {
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 5e13f801c902..5d85ffb15800 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -76,6 +76,13 @@ extern int register_refined_jiffies(long clock_tick_rate);
  * without sampling the sequence number in jiffies_lock.
  * get_jiffies_64() will do this for you as appropriate.
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - jiffies    : kernel/time/jiffies.c에 export symbol
+ *                arm/arm64/kernel/vmlinux.lkds.S에서
+ *                jiffies_64를 jiffies로 사용하는것이 확인된다.
+ * - jiffies_64 : kernel/time/timer.c 
+ */
 extern u64 __cacheline_aligned_in_smp jiffies_64;
 extern unsigned long volatile __cacheline_aligned_in_smp __jiffy_arch_data jiffies;
 
@@ -170,6 +177,10 @@ static inline u64 get_jiffies_64(void)
  * Have the 32 bit jiffies value wrap 5 minutes after boot
  * so jiffies wrap bugs show up earlier.
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - -5분. bug를 찾기 위한 용도.
+ */
 #define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
 
 /*
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index 73f20deb497d..27153383448e 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -219,6 +219,10 @@ static inline __must_check bool ktime_to_timespec64_cond(const ktime_t kt,
 
 #include <vdso/ktime.h>
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - ktime은 ns로 사용하니 즉시 return. 부호 여부.
+ */
 static inline ktime_t ns_to_ktime(u64 ns)
 {
     return ns;
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
index 749b174ef2f2..ef6f6a293bca 100644
--- a/include/linux/seqlock.h
+++ b/include/linux/seqlock.h
@@ -692,6 +692,13 @@ typedef struct {
  * picking which data copy to read. The full counter must then be checked
  * with read_seqcount_latch_retry().
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - papgo
+ *   시퀀스 카운터 원시 값. 읽을 데이터 복사본을 선택하기 위한 인덱스로
+ *   가장 낮은 비트를 사용합니다. 그런 다음 전체 카운터를
+ *   read_seqcount_latch_retry()로 확인해야 합니다 
+ */
 static inline unsigned raw_read_seqcount_latch(const seqcount_latch_t *s)
 {
     /*
@@ -795,6 +802,82 @@ read_seqcount_latch_retry(const seqcount_latch_t *s, unsigned start)
  *    When data is a dynamic data structure; one should use regular RCU
  *    patterns to manage the lifetimes of the objects within.
  */
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - papgo
+ *   aw_write_seqcount_latch() - 래치 판독기를 짝수/홀수 사본 @s로 리디렉션:
+ *   seqcount_latch_t에 대한 포인터 래치 기술은 원자가 아닌 수정 중에
+ *   쿼리를 허용하는 다중 버전 동시성 제어 방법입니다. 쿼리가 수정을
+ *   중단하지 않도록 보장할 수 있다면 -- 예를 들어 동시성은 CPU 간에
+ *   엄격하게 이루어지므로 필요하지 않을 가능성이 큽니다.
+ *
+ *   기존의 RCU/잠금 없는 데이터 구조가 원자적 수정에 의존하여 쿼리가 이전
+ *   또는 새 상태를 관찰하도록 보장하는 경우 래치가 비원자 업데이트에 대해
+ *   동일한 것을 허용합니다. 절충안은 스토리지 비용을 두 배로 늘립니다.
+ *   전체 데이터 구조의 두 복사본을 유지해야 합니다.
+ *
+ *   아주 간단히 말해서:
+ *   먼저 한 사본을 수정한 다음 다른 사본을 수정합니다. 이것은 우리에게
+ *   답을 줄 준비가 된 안정적인 상태의 사본이 항상 하나 있음을 보장합니다.
+ *
+ *   기본 형식은 다음과 같은 데이터 구조입니다.
+ *    struct latch_struct {
+ *        seqcount_latch_t    seq;
+ *        struct data_struct    data[2];
+ *    };
+ *
+ *   외부 직렬화를 전제로 하는 수정 사항은 다음과 같습니다::
+ *
+ *    void latch_modify(struct latch_struct *latch, ...)
+ *    {
+ *        smp_wmb();    // Ensure that the last data[1] update is visible
+ *        latch->seq.sequence++;
+ *        smp_wmb();    // Ensure that the seqcount update is visible
+ *
+ *        modify(latch->data[0], ...);
+ *
+ *        smp_wmb();    // Ensure that the data[0] update is visible
+ *        latch->seq.sequence++;
+ *        smp_wmb();    // Ensure that the seqcount update is visible
+ *
+ *        modify(latch->data[1], ...);
+ *    }
+ *
+ * The query will have a form like::
+ *
+ *    struct entry *latch_query(struct latch_struct *latch, ...)
+ *    {
+ *        struct entry *entry;
+ *        unsigned seq, idx;
+ *
+ *        do {
+ *            seq = raw_read_seqcount_latch(&latch->seq);
+ *
+ *            idx = seq & 0x01;
+ *            entry = data_query(latch->data[idx], ...);
+ *
+ *        // This includes needed smp_rmb()
+ *        } while (read_seqcount_latch_retry(&latch->seq, seq));
+ *
+ *        return entry;
+ *    }
+ *
+ *  따라서 수정하는 동안 쿼리는 먼저 data[1]로 리디렉션됩니다. 그런 다음
+ *  데이터[0]을 수정합니다. 완료되면 쿼리를 다시 data[0]으로 리디렉션하고
+ *  data[1]을 수정할 수 있습니다.
+ *
+ *  노트:
+ *  원자적 수정에 대한 비요구 사항은 데이터가 동적 데이터 구조인 경우
+ *  새 항목의 게시를 포함하지 않는다.
+ *
+ *  반복은 data[0]에서 시작하고 전체 수정 시퀀스를 놓칠 만큼 충분히
+ *  오래 일시 중단될 수 있습니다. 다시 시작하면 새 항목이 관찰될 수
+ *  있습니다.
+ *
+ *  노트 2: 데이터가 동적 데이터 구조인 경우 내부 개체의 수명을 관리하려면
+ *  일반 RCU 패턴을 사용해야 합니다.
+ */
 static inline void raw_write_seqcount_latch(seqcount_latch_t *s)
 {
     smp_wmb();    /* prior stores before incrementing "sequence" */
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 003ccf338d20..61eb67d4fd16 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -29,20 +29,47 @@ struct ce_unbind {
     int res;
 };
 
+/*
+ * IAMROOT, 2022.08.27:
+ * @return 최솟값이 1000ns이상인 latch -> ns 변환값.
+ * - @evt의 mult, shift값을 사용해 latch의 ns를 구해온다.
+ * - ex) mult = 0xdd2_f1aa, shift = 32
+ *   1. latch = 0xf = > 숫자가 작기때문에 1000
+ *   2. latch = 0x7fffffff
+ *    clc = 0x7fffffff = 0x7fffffff_0000_0000
+ *    rnd = mult - 1 = 0xdd2_f1a9
+ *    clc += rnd ==> clc = 0x7fffffff_0dd2_f1a9
+ *    clc = clc / 0xdd2_f1a9
+ *        = 39768215854 (ns)
+ *        = 39 (sec)
+ */
 static u64 cev_delta2ns(unsigned long latch, struct clock_event_device *evt,
             bool ismax)
 {
+/*
+ * IAMROOT, 2022.08.27:
+ * - clc = (정확도가 고려된 cycle)
+ *   mult = (정확도가 고려된 1 ns당 cycle 개수)
+ */
     u64 clc = (u64) latch << evt->shift;
     u64 rnd;
 
     if (WARN_ON(!evt->mult))
         evt->mult = 1;
+/*
+ * IAMROOT, 2022.08.27:
+ * - 반올 손상 보정.
+ */
     rnd = (u64) evt->mult - 1;
 
     /*
      * Upper bound sanity check. If the backwards conversion is
      * not equal latch, we know that the above shift overflowed.
      */
+/*
+ * IAMROOT, 2022.08.27:
+ * - overflow check. 
+ */
     if ((clc >> evt->shift) != (u64)latch)
         clc = ~0ULL;
 
@@ -65,6 +92,26 @@ static u64 cev_delta2ns(unsigned long latch, struct clock_event_device *evt,
      *
      * Also omit the add if it would overflow the u64 boundary.
      */
+/*
+ * IAMROOT, 2022.08.27:
+ * - papago
+ *   스케일링된 수학 기이함:
+ *   mult <= (1 << shift)의 경우 정수 반올림 손실을 방지하기 위해 mult - 1을
+ *   안전하게 추가할 수 있습니다. 따라서 nsec에서 장치 틱으로의 역변환은
+ *   정확할 것입니다.
+ *
+ *   mult > (1 << shift), 즉 장치 주파수가 > 1GHz인 경우 주의해야 합니다.
+ *   mult - 1을 추가하면 장치 틱으로 다시 변환될 때 최대
+ *   (mult - 1) >> shift만큼 래치보다 클 수 있는 값이 생성됩니다. min_delta
+ *   계산의 경우 최소 장치 틱 제한 이상을 유지하기 위해 여전히 이를 적용하려고
+ *   합니다. 상한선의 경우 장치의 상한선보다 큰 래치 값으로 끝나므로 장치
+ *   상한선 아래에 머물기 위해 추가를 생략합니다.
+ *
+ *   또한 u64 경계를 넘을 경우 추가를 생략합니다.
+ *
+ * - 반올림을 계산한다. 이 계산으로 인한 상한값 overflow가 발생안하게 하기위한
+ *   예외처리.
+ */
     if ((~0ULL - clc > rnd) &&
         (!ismax || evt->mult <= (1ULL << evt->shift)))
         clc += rnd;
@@ -340,6 +387,10 @@ int clockevents_program_event(struct clock_event_device *dev, ktime_t expires,
  * Called after a notify add to make devices available which were
  * released from the notifier call.
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - TODO
+ */
 static void clockevents_notify_released(void)
 {
     struct clock_event_device *dev;
@@ -440,6 +491,10 @@ EXPORT_SYMBOL_GPL(clockevents_unbind_device);
  * clockevents_register_device - register a clock event device
  * @dev:    device to register
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - cpumask 검사, state 변경. clock event 등록
+ */
 void clockevents_register_device(struct clock_event_device *dev)
 {
     unsigned long flags;
@@ -447,6 +502,10 @@ void clockevents_register_device(struct clock_event_device *dev)
     /* Initialize state to DETACHED */
     clockevent_set_state(dev, CLOCK_EVT_STATE_DETACHED);
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - cpumask가 지정이 안되있으면 현재 cpu만. all cpu면 possible로 지정한다.
+ */
     if (!dev->cpumask) {
         WARN_ON(num_possible_cpus() > 1);
         dev->cpumask = cpumask_of(smp_processor_id());
@@ -468,6 +527,10 @@ void clockevents_register_device(struct clock_event_device *dev)
 }
 EXPORT_SYMBOL_GPL(clockevents_register_device);
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - @dev가 @freq로 지원하는 min / max nsec를 구한다.
+ */
 static void clockevents_config(struct clock_event_device *dev, u32 freq)
 {
     u64 sec;
@@ -487,7 +550,16 @@ static void clockevents_config(struct clock_event_device *dev, u32 freq)
     else if (sec > 600 && dev->max_delta_ticks > UINT_MAX)
         sec = 600;
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - @dev의 mult, shift값을 계산해온다.
+ */
     clockevents_calc_mult_shift(dev, freq, sec);
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - min, max tick을 가지고 nsec를 구한다.
+ */
     dev->min_delta_ns = cev_delta2ns(dev->min_delta_ticks, dev, false);
     dev->max_delta_ns = cev_delta2ns(dev->max_delta_ticks, dev, true);
 }
@@ -501,6 +573,11 @@ static void clockevents_config(struct clock_event_device *dev, u32 freq)
  *
  * min/max_delta can be 0 for devices which do not support oneshot mode.
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - clockevents의 @freq, 최대최소 nsec를 설정하고 시슷템에 clock event를
+ *   등록한다.
+ */
 void clockevents_config_and_register(struct clock_event_device *dev,
                      u32 freq, unsigned long min_delta,
                      unsigned long max_delta)
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index d7082bc17fc4..fab45863c9d1 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -49,6 +49,8 @@
  * - sftacc 계산
  *   600 * 19200000 = 0x2_AEA5_4000 => shift32 => 0x2
  *   두번 loop를 돌면 sftacc = 30가 된다.
+ *
+ * - 이진화 정수화.
  */
 void
 clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 maxsec)
@@ -56,7 +58,7 @@ clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 maxsec)
     u64 tmp;
 /*
  * IAMROOT, 2022.08.20:
- * - 정확도는 최대 32bit.
+ * - 이진화 정확도는 최대 32bit.
  */
     u32 sft, sftacc= 32;
 
@@ -113,9 +115,26 @@ clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 maxsec)
  * tmp = do_div(16777216000000000,  19200000) = 873813333 = 0x3415_5555
  * tmp >> sftasce = 0x3415_5555 >> 30 == 0
  * mult = 0x3415_5555, shift = 24가 된다.
+ *
+ * - ex) 0.1을 이진화 정수화.
+ *
+ *   0            | (0.1에 대한 값)
+ *
+ *   0.1 * 2 = 0.2 -> 0
+ *   0.2 * 2 = 0.4 -> 0
+ *   0.4 * 2 = 0.8 -> 0
+ *   0.8 * 2 = 1.6 -> 1
+ *    .------- 0.6
+ *   0.6 * 2 = 1.2 -> 1
+ *   0.2 * 2 = 0.4 -> 0
  */
     for (sft = 32; sft > 0; sft--) {
         tmp = (u64) to << sft;
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - round up
+ */
         tmp += from / 2;
         do_div(tmp, from);
         if ((tmp >> sftacc) == 0)
@@ -869,6 +888,10 @@ void clocksource_touch_watchdog(void)
  * @cs:         Pointer to clocksource
  *
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - mult의 0.11배값을 return.
+ */
 static u32 clocksource_max_adjustment(struct clocksource *cs)
 {
     u64 ret;
@@ -895,6 +918,20 @@ static u32 clocksource_max_adjustment(struct clocksource *cs)
  * delayed timers or bad hardware, which might result in time intervals that
  * are larger than what the math used can handle without overflows.
  */
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - papago
+ *   이 함수에는 50%의 safety margin가 포함됩니다. 즉, 하드웨어 카운터가 기술적으로
+ *   처리할 수 있는 나노초 수의 절반을 반환합니다. 이는 지연된 타이머 또는 잘못된
+ *   하드웨어로 인해 발생하는 문제를 잠재적으로 감지할 수 있도록 하기 위해 수행되며,
+ *   이로 인해 사용된 수학이 오버플로 없이 처리할 수 있는 것보다 더 큰 시간 간격이
+ *   발생할 수 있습니다.
+ */
+/*
+ * IAMROOT, 2022.08.27:
+ * - overlfow가 발생할수있는 제한을 구한다.
+ */
 u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cyc)
 {
     u64 max_nsecs, max_cycles;
@@ -903,6 +940,10 @@ u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cy
      * Calculate the maximum number of cycles that we can pass to the
      * cyc2ns() function without overflowing a 64-bit result.
      */
+/*
+ * IAMROOT, 2022.08.27:
+ * - max_cycles = UNLLONG_MAX / (mult + maxadj)
+ */
     max_cycles = ULLONG_MAX;
     do_div(max_cycles, mult+maxadj);
 
@@ -912,7 +953,24 @@ u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cy
      * Note: Here we subtract the maxadj to make sure we don't sleep for
      * too long if there's a large negative adjustment.
      */
+/*
+ * IAMROOT, 2022.08.27:
+ * - papago
+ *   클럭 소스를 연기할 수 있는 실제 최대 사이클 수는 max_cycles와
+ *   마스크의 최소값에 의해 결정됩니다.
+ *   note:
+ *   여기서 우리는 큰 음수 조정이 있는 경우 너무 오랫동안 잠을 자지
+ *   않도록 maxadj를 뺍니다. 
+ *
+ * - mask값(ex. arm arch timer CLOCKSOURCE_MASK(56)과 min 비교를 한다.
+ *   즉 mask값보다 높은 값을 사용하지 않겟다는것.
+ */
     max_cycles = min(max_cycles, mask);
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - max_cyc값에 해당하는 max_nsecs값을 구한다
+ */
     max_nsecs = clocksource_cyc2ns(max_cycles, mult - maxadj, shift);
 
     /* return the max_cycles value as well if requested */
@@ -930,6 +988,10 @@ u64 clocks_calc_max_nsecs(u32 mult, u32 shift, u32 maxadj, u64 mask, u64 *max_cy
  * @cs:         Pointer to clocksource to be updated
  *
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - overflow당하지 않을 cycle값과 ns값을 구한다.
+ */
 static inline void clocksource_update_max_deferment(struct clocksource *cs)
 {
     cs->max_idle_ns = clocks_calc_max_nsecs(cs->mult, cs->shift,
@@ -1079,6 +1141,11 @@ static void clocksource_enqueue(struct clocksource *cs)
  * __clocksource_update_freq_hz() or __clocksource_update_freq_khz() helper
  * functions.
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - @cs에 대한 mult, shift값을 구하고 margin, adj, max_idle_ns,
+ *   max_cycles 값을 구한다.
+ */
 void __clocksource_update_freq_scale(struct clocksource *cs, u32 scale, u32 freq)
 {
     u64 sec;
@@ -1142,6 +1209,22 @@ void __clocksource_update_freq_scale(struct clocksource *cs, u32 scale, u32 freq
      * to be specified by the caller for testing purposes, but warn
      * to discourage production use of this capability.
      */
+/*
+ * IAMROOT, 2022.08.27:
+ * - papgo
+ *   불확실성 마진이 지정되지 않은 경우 계산합니다. scale과 freq가 모두 0이 아닌 경우 클록 주기를
+ *   계산하지만 2*WATCHDOG_MAX_SKEW에서 아래로 제한됩니다. 그러나 scale 또는 freq 중 하나가 0이면
+ *   매우 보수적이며 불확실성 마진에 대해 수십 밀리초 WATCHDOG_THRESHOLD 값을 사용합니다. 테스트
+ *   목적으로 호출자가 지정하는 어리석게 작은 불확실성 마진을 허용하지만 이 기능의 프로덕션
+ *   사용을 권장하지 않도록 경고합니다.
+ */
+/*
+ * IAMROOT, 2022.08.27:
+ * - cs->uncertainty_margin이 0인 경우
+ *   scale, freq둘다 0이 아니면 계산. 그렇지 않은경우 고정값 사용.
+ * - 1초에대한 margin값을 정의 하는것.
+ *   ex) margin이 0.1이라고 하면 0.9 ~ 1.1 사이값이 오면 1초라고 생각한다는것.
+ */
     if (scale && freq && !cs->uncertainty_margin) {
         cs->uncertainty_margin = NSEC_PER_SEC / (scale * freq);
         if (cs->uncertainty_margin < 2 * WATCHDOG_MAX_SKEW)
@@ -1156,6 +1239,11 @@ void __clocksource_update_freq_scale(struct clocksource *cs, u32 scale, u32 freq
      * when adjusted.
      */
     cs->maxadj = clocksource_max_adjustment(cs);
+/*
+ * IAMROOT, 2022.08.27:
+ * - adj값을 계산하고 계산된 mult에 적용해봐서 overflow, underflow가 안될때까지
+ *   재조정한다.
+ */
     while (freq && ((cs->mult + cs->maxadj < cs->mult)
         || (cs->mult - cs->maxadj > cs->mult))) {
         cs->mult >>= 1;
@@ -1171,8 +1259,23 @@ void __clocksource_update_freq_scale(struct clocksource *cs, u32 scale, u32 freq
         "timekeeping: Clocksource %s might overflow on 11%% adjustment\n",
         cs->name);
 
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - overflow당하지 않은 제한값(cs->max_idle_ns)을 구한다.
+ */
     clocksource_update_max_deferment(cs);
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - ex) x64 ubuntu
+ *   clocksource: tsc: mask: 0xffffffffffffffff
+ *   max_cycles: 0x6d581b92771, max_idle_ns: 881590605997 ns
+ * - 위 예제로 봤을때 600초를 제한으로 했지만, 881초까지 여유를 두는것이
+ *   확인된다.
+ *   881초도 50%줄인 숫자(max_idle_ns)이고, 실제로는 max_cycles에 있는
+ *   881 * 2초 만큼 버티게된다.
+ */
     pr_info("%s: mask: 0x%llx max_cycles: 0x%llx, max_idle_ns: %lld ns\n",
         cs->name, cs->mask, cs->max_cycles, cs->max_idle_ns);
 }
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
index bc4db9e5ab70..c073ad67d6d4 100644
--- a/kernel/time/jiffies.c
+++ b/kernel/time/jiffies.c
@@ -59,6 +59,12 @@ u64 get_jiffies_64(void)
 EXPORT_SYMBOL(get_jiffies_64);
 #endif
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - jiffes를 export symbol한다.
+ *   jiffes는 arch/arm64/kernel/vmlinux.lds.S.
+ *   실제 위치는 kernel/time/jiffies.c
+ */
 EXPORT_SYMBOL(jiffies);
 
 static int __init init_jiffies_clocksource(void)
diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c
index b1b9b12899f5..a7d203537bea 100644
--- a/kernel/time/sched_clock.c
+++ b/kernel/time/sched_clock.c
@@ -36,6 +36,10 @@
  */
 struct clock_data {
     seqcount_latch_t    seq;
+/*
+ * IAMROOT, 2022.08.27:
+ * - update_clock_read_data() 주석참고
+ */
     struct clock_read_data    read_data[2];
     ktime_t            wrap_kt;
     unsigned long        rate;
@@ -48,16 +52,28 @@ static int irqtime = -1;
 
 core_param(irqtime, irqtime, int, 0400);
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - system에서 사용하는 기본 clock.
+ */
 static u64 notrace jiffy_sched_clock_read(void)
 {
     /*
      * We don't need to use get_jiffies_64 on 32-bit arches here
      * because we register with BITS_PER_LONG
      */
+/*
+ * IAMROOT, 2022.08.27:
+ * - -5분 offset을 원복하는 개념.
+ */
     return (u64)(jiffies - INITIAL_JIFFIES);
 }
 
 static struct clock_data cd ____cacheline_aligned = {
+/*
+ * IAMROOT, 2022.08.27:
+ * - mult = 1clock당 nanosec
+ */
     .read_data[0] = { .mult = NSEC_PER_SEC / HZ,
               .read_sched_clock = jiffy_sched_clock_read, },
     .actual_read_sched_clock = jiffy_sched_clock_read,
@@ -106,6 +122,42 @@ unsigned long long notrace sched_clock(void)
  * as possible the system reverts back to the even copy when the update
  * completes; the odd copy is used *only* during an update.
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - papago
+ *   clock을 읽는 데 필요한 데이터 업데이트.
+ *   sched_clock()은 NMI에서 호출되더라도 일치하지 않는 데이터를 관찰하지
+ *   않습니다. 데이터의 홀수/짝수 복사본을 유지하고 시퀀스 카운터를 사용하여
+ *   sched_clock()을 하나 또는 다른 것으로 조정하여 이를 수행합니다.
+ *   sched_clock()의 데이터 캐시 프로필을 최대한 유지하기 위해 업데이트가
+ *   완료되면 시스템이 짝수 복사본으로 되돌아갑니다. 홀수 복사본은 업데이트
+ *   *중*에만 사용됩니다
+ *
+ * - clock이 바뀌고 있는 와중에, 다른 cpu등에서 참조를 할수있다.
+ *   특히 nmi같은 경우엔 lockless가 필수적인데 이러한 상황을 고려하여
+ *   seqcount latch방법을 사용한다.
+ *
+ * - ex) seq = 0인 상황
+ *
+ * 1. 평소 상태. seq는 무조건 짝수일것.(seq = 0, 2, 4..)
+ *   read_data[0]         read_data[1]
+ *   ^평소에 읽는 data    ^갱신을 할때만 읽게하는 data
+ *
+ * 2. read_data[1]을 write. 시작. (seq = 0, 2, 4..)
+ *
+ *                        갱신 진행중
+ *   read_data[0]         read_data[1]
+ *   ^seq&1로 접근.
+ *
+ * 3. read_data[1] 갱신 완료. seq++ (seq = 1, 3, 5..)
+ *    read_data[0] 갱신 시작.
+ *
+ *   갱신 진행중          이미 갱신된상태
+ *   read_data[0]         read_data[1]
+ *   ^write중             ^seq&1 로 읽음.
+ *
+ * 4. read_data[0] 갱신완료. seq++ (seq = 0, 2, 4..) 1.번으로 복귀.
+ */
 static void update_clock_read_data(struct clock_read_data *rd)
 {
     /* update the backup (odd) copy with the new data */
@@ -141,6 +193,11 @@ static void update_sched_clock(void)
     update_clock_read_data(&rd);
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - clock을 update해주고 다시 timer를 가동한다.
+ *   1시간 주기로 동작을 할것이다.
+ */
 static enum hrtimer_restart sched_clock_poll(struct hrtimer *hrt)
 {
     update_sched_clock();
@@ -149,6 +206,12 @@ static enum hrtimer_restart sched_clock_poll(struct hrtimer *hrt)
     return HRTIMER_RESTART;
 }
 
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - @cd를 재계산한다. sched에 사용할 clocksource를 갱신한다.
+ * - sche tick은 아주 높은 정밀도는 필요없다.
+ */
 void __init
 sched_clock_register(u64 (*read)(void), int bits, unsigned long rate)
 {
@@ -158,6 +221,10 @@ sched_clock_register(u64 (*read)(void), int bits, unsigned long rate)
     char r_unit;
     struct clock_read_data rd;
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - 이 함수는 여러번 call될수있다. 가장 높은 rate로 갱신한다는것.
+ */
     if (cd.rate > rate)
         return;
 
@@ -165,12 +232,20 @@ sched_clock_register(u64 (*read)(void), int bits, unsigned long rate)
     local_irq_save(flags);
 
     /* Calculate the mult/shift to convert counter ticks to ns. */
+/*
+ * IAMROOT, 2022.08.27:
+ * - 3600초로 mult shift를 계산한다.
+ */
     clocks_calc_mult_shift(&new_mult, &new_shift, rate, NSEC_PER_SEC, 3600);
 
     new_mask = CLOCKSOURCE_MASK(bits);
     cd.rate = rate;
 
     /* Calculate how many nanosecs until we risk wrapping */
+/*
+ * IAMROOT, 2022.08.27:
+ * - 1바퀴란 의미의 wrap. 1주기에 대한 시간 계산.
+ */
     wrap = clocks_calc_max_nsecs(new_mult, new_shift, 0, new_mask, NULL);
     cd.wrap_kt = ns_to_ktime(wrap);
 
@@ -179,6 +254,14 @@ sched_clock_register(u64 (*read)(void), int bits, unsigned long rate)
     /* Update epoch for new counter and update 'epoch_ns' from old counter*/
     new_epoch = read();
     cyc = cd.actual_read_sched_clock();
+
+/*
+ * IAMROOT, 2022.08.27:
+ * - clock 속도는 기본적으로 높고(ex 54000000Hz) sche clck은 1000hz이다.
+ *
+ * - new_epoch = old_epoch_ns + cyc_to_ns(curr_cyc - old_cyc)
+ * - A clock과 B clock간에 격차를 줄이기 위한 작업을 한다.
+ */
     ns = rd.epoch_ns + cyc_to_ns((cyc - rd.epoch_cyc) & rd.sched_clock_mask, rd.mult, rd.shift);
     cd.actual_read_sched_clock = read;
 
@@ -189,8 +272,22 @@ sched_clock_register(u64 (*read)(void), int bits, unsigned long rate)
     rd.epoch_cyc        = new_epoch;
     rd.epoch_ns        = ns;
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - 새로만든 rd를 cd에 update한다.
+ */
     update_clock_read_data(&rd);
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - wrap이 끝나기 전에 wrap_kt시간으로 자동으로 갱신해준다. 
+ * - no hz에 대비한 갱신. 
+ *   예를들어 cpu0가 잠들어있는 중에 변경이되면 overflow가 발생할수있으므로
+ *   이를 예방하는것이다.
+ * - nohz(sche tick이 필요없는 상태).
+ *   nohz idle : task가 절전상태.
+ *   nohz full : task가 한개만 동작중.
+ */
     if (sched_clock_timer.function != NULL) {
         /* update timeout for clock wrap */
         hrtimer_start(&sched_clock_timer, cd.wrap_kt,
@@ -213,6 +310,13 @@ sched_clock_register(u64 (*read)(void), int bits, unsigned long rate)
     /* Calculate the ns resolution of this counter */
     res = cyc_to_ns(1ULL, new_mult, new_shift);
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - ex)x64 pc ubuntu에서의 qemu
+ *   sched_clock: 56 bits at 62MHz, resolution 16ns,
+ *   wraps every 4398 046 511 096ns
+ *   4398초마다 깨어나서 자동 갱신한다는것.
+ */
     pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lluns\n",
         bits, r, r_unit, res, wrap);
 
@@ -256,6 +360,17 @@ void __init generic_sched_clock_init(void)
  * at the end of the critical section to be sure we observe the
  * correct copy of 'epoch_cyc'.
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - papago
+ *   clock이 정지되었을 때 사용하는 clock 읽기 기능.
+ *   이 함수는 clock이 마지막 업데이트에서 계산을 멈춘 것처럼 sched_clock()에
+ *   표시되도록 합니다. 
+ *
+ *   이 함수는 sched_clock()의 크리티컬 섹션에서만 호출해야 합니다.
+ *   'epoch_cyc'의 올바른 복사본을 관찰하기 위해 중요한 섹션 끝에 있는
+ *   read_seqcount_retry()에 의존합니다.
+ */
 static u64 notrace suspended_sched_clock_read(void)
 {
     unsigned int seq = raw_read_seqcount_latch(&cd.seq);
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 46789356f856..4d3756a801d3 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -25,6 +25,10 @@
 /*
  * Tick devices
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - sche tick. 
+ */
 DEFINE_PER_CPU(struct tick_device, tick_cpu_device);
 /*
  * Tick next event: keeps track of the tick time. It's updated by the
@@ -338,6 +342,10 @@ bool tick_check_replacement(struct clock_event_device *curdev,
  * Check, if the new registered device should be used. Called with
  * clockevents_lock held and interrupts disabled.
  */
+/*
+ * IAMROOT, 2022.08.27:
+ * - TODO
+ */
 void tick_check_new_device(struct clock_event_device *newdev)
 {
     struct clock_event_device *curdev;
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index 649f2b48e8f0..3a6176519ba3 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -41,6 +41,10 @@ static inline enum clock_event_state clockevent_get_state(struct clock_event_dev
     return dev->state_use_accessors;
 }
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - @state로 설정한다.
+ */
 static inline void clockevent_set_state(struct clock_event_device *dev,
                     enum clock_event_state state)
 {
diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c
index e6285288d765..802946cd1f75 100644
--- a/kernel/time/timecounter.c
+++ b/kernel/time/timecounter.c
@@ -5,6 +5,10 @@
 #include <linux/export.h>
 #include <linux/timecounter.h>
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - @cc로 @tc를 초기화한다.
+ */
 void timecounter_init(struct timecounter *tc,
               const struct cyclecounter *cc,
               u64 start_tstamp)
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index e3d2c23c413d..3a68f23b6786 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -56,6 +56,10 @@
 #define CREATE_TRACE_POINTS
 #include <trace/events/timer.h>
 
+/*
+ * IAMROOT, 2022.08.27:
+ * - jiffies_64 정의.
+ */
 __visible u64 jiffies_64 __cacheline_aligned_in_smp = INITIAL_JIFFIES;
 
 EXPORT_SYMBOL(jiffies_64);
 

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 626
148 [커널 17차] 103주차 ㅇㅇㅇ 2022.08.28 35
» [커널 18차] 66주차 kkr 2022.08.27 76
146 [커널 17차] 101~102주차 ㅇㅇㅇ 2022.08.21 47
145 [커널 18차] 65주차 kkr 2022.08.20 28
144 [커널 18차] 64주차 kkr 2022.08.13 75
143 [커널 17차] 100주차 [1] ㅇㅇㅇ 2022.08.06 100
142 [커널 18차] 63주차 kkr 2022.08.06 102
141 [커널 17차] 99주차 ㅇㅇㅇ 2022.07.31 35
140 [커널 18차] 62주차 kkr 2022.07.30 26
139 [커널 17차] 97~98주차 ㅇㅇㅇ 2022.07.24 52
138 [커널 18차] 61주차 kkr 2022.07.23 113
137 [커널 18차] 60주차 kkr 2022.07.16 129
136 [커널 17차] 95~96주차 ㅇㅇㅇ 2022.07.10 105
135 [커널 18차] 59주차 kkr 2022.07.09 126
134 [커널 19차] 8주차 kanlee 2022.07.02 160
133 [커널 19차] 7주차 kanlee 2022.07.02 95
132 [커널 19차] 6주차 kanlee 2022.07.02 42
131 [커널 19차] 5주차 kanlee 2022.07.02 38
130 [커널 19차] 4주차 kanlee 2022.07.02 106
129 [커널 18차] 57주차 kkr 2022.06.25 129
XE Login