2015년 6월 6일 토요일

[Linux Kernel] 104주차(2015.06.06)

ARM10C : 104 주차
일시 : 2015.06.06 (104 주차 스터디 진행)
모임명 : NAVER개발자커뮤니티지원_IAMROOT.ORG_10차ARM-C
장소 : 토즈 타워점
장소지원 : NAVER 개발자 커뮤니티 지원 프로그램
참여인원 : 2명

104 주차 진도

1  1 start_kernel        1  ~/kernel/iamroot/linux-stable/init/main.c
2  2 sched_clock_postinit   750  ~/kernel/iamroot/linux-stable/init/main.c

main.c::main.c()

  • called: start_kernel()
asmlinkage void __init start_kernel(void)
{
...
    time_init();
    // timer 를 사용하기 위한 clk source, clk_table 메모리 할당 및 초기화,
    // timer event를 위한 timer irq (MCT) 초기화 수행

    sched_clock_postinit();
  • call: start_kernel()->sched_clock_postinit()

sched_clock.c::sched_clockinit()

  • called: start_kernel()->sched_clock_postinit()
// ARM10C 20150530
void __init sched_clock_postinit(void)
{
    /*
     * If no sched_clock function has been provided at that point,
     * make it the final one one.
     */
    // read_sched_clock: jiffy_sched_clock_read
    if (read_sched_clock == jiffy_sched_clock_read)
        // BITS_PER_LONG: 32, HZ: 100
        sched_clock_register(jiffy_sched_clock_read, BITS_PER_LONG, HZ);

        // sched_clock_register에서 한일:
        // read_sched_clock: jiffy_sched_clock_read
        // sched_clock_mask: 0xFFFFFFFF
        // cd.rate: 100
        // cd.epoch_ns: 0
        // cd.epoch_cyc: 0
        // cd.wrap_kt: 0x42C1D83B9ACA00
        // (&cd)->mult: 0x98968000
        // (&cd)->shift: 8
        // (&cd.seq)->sequence: 2

    update_sched_clock();

    // update_sched_clock에서 한일:
    // cd.epoch_ns: 0
    // cd.epoch_cyc: 0
    // (&cd.seq)->sequence: 4

    /*
     * Start the timer to keep sched_clock() properly updated and
     * sets the initial epoch.
     */
    // CLOCK_MONOTONIC: 1, HRTIMER_MODE_REL: 1
    hrtimer_init(&sched_clock_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);

    // hrtimer_init에서 한일:
    // sched_clock_timer의 값을 0으로 초기화
    // (&sched_clock_timer)->base: &hrtimer_bases->clock_base[0]
    // RB Tree의 &(&sched_clock_timer)->node 를 초기화

    sched_clock_timer.function = sched_clock_poll;
    // sched_clock_timer.function: sched_clock_poll

// 2015/05/30 종료

    // cd.wrap_kt: 0x42C1D83B9ACA00, HRTIMER_MODE_REL: 1
    hrtimer_start(&sched_clock_timer, cd.wrap_kt, HRTIMER_MODE_REL);
  • call: start_kernel()->sched_clock_postinit()->hrtimer_start()

sched_clock.c::sched_clock_register()

  • call: start_kernel()->sched_clock_postinit()->hrtimer_start()
// ARM10C 20150530
// &sched_clock_timer, cd.wrap_kt: 0x42C1D83B9ACA00, HRTIMER_MODE_REL: 1
int
hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)
{
    // timer: &sched_clock_timer, tim: 0x42C1D83B9ACA00, mode: 1
    return __hrtimer_start_range_ns(timer, tim, 0, mode, 1);
}
EXPORT_SYMBOL_GPL(hrtimer_start);
  • call: start_kernel()->sched_clock_postinit()->hrtimer_start()->__hrtimer_start_range_ns()

hrtimer.c::__hrtimer_start_range_ns()

  • called: start_kernel()->sched_clock_postinit()->hrtimer_start()->__hrtimer_start_range_ns()
// ARM10C 20150530
// timer: &sched_clock_timer, tim: 0x42C1D83B9ACA00, 0, mode: 1, 1
int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
        unsigned long delta_ns, const enum hrtimer_mode mode,
        int wakeup)
{
    struct hrtimer_clock_base *base, *new_base;
    unsigned long flags;
    int ret, leftmost;

    base = lock_hrtimer_base(timer, &flags);
  • call: start_kernel()->sched_clock_postinit()->hrtimer_start()
    • ->__hrtimer_start_range_ns()
    • ->lock_hrtimer_base()

hrtimer.c::lock_hrtimer_base()

  • called: start_kernel()->sched_clock_postinit()->hrtimer_start()
    • ->__hrtimer_start_range_ns()
    • ->lock_hrtimer_base()
static
struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer,
                         unsigned long *flags)
{
    struct hrtimer_clock_base *base;

    for (;;) {
        base = timer->base;
        if (likely(base != NULL)) {
            raw_spin_lock_irqsave(&base->cpu_base->lock, *flags);
            if (likely(base == timer->base))
                return base;
            /* The timer has migrated to another CPU: */
            raw_spin_unlock_irqrestore(&base->cpu_base->lock, *flags);
        }
        cpu_relax();
    }
}
  • called: start_kernel()->sched_clock_postinit()->hrtimer_start()
    • ->__hrtimer_start_range_ns()
    • ->lock_hrtimer_base()
  • return: start_kernel()->sched_clock_postinit()->hrtimer_start()
    • ->__hrtimer_start_range_ns()
    • ->lock_hrtimer_base()
      • return: &hrtimer_base->clock_base[0], flags
// ARM10C 20150530
// timer: &sched_clock_timer, tim: 0x42C1D83B9ACA00, 0, mode: 1, 1
int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
        unsigned long delta_ns, const enum hrtimer_mode mode,
        int wakeup)
{
    struct hrtimer_clock_base *base, *new_base;
    unsigned long flags;
    int ret, leftmost;

    base = lock_hrtimer_base(timer, &flags);

    /* Remove an active timer from the queue: */
    ret = remove_hrtimer(timer, base);
  • called: start_kernel()->sched_clock_postinit()->hrtimer_start()
    • ->__hrtimer_start_range_ns()
    • ->lock_hrtimer_base()
    • ->remove_hrtimer()

hrtimer.c::remove_hrtimer()

  • call: start_kernel()->sched_clock_postinit()->hrtimer_start()
    • ->__hrtimer_start_range_ns()
    • ->lock_hrtimer_base()
    • ->remove_hrtimer()
static inline int
remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base)
{
    if (hrtimer_is_queued(timer)) {
        unsigned long state;
        int reprogram;

        /*
         * Remove the timer and force reprogramming when high
         * resolution mode is active and the timer is on the current
         * CPU. If we remove a timer on another CPU, reprogramming is
         * skipped. The interrupt event on this CPU is fired and
         * reprogramming happens in the interrupt handler. This is a
         * rare case and less expensive than a smp call.
         */
        debug_deactivate(timer);
        timer_stats_hrtimer_clear_start_info(timer);
        reprogram = base->cpu_base == &__get_cpu_var(hrtimer_bases);
        /*
         * We must preserve the CALLBACK state flag here,
         * otherwise we could move the timer base in
         * switch_hrtimer_base.
         */
        state = timer->state & HRTIMER_STATE_CALLBACK;
        __remove_hrtimer(timer, base, state, reprogram);
        return 1;
    }
    return 0;
}

log

  • 1st log
   cf3996e..db7acca  master     -> origin/master
Updating cf3996e..db7acca
Fast-forward
include/asm-generic/bitsperlong.h |   1 +
include/asm-generic/param.h       |   1 +
include/linux/clocksource.h       |   2 +
include/linux/irqflags.h          |   3 +
include/linux/sched_clock.h       |   2 +-
include/linux/time.h              |   1 +
init/main.c                       |   3 +
kernel/time/clocksource.c         | 341 +++++++++++++++++++++++++++++---------
kernel/time/sched_clock.c         |  26 +++
9 files changed, 302 insertions(+), 78 deletions(-)
  • 2nd log
   db7acca..e6b188d  master     -> origin/master
Merge made by the 'recursive' strategy.
include/linux/clocksource.h  |   4 ++++
include/linux/hrtimer.h      |   2 ++
include/linux/irqflags.h     |   1 +
include/linux/ktime.h        |  16 +++++++++++++---
include/linux/log2.h         |   2 ++
include/linux/rbtree.h       |   2 ++
include/linux/seqlock.h      |  20 ++++++++++++++++++++
include/linux/timerqueue.h   |   6 ++++++
include/trace/events/timer.h |   2 ++
include/uapi/linux/time.h    |   1 +
kernel/hrtimer.c             |  46 ++++++++++++++++++++++++++++++++++++++++++++--
kernel/time/clocksource.c    |  13 ++++++++++++-
kernel/time/sched_clock.c    | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
13 files changed, 223 insertions(+), 6 deletions(-)

댓글 없음:

댓글 쓰기