[커널 18차] 70주차

2022.09.24 22:14

kkr 조회 수:77

hrtimer 진행

git : https://github.com/iamroot18/5.10/commit/893cf3736b05a7bcf8f63b333e422b47f4976dd8

 

diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index df0121d127d6..575be407c243 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -123,6 +123,14 @@ enum hrtimer_restart {
  */
 struct hrtimer {
     struct timerqueue_node        node;
+
+/*
+ * IAMROOT, 2022.09.24:
+ *  
+ * - slack --|---------------|---
+ *           ^               ^
+ *           _softexpires    node.expires
+ */
     ktime_t                _softexpires;
     enum hrtimer_restart        (*function)(struct hrtimer *);
     struct hrtimer_clock_base    *base;
diff --git a/include/linux/seqlock.h b/include/linux/seqlock.h
index ef6f6a293bca..1bc714c90095 100644
--- a/include/linux/seqlock.h
+++ b/include/linux/seqlock.h
@@ -326,6 +326,23 @@ SEQCOUNT_LOCKNAME(ww_mutex,     struct ww_mutex, true,     &s->lock->base, ww_mu
  *
  * Return: count to be passed to read_seqcount_retry()
  */
+/*
+ * IAMROOT, 2022.09.24:
+ * - papago
+ *   __read_seqcount_begin() - 장벽 없이 seqcount_t 읽기 섹션을 시작합니다. 
+ *
+ *   @s: seqcount_t 또는 seqcount_LOCKNAME_t 변형에 대한 포인터입니다.
+ *
+ *   __read_seqcount_begin은 read_seqcount_begin과 비슷하지만 smp_rmb() 장벽이
+ *   없습니다. 호출자는 이 중요한 섹션에서 보호할 변수를 실제로 로드하기 전에
+ *   smp_rmb() 또는 이에 상응하는 순서가 제공되었는지 확인해야 합니다.
+ *
+ *   중요한 코드에서만 신중하게 사용하고 장벽이 제공되는 방식을 설명합니다. 
+ *
+ *   return: read_seqcount_retry()에 전달할 카운트.
+ *
+ * - raw_write_seqcount_barrier()과 같이 본다.
+ */
 #define __read_seqcount_begin(s)                    \
 ({                                    \
     unsigned __seq;                            \
@@ -622,6 +639,24 @@ static inline void do_write_seqcount_end(seqcount_t *s)
  *        WRITE_ONCE(X, false);
  *      }
  */
+
+/*
+ * IAMROOT, 2022.09.24:
+ * - papago
+ *   이것은 일반적인 일관성 보증 대신 주문 보증을 제공하는 데 사용할 수 있습니다.
+ *   두 개의 연속적인 wmb()를 접을 수 있기 때문에 하나의 wmb가 더 저렴합니다. 
+ *
+ *   장벽을 둘러싼 쓰기는 원자성으로 선언되어야 합니다(예: WRITE_ONCE를 통해):
+ *   a) 컴파일러 최적화를 피하면서 쓰기를 원자적으로 다른 스레드에서 볼 수 있도록
+ *   합니다. b) 어떤 쓰기가 독자의 임계 영역에 전파될 것인지 문서화합니다.
+ *   이는 독자가 진행 중인 쓰기를 인식할 수 있도록 장벽 전후의 쓰기가 모두
+ *   seq-writer 임계 섹션에 포함되지 않기 때문에 필요합니다.
+ *
+ * - 빈번한 갱신상황에 다른 core들이 빠르게 인지해야될때
+ * - __read_seqcount_begin(), __read_seqcount_retry()와 같이 본다.
+ *
+ * - write를 한시점에서 모든 core가 sequence를 읽을때 갱신된것을 보장해야 될때.
+ */
 #define raw_write_seqcount_barrier(s)                    \
     do_raw_write_seqcount_barrier(seqprop_ptr(s))
 
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 1019b15947ab..ba19d7aaa26a 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -262,6 +262,10 @@ struct hrtimer_cpu_base *get_target_base(struct hrtimer_cpu_base *base,
  * to the current CPU or leave it on the previously assigned CPU if
  * the timer callback is currently running.
  */
+/*
+ * IAMROOT, 2022.09.24:
+ * - cpu상황에 따라 timer를 다른 cpu의 clock base로 옮긴다.
+ */
 static inline struct hrtimer_clock_base *
 switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base,
             int pinned)
@@ -564,6 +568,10 @@ __next_base(struct hrtimer_cpu_base *cpu_base, unsigned int *active)
     return &cpu_base->clock_base[idx];
 }
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - cpu_base의 active mask의 clock base를 iterate한다.
+ */
 #define for_each_active_base(base, cpu_base, active)    \
     while ((base = __next_base((cpu_base), &(active))))
 
@@ -776,6 +784,11 @@ static ktime_t hrtimer_update_next_event(struct hrtimer_cpu_base *cpu_base)
     return expires_next;
 }
 
+
+/*
+ * IAMROOT, 2022.09.24:
+ * - hard irq offset 을 갱신한다음에 soft irq에도 적용한다.
+ */
 static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base)
 {
     ktime_t *offs_real = &base->clock_base[HRTIMER_BASE_REALTIME].offset;
@@ -805,6 +818,10 @@ static inline int __hrtimer_hres_active(struct hrtimer_cpu_base *cpu_base)
         cpu_base->hres_active : 0;
 }
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - this_cpu의 hrtime 동작여부 확인.
+ */
 static inline int hrtimer_hres_active(void)
 {
     return __hrtimer_hres_active(this_cpu_ptr(&hrtimer_bases));
@@ -899,6 +916,10 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal)
  * High resolution timer enabled ?
  */
 static bool hrtimer_hres_enabled __read_mostly  = true;
+/*
+ * IAMROOT, 2022.09.24:
+ * - hr timer가 동작하는 최소 실행 시간.
+ */
 unsigned int hrtimer_resolution __read_mostly = LOW_RES_NSEC;
 EXPORT_SYMBOL_GPL(hrtimer_resolution);
 
@@ -1277,6 +1298,34 @@ void unlock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
  * Note: This only updates the timer expiry value and does not requeue
  * the timer.
  */
+/*
+ * IAMROOT, 2022.09.24:
+ * - ex) orun = 0 (old time ----------> new time)
+ *
+ *   1. 만료시각이 now보다 뒤에 이미 설정되있다.
+ *   vNow    vExpire
+ *   |-------|
+ *
+ *   2. timer가 enqueued 상태.
+ *
+ * - ex) orun = 1
+ *   1. delta가 interval보다 짧은상태.
+ *   <---delta --->
+ *   vExpire       vNow
+ *   |-------------*---|-----------------|
+ *   <-interval-------->            
+ *                     ^NewExpire
+ *
+ * - ex) orun = 2
+ *
+ *   1. delta가 interval보다 나중일때
+ *   <---delta --------------->
+ *   vExpire                   vNow
+ *   |-----------------|-------*---------|
+ *   <-interval-------->                 ^NewExpire
+ *
+ * - next expire 시간을 interval 단위로 갱신한다.
+ */
 u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval)
 {
     u64 orun = 1;
@@ -1284,20 +1333,67 @@ u64 hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval)
 
     delta = ktime_sub(now, hrtimer_get_expires(timer));
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - expire시간이 아직 안지낫으면 return.
+ *   over_run이 없어서 return 0.
+ */
     if (delta < 0)
         return 0;
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - 이미 실행 대기중. 
+ */
     if (WARN_ON(timer->state & HRTIMER_STATE_ENQUEUED))
         return 0;
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - @internal이 hardware 지원시간보다 낮을경우 보정한다.
+ */
     if (interval < hrtimer_resolution)
         interval = hrtimer_resolution;
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - 실행되야될 timer가 internal보다 지낫다면.
+ */
     if (unlikely(delta >= interval)) {
         s64 incr = ktime_to_ns(interval);
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - interval 개수 = delta / interval.
+ */
         orun = ktime_divns(delta, incr);
+
+/*
+ * IAMROOT, 2022.09.24:
+ * -
+ *  1
+ *   <----------- delta -------------------->
+ *   vExpire                                 vNow
+ *   |-------|-------|-------|-------|-------|
+ *   <-incr->
+ *   orun = delta / incr = 5
+ *
+ *  2.
+ *   <----------- delta -------->
+ *   vExpire                      vNow
+ *   |-------|-------|-------|-------|----
+ *   <-incr->                    <------->
+ *                                <-incr->
+ *   orun = delta / incr = 3.
+ *   now보다 전시간이므로 orun을 하나 더 추가.
+ *   orun = 3 + 1 = 4
+ *
+ */
         hrtimer_add_expires_ns(timer, incr * orun);
+/*
+ * IAMROOT, 2022.09.24:
+ * - 예외처리.
+ */
         if (hrtimer_get_expires_tv64(timer) > now)
             return orun;
         /*
@@ -1501,6 +1597,10 @@ static inline ktime_t hrtimer_update_lowres(struct hrtimer *timer, ktime_t tim,
     return tim;
 }
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - softirq만 갱신해준다. next timer가 있다면 reprogram
+ */
 static void
 hrtimer_update_softirq_timer(struct hrtimer_cpu_base *cpu_base, bool reprogram)
 {
@@ -2081,6 +2181,11 @@ EXPORT_SYMBOL_GPL(hrtimer_init);
  *
  * It is important for this function to not return a false negative.
  */
+
+/*
+ * IAMROOT, 2022.09.24:
+ * - @timer가 queue에 있거나 running중인지 확인한다.
+ */
 bool hrtimer_active(const struct hrtimer *timer)
 {
     struct hrtimer_clock_base *base;
@@ -2090,6 +2195,12 @@ bool hrtimer_active(const struct hrtimer *timer)
         base = READ_ONCE(timer->base);
         seq = raw_read_seqcount_begin(&base->seq);
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - 탈출조건
+ *   1. timer가 queue에 있다.
+ *   2. running중인 timer가 timer다.
+ */
         if (timer->state != HRTIMER_STATE_INACTIVE ||
             base->running == timer)
             return true;
@@ -2097,6 +2208,10 @@ bool hrtimer_active(const struct hrtimer *timer)
     } while (read_seqcount_retry(&base->seq, seq) ||
          base != READ_ONCE(timer->base));
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - timer->state == HRTIMER_STATE_INACTIVE && base->running != timer
+ */
     return false;
 }
 EXPORT_SYMBOL_GPL(hrtimer_active);
@@ -2119,6 +2234,31 @@ EXPORT_SYMBOL_GPL(hrtimer_active);
  * __run_hrtimer() invocations.
  */
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - papago
+ *   __run_hrtimer()의 write_seqcount_barrier()는 사물을 3개의 개별 섹션으로
+ *   나눕니다.
+ *
+ *  - queued:    the timer is queued
+ *  - callback:    the timer is being ran
+ *  - post:    the timer is inactive or (re)queued
+ *
+ *  read side측에서 우리는 같은 섹션에서 실행 중인 timer->state 및 cpu_base->state를
+ *  관찰했는지 확인하고, 보는 동안 변경된 사항이 있으면 재시도합니다.
+ *  여기에는 sequence number만으로는 충분하지 않기 때문에 timer->base 변경이
+ *  포함됩니다.
+ *
+ *  그렇지 않으면 read side측이 여러 연속 __run_hrtimer()호출로 번지는 경우
+ *  여전히 false negative를 관찰할수 있기 때문에 sequence number가 필요 합니다.
+ *
+ * - timer를 실행시킨다.
+ *   timer를 queue에서 빼와(remove, state = HRTIMER_STATE_INACTIVE)
+ *   base->running에 갱신하고, 실행이 끝나면 base->running을 NULL로 다시 갱신한다.
+ * - read side(hrtimer_active()) 측에서 동기화를 위해 barrier seqcount를 사용한다.
+ *   (__run_timers()가 많이 호출되는 상황에서, read side가 true가 되야되는
+ *   상황임에도 false가 호출되는 상황이 있을수 있기 때문에)
+ */
 static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
               struct hrtimer_clock_base *base,
               struct hrtimer *timer, ktime_t *now,
@@ -2131,8 +2271,22 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
     lockdep_assert_held(&cpu_base->lock);
 
     debug_deactivate(timer);
+
+/*
+ * IAMROOT, 2022.09.24:
+ * - 1.
+ *   base->running == NULL
+ *   timer->state  == HRTIMER_STATE_ENQUEUED
+ */
     base->running = timer;
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - 2.
+ *   base->running == timer
+ *   timer->state  == HRTIMER_STATE_ENQUEUED
+ */
+
     /*
      * Separate the ->running assignment from the ->state assignment.
      *
@@ -2140,8 +2294,27 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
      * hrtimer_active() cannot observe base->running == NULL &&
      * timer->state == INACTIVE.
      */
+/*
+ * IAMROOT, 2022.09.24:
+ * - papago
+ *   Separate the ->running assignment from the ->state assignment. 
+ *
+ *   일반 쓰기 장벽과 마찬가지로 이것은 hrtimer_active()의 읽기 측이
+ *   base->running == NULL && timer->state == INACTIVE를 관찰할 수 없도록 합니다.
+ *
+ * - 3. seq홀수 -> smp_wmb -> seq짝수 
+ *   base->running == timer
+ *   timer->state  == HRTIMER_STATE_ENQUEUED
+ */
     raw_write_seqcount_barrier(&base->seq);
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - @timer를 실행할 예정이다. 등록되있는 대기열에서 뺀다음에 실행을 준비한다.
+ * - 4.
+ *   base->running == timer
+ *   timer->state  == HRTIMER_STATE_INACTIVE
+ */
     __remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, 0);
     fn = timer->function;
 
@@ -2150,6 +2323,13 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
      * timer is restarted with a period then it becomes an absolute
      * timer. If its not restarted it does not matter.
      */
+/*
+ * IAMROOT, 2022.09.24:
+ * - papago
+ *   TIME_LOW_RES 경우에 대해 '상대적' 플래그를 지웁니다. 타이머가 마침표와 함께
+ *   다시 시작되면 절대 타이머가 됩니다. 다시 시작하지 않으면 문제가 되지
+ *   않습니다.
+ */
     if (IS_ENABLED(CONFIG_TIME_LOW_RES))
         timer->is_rel = false;
 
@@ -2162,6 +2342,10 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
     trace_hrtimer_expire_entry(timer, now);
     expires_in_hardirq = lockdep_hrtimer_enter(timer);
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - 실행
+ */
     restart = fn(timer);
 
     lockdep_hrtimer_exit(expires_in_hardirq);
@@ -2177,6 +2361,11 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
      * hrtimer_start_range_ns() can have popped in and enqueued the timer
      * for us already.
      */
+/*
+ * IAMROOT, 2022.09.24:
+ * - @timer가 restart를 해야되는데, 그사이에 다시 queue에 안들어 가있다면
+ *   queue에 넣는다.
+ */
     if (restart != HRTIMER_NORESTART &&
         !(timer->state & HRTIMER_STATE_ENQUEUED))
         enqueue_hrtimer(timer, base, HRTIMER_MODE_ABS);
@@ -2188,12 +2377,22 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base,
      * hrtimer_active() cannot observe base->running.timer == NULL &&
      * timer->state == INACTIVE.
      */
+
     raw_write_seqcount_barrier(&base->seq);
 
     WARN_ON_ONCE(base->running != timer);
+
+/*
+ * IAMROOT, 2022.09.24:
+ * - running이 완료 됬다.
+ */
     base->running = NULL;
 }
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - clock base를 iterate하며 slack range에따라 timer를 실행한다. 
+ */
 static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now,
                  unsigned long flags, unsigned int active_mask)
 {
@@ -2206,6 +2405,23 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now,
 
         basenow = ktime_add(now, base->offset);
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - 가장 빨리 wakeup되야 되는 timer를 가져온다.
+ *
+ *
+ * - ex) timer1, timer2, timer3이 다음과 같은상황
+ *        (_softexpires --------------- node.expire)
+ *
+ *                           vinterrup 
+ *     timer1 ----------------
+ *     timer2     ----------------------
+ *     timer3               ---------
+ *
+ *  next_expire는 node.expire가 제일빠른 timer1로 선택되고, timer1이 실행될때
+ *  timer2, timer3도 같이 실행된다.
+ *  (node.expire 순서대로 실행. timer1->timer3->timer2)
+ */
         while ((node = timerqueue_getnext(&base->active))) {
             struct hrtimer *timer;
 
@@ -2223,6 +2439,19 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now,
              * are right-of a not yet expired timer, because that
              * timer will have to trigger a wakeup anyway.
              */
+/*
+ * IAMROOT, 2022.09.24:
+ * - papago
+ *   softexpire를 사용하는 즉각적인 목표는 소프트 만료 후 가장 빠른 인터럽트에서
+ *   타이머를 실행하지 않고 깨우기를 최소화하는 것입니다.
+ *   이를 통해 겹치는 간격에 대한 찌르는 쿼리에 응답할 수 있는 우선 순위 검색
+ *   트리를 사용하지 않고 대신 이미 가지고 있는 간단한 BST를 사용할 수 있습니다.
+ *   아직 만료되지 않은 타이머의 오른쪽에 있는 타이머를 지연시켜 추가 깨우기를
+ *   추가하지 않습니다. 해당 타이머는 어쨌든 깨우기를 트리거해야 하기 때문입니다.
+ *
+ * - 현재시각이 _softexpires에 도래하지 않았다면, 즉 제일 빠른 timer의 slack
+ *   범위이내로 들어오지 않았다면 그냥 종료.
+ */
             if (basenow < hrtimer_get_softexpires_tv64(timer))
                 break;
 
@@ -2235,7 +2464,8 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now,
 
 /*
  * IAMROOT, 2022.09.17:
- * - TODO
+ * - this_cpu의 expire된 softirq용 hrtimer를 clock base를 순회하며
+ *   _softexpires를 지난 timer들을 전부 실행한다.
  */
 static __latent_entropy void hrtimer_run_softirq(struct softirq_action *h)
 {
@@ -2243,9 +2473,17 @@ static __latent_entropy void hrtimer_run_softirq(struct softirq_action *h)
     unsigned long flags;
     ktime_t now;
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - cpu_base->softirq_expiry_lock, cpu_base->lock 을 lock 건다.
+ */
     hrtimer_cpu_base_lock_expiry(cpu_base);
     raw_spin_lock_irqsave(&cpu_base->lock, flags);
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - clock base들의 offset 갱신.
+ */
     now = hrtimer_update_base(cpu_base);
     __hrtimer_run_queues(cpu_base, now, flags, HRTIMER_ACTIVE_SOFT);
 
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index b348749a9fc6..a55105afa33c 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -45,6 +45,10 @@ DEFINE_RAW_SPINLOCK(timekeeper_lock);
  * The most important data for readout fits into a single 64 byte
  * cache line.
  */
+/*
+ * IAMROOT, 2022.09.24:
+ * - 현새 시각을 관리하기 위한 구조체.
+ */
 static struct {
     seqcount_raw_spinlock_t    seq;
     struct timekeeper    timekeeper;
@@ -186,6 +190,10 @@ static inline void tk_update_sleep_time(struct timekeeper *tk, ktime_t delta)
  * a read of the fast-timekeeper tkrs (which is protected by its own locking
  * and update logic).
  */
+/*
+ * IAMROOT, 2022.09.24:
+ * - read 함수를 통해 clocksource의 clock을 알아 온다.
+ */
 static inline u64 tk_clock_read(const struct tk_read_base *tkr)
 {
     struct clocksource *clock = READ_ONCE(tkr->clock);
@@ -279,6 +287,11 @@ static inline u64 timekeeping_get_delta(const struct tk_read_base *tkr)
 static inline void timekeeping_check_update(struct timekeeper *tk, u64 offset)
 {
 }
+
+/*
+ * IAMROOT, 2022.09.24:
+ * - clock delta = now(tk_clock_read) - old(tkr->cycle_last)
+ */
 static inline u64 timekeeping_get_delta(const struct tk_read_base *tkr)
 {
     u64 cycle_now, delta;
@@ -368,7 +381,10 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock)
 }
 
 /* Timekeeper helper functions. */
-
+/*
+ * IAMROOT, 2022.09.24:
+ * - clock을 ns로 변환한다.
+ */
 static inline u64 timekeeping_delta_to_ns(const struct tk_read_base *tkr, u64 delta)
 {
     u64 nsec;
@@ -379,6 +395,12 @@ static inline u64 timekeeping_delta_to_ns(const struct tk_read_base *tkr, u64 de
     return nsec;
 }
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - tkr에 저장된 시간을오부터 지나간 시간(ns)를 알아온다.
+ * - delta = now(clock을 callback에서 읽음) - old(tkr에 있는값)
+ *   delta를 ns로 변환하여 return.
+ */
 static inline u64 timekeeping_get_ns(const struct tk_read_base *tkr)
 {
     u64 delta;
@@ -2285,6 +2307,11 @@ void do_timer(unsigned long ticks)
  *
  * Called from hrtimer_interrupt() or retrigger_next_event()
  */
+/*
+ * IAMROOT, 2022.09.24:
+ * - timekeeper로 인자값들을 update해준다.
+ *   mono는 항상 offset이 0이기 때문에 할필요가 없다.
+ */
 ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real,
                      ktime_t *offs_boot, ktime_t *offs_tai)
 {
@@ -2293,13 +2320,25 @@ ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real,
     ktime_t base;
     u64 nsecs;
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - seqlock으로 인자값들을 tk 값으로 갱신한다.
+ */
     do {
         seq = read_seqcount_begin(&tk_core.seq);
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - base + delta nsec로 now의 완전한 시각을 구한다.
+ */
         base = tk->tkr_mono.base;
         nsecs = timekeeping_get_ns(&tk->tkr_mono);
         base = ktime_add_ns(base, nsecs);
 
+/*
+ * IAMROOT, 2022.09.24:
+ * - sequence가 바뀌엇을대만 갱신을 한다. 즉 interrupt 발생 시간을 저장한다.
+ */
         if (*cwsseq != tk->clock_was_set_seq) {
             *cwsseq = tk->clock_was_set_seq;
             *offs_real = tk->offs_real;
@@ -2308,6 +2347,11 @@ ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real,
         }
 
         /* Handle leapsecond insertion adjustments */
+/*
+ * IAMROOT, 2022.09.24:
+ * - tk가 발생한 interrupt 시간보다 한참 지나서 이 루틴에 들어왔다면
+ *   real time은 overflow된 1초를 빼준다.
+ */
         if (unlikely(base >= tk->next_leap_ktime))
             *offs_real = ktime_sub(tk->offs_real, ktime_set(1, 0));
 
diff --git a/kernel/time/timekeeping_internal.h b/kernel/time/timekeeping_internal.h
index 4ca2787d1642..415e310c5003 100644
--- a/kernel/time/timekeeping_internal.h
+++ b/kernel/time/timekeeping_internal.h
@@ -27,6 +27,11 @@ static inline u64 clocksource_delta(u64 now, u64 last, u64 mask)
     return ret & ~(mask >> 1) ? 0 : ret;
 }
 #else
+
+/*
+ * IAMROOT, 2022.09.24:
+ * - cycle delta
+ */
 static inline u64 clocksource_delta(u64 now, u64 last, u64 mask)
 {
     return (now - last) & mask;
diff --git a/lib/timerqueue.c b/lib/timerqueue.c
index 8034bfda310a..5161254f20ac 100644
--- a/lib/timerqueue.c
+++ b/lib/timerqueue.c
@@ -17,6 +17,11 @@
 #define __node_2_tq(_n) \
     rb_entry((_n), struct timerqueue_node, node)
 
+
+/*
+ * IAMROOT, 2022.09.24:
+ * - expires를 기준으로 정렬한다.
+ */
 static inline bool __timerqueue_less(struct rb_node *a, const struct rb_node *b)
 {
     return __node_2_tq(a)->expires < __node_2_tq(b)->expires;
 

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 626
167 [커널 18차] 80주차 kkr 2022.12.03 156
166 [커널 19차] 28 ~ 29 주차 Min 2022.12.03 35
165 [커널 19차] 27 주차 Min 2022.11.22 82
164 [커널 18차] 78주차 kkr 2022.11.19 187
163 [커널 19차] 25 ~ 26 주차 Min 2022.11.14 72
162 [커널 18차] 76-77주차 kkr 2022.11.12 386
161 [커널 19차] 24주차 Min 2022.10.31 108
160 [커널 17차] 112주차 ㅇㅇㅇ 2022.10.30 81
159 [커널 18차] 75주차 kkr 2022.10.29 42
158 [커널 17차] 107 ~ 111주차 ㅇㅇㅇ 2022.10.23 77
157 [커널 19차] 22주차 Min 2022.10.17 76
156 [커널 18차] 73주차 kkr 2022.10.15 46
155 [커널 18차] 72주차 kkr 2022.10.09 183
154 [커널 18차] 71주차 kkr 2022.10.01 75
» [커널 18차] 70주차 kkr 2022.09.24 77
152 [커널 18차] 69주차 kkr 2022.09.22 58
151 [커널 17차] 105~106주차 ㅇㅇㅇ 2022.09.18 50
150 [커널 17차] 104주차 ㅇㅇㅇ 2022.09.04 88
149 [커널 18차] 67주차 kkr 2022.09.03 138
148 [커널 17차] 103주차 ㅇㅇㅇ 2022.08.28 35
XE Login