2014년 10월 5일 일요일

[Linux Kernel] 72주차(2014.10.04)

ARM10C 72주차 후기

일시 : 2014.10.04 (72주차)
모임명 : NAVER개발자커뮤니티지원_IAMROOT.ORG_10차ARM-C
장소 : 토즈 타워점
장소지원 : NAVER 개발자 커뮤니티 지원 프로그램
참여인원 : 3명

스터디 진도 :

  • tick_nohz_init()
    • null funtion
  • context_tracking_init()
    • null function
  • radix_tree_init()
    • radix tree로 사용하는 radix_tree_node_cachep에 kmem_cache#20을 생성 및 초기화 후 할당하고
    • height_to_maxindex을 초기화 수행
  • early_irq_init();
    • irq_desc 0 ~ 15 까지의 object을 할당 받고 초기화를 수행
    • allocated_irqs에 bit를 1로 세팅하고 radix tree에 각 irq_desc를 노트로 추가
  • init_IRQ();

main.c::start_kernel()

asmlinkage void __init start_kernel(void)
{

...

    boot_cpu_init();
    // 현재 cpu(core id)를 얻어서 cpu_XXX_bits[] 의 cpu를 셋한다.

...

    setup_arch(&command_line);

...

    mm_init();
    // buddy와 slab 을 활성화 하고 기존 할당 받은 bootmem 은 buddy,
    // pcpu 메모리, vmlist 는 slab으로 이관

    sched_init();
    // scheduler가 사용하는 자료 구조 초기화, idle_threads를 init_task로 세팅

    preempt_disable();
    // preempt count를 증가시켜 preemption 못하도록 막음

...

    rcu_init();
    // rcu 자료구조 bh, sched, preempt 를 각각 초기화 수행함

    tick_nohz_init(); // null function
    context_tracking_init(); // null function

    radix_tree_init();
    // radix tree로 사용하는 radix_tree_node_cachep에 kmem_cache#20을 생성 및 초기화 후 할당하고
    // height_to_maxindex을 초기화 수행

    /* init some links before init_ISA_irqs() */
    early_irq_init();
    // irq_desc 0 ~ 15 까지의 object을 할당 받고 초기화를 수행
    // allocated_irqs에 bit를 1로 세팅하고 radix tree에 각 irq_desc를 노트로 추가

tick.h::tick_nohz_init()

  • Null Function
// ARM10C 20141004
static inline void tick_nohz_init(void) { }

context_tracking.h::context_tracking_init()

  • Null Function
// ARM10C 20141004
static inline void context_tracking_init(void) { }

radix-tree.h::radix_tree_init()

// ARM10C 20141004
// #define RADIX_TREE_INIT(GFP_KERNEL):
// {
//  .height = 0,
//  .gfp_mask = (GFP_KERNEL),
//  .rnode = NULL,
// }
#define RADIX_TREE_INIT(mask)   {                   \
    .height = 0,                            \
    .gfp_mask = (mask),                     \
    .rnode = NULL,                          \
}

irqdesc.c::early_irq_init()

// ARM10C 20141004
int __init early_irq_init(void)
{
    // first_online_node: 0
    int i, initcnt, node = first_online_node;
    // node: 0
    struct irq_desc *desc;

    init_irq_default_affinity();
    // init_irq_default_affinity에서 한일:
    // irq_default_affinity->bits[0]: 0xF

    /* Let arch update nr_irqs and return the nr of preallocated irqs */
    // arch_probe_nr_irqs(): 16
    initcnt = arch_probe_nr_irqs();
    // initcnt: 16

    // NR_IRQS: 16, nr_irqs: 16, initcnt: 16
    printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d %d\n", NR_IRQS, nr_irqs, initcnt);
    // "NR_IRQS:16 nr_irqs:16 16"

    // nr_irqs: 16, IRQ_BITMAP_BITS: 8212
    if (WARN_ON(nr_irqs > IRQ_BITMAP_BITS))
        nr_irqs = IRQ_BITMAP_BITS;

    // initcnt: 16, IRQ_BITMAP_BITS: 8212
    if (WARN_ON(initcnt > IRQ_BITMAP_BITS))
        initcnt = IRQ_BITMAP_BITS;

    // initcnt: 16, nr_irqs: 16
    if (initcnt > nr_irqs)
        nr_irqs = initcnt;

    // initcnt: 16
    for (i = 0; i < initcnt; i++) {
        // i: 0, node: 0
        // alloc_desc(0, 0, NULL): kmem_cache#28-o0
        desc = alloc_desc(i, node, NULL);
        // desc: kmem_cache#28-o0

        // i: 0
        set_bit(i, allocated_irqs);
        // allocated_irqs[0]: 0x1

        // i: 0, desc: kmem_cache#28-o0
        irq_insert_desc(i, desc);
        // radix tree에 kmem_cache#28-o0를 노드로 추가

        // i: 1 ... 15 수행
    }

    // arch_early_irq_init(): 0
    return arch_early_irq_init();
    // return 0
}

cpumask.h::alloc_cpumask_var()

  • initcnt: 16
// ARM10C 20141004
// &irq_default_affinity, GFP_NOWAIT: 0
static inline bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags)
{
    return true;
}

cpumask.h::cpumask_setall()

// ARM10C 20141004
// irq_default_affinity
static inline void cpumask_setall(struct cpumask *dstp)
{
    // dstp: irq_default_affinity, cpumask_bits(irq_default_affinity): irq_default_affinity->bits,
    // nr_cpumask_bits: 4
    bitmap_fill(cpumask_bits(dstp), nr_cpumask_bits);
    // irq_default_affinity->bits[0]: 0xF
}

bitmap.h::bitmap_fill()

// ARM10C 20141004
// irq_default_affinity->bits, nr_cpumask_bits: 4
static inline void bitmap_fill(unsigned long *dst, int nbits)
{
    // nbits: 4, BITS_TO_LONGS(4): 1
    size_t nlongs = BITS_TO_LONGS(nbits);
    // nlongs: 1

    // nbits: 4, small_const_nbits(4): 1
    if (!small_const_nbits(nbits)) {
        int len = (nlongs - 1) * sizeof(unsigned long);
        memset(dst, 0xff,  len);
    }

    // dst: irq_default_affinity->bits, nlongs: 1, nbits: 4, BITMAP_LAST_WORD_MASK(4): 0xF
    dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
    // irq_default_affinity->bits[0]: 0xF
}

init_irq_default_affinity();에서 한일

  • irq_default_affinity->bits[0]: 0xF

irq.c::arch_probe_nr_irqs()

  • initcnt = arch_probe_nr_irqs();
    • // arch_probe_nr_irqs(): 16
#ifdef CONFIG_SPARSE_IRQ // CONFIG_SPARSE_IRQ=y
int __init arch_probe_nr_irqs(void)
{
    // machine_desc->nr_irqs: __mach_desc_EXYNOS5_DT.nr_irqs: 0, NR_IRQS: 16
    nr_irqs = machine_desc->nr_irqs ? machine_desc->nr_irqs : NR_IRQS;
    // nr_irqs: 16

    // nr_irqs: 16
    return nr_irqs;
    // return 16
}

irqdesc.c::init_irq_defalut_affinity()

  • irq_default_affinity->bits[0]: 0xF
#if defined(CONFIG_SMP) // CONFIG_SMP=y
// ARM10C 20141004
static void __init init_irq_default_affinity(void)
{
    // GFP_NOWAIT: 0
    // alloc_cpumask_var(&irq_default_affinity, 0): 0
    alloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT);
    cpumask_setall(irq_default_affinity);
    // irq_default_affinity->bits[0]: 0xF
}
#else
static void __init init_irq_default_affinity(void)
{
}
#endif

iqrdesc.c::for (i = 0; i < initcnt; i++) loop

  • initcnt: 16
for (i = 0; i < initcnt; i++) {
    // i: 0, node: 0
    // alloc_desc(0, 0, NULL): kmem_cache#28-o0
    desc = alloc_desc(i, node, NULL);
    // desc: kmem_cache#28-o0

    // alloc_desc(0)에서 한일:
    // (kmem_cache#28-o0)->kstat_irqs: pcp 4 byte 공간
    // (kmem_cache#28-o0)->lock 을 이용한 spinlock 초기화 수행
    // (kmem_cache#28-o0)->irq_data.irq: 0
    // (kmem_cache#28-o0)->irq_data.chip: &no_irq_chip
    // (kmem_cache#28-o0)->irq_data.chip_data: NULL
    // (kmem_cache#28-o0)->irq_data.handler_data: NULL
    // (kmem_cache#28-o0)->irq_data.msi_desc: NULL
    // (kmem_cache#28-o0)->status_use_accessors: 0xc00
    // (&(kmem_cache#28-o0)->irq_data)->state_use_accessors: 0x10000
    // (kmem_cache#28-o0)->handle_irq: handle_bad_irq
    // (kmem_cache#28-o0)->depth: 1
    // (kmem_cache#28-o0)->irq_count: 0
    // (kmem_cache#28-o0)->irqs_unhandled: 0
    // (kmem_cache#28-o0)->name: NULL
    // (kmem_cache#28-o0)->owner: null
    // [pcp0...3] (kmem_cache#28-o0)->kstat_irqs: 0
    // (kmem_cache#28-o0)->irq_data.node: 0
    // (kmem_cache#28-o0)->irq_data.affinity.bits[0]: 0xF

    // i: 0
    set_bit(i, allocated_irqs);
    // allocated_irqs[0]: 0x1

    // i: 0, desc: kmem_cache#28-o0
    irq_insert_desc(i, desc);
    // radix tree에 kmem_cache#28-o0를 노드로 추가

    // i: 1 ... 15 수행
}

irqdesc.c::alloc_desc()

// ARM10C 20141004
// i: 0, node: 0, null
static struct irq_desc *alloc_desc(int irq, int node, struct module *owner)
{
    struct irq_desc *desc;
    // GFP_KERNEL: 0xD0
    gfp_t gfp = GFP_KERNEL;
    // gfp: GFP_KERNEL: 0xD0

    // sizeof(struct irq_desc): 156 bytes, gfp: GFP_KERNEL: 0xD0, node: 0
    // kzalloc_node(156, GFP_KERNEL: 0xD0, 0): kmem_cache#28-o0
    desc = kzalloc_node(sizeof(*desc), gfp, node);
    // desc: kmem_cache#28-o0

    // desc: kmem_cache#28-o0
    if (!desc)
        return NULL;

    /* allocate based on nr_cpu_ids */
    // desc->kstat_irqs: (kmem_cache#28-o0)->kstat_irqs
    // alloc_percpu(unsigned int): pcp 4 byte 공간 할당
    desc->kstat_irqs = alloc_percpu(unsigned int);
    // desc->kstat_irqs: (kmem_cache#28-o0)->kstat_irqs: pcp 4 byte 공간

    // desc->kstat_irqs: (kmem_cache#28-o0)->kstat_irqs: pcp 4 byte 공간
    if (!desc->kstat_irqs)
        goto err_desc;

    // desc: kmem_cache#28-o0, gfp: GFP_KERNEL: 0xD0, node: 0
    // alloc_masks(kmem_cache#28-o0, GFP_KERNEL: 0xD0, 0): 0
    if (alloc_masks(desc, gfp, node))
        goto err_kstat;
    // alloc_masks에서 한일:
    // (kmem_cache#28-o0)->irq_data.affinity.bits[0]: 0

    // desc->lock: (kmem_cache#28-o0)->lock
    raw_spin_lock_init(&desc->lock);
    // desc->lock: (kmem_cache#28-o0)->lock 을 이용한 spinlock 초기화 수행

    // desc->lock: (kmem_cache#28-o0)->lock
    lockdep_set_class(&desc->lock, &irq_desc_lock_class); // null function

    // irq: 0, desc: kmem_cache#28-o0, node: 0, owner: null
    desc_set_defaults(irq, desc, node, owner);
    // desc_set_defaults에서 한일:
    // (kmem_cache#28-o0)->irq_data.irq: 0
    // (kmem_cache#28-o0)->irq_data.chip: &no_irq_chip
    // (kmem_cache#28-o0)->irq_data.chip_data: NULL
    // (kmem_cache#28-o0)->irq_data.handler_data: NULL
    // (kmem_cache#28-o0)->irq_data.msi_desc: NULL
    // (kmem_cache#28-o0)->status_use_accessors: 0xc00
    // (&(kmem_cache#28-o0)->irq_data)->state_use_accessors: 0x10000
    // (kmem_cache#28-o0)->handle_irq: handle_bad_irq
    // (kmem_cache#28-o0)->depth: 1
    // (kmem_cache#28-o0)->irq_count: 0
    // (kmem_cache#28-o0)->irqs_unhandled: 0
    // (kmem_cache#28-o0)->name: NULL
    // (kmem_cache#28-o0)->owner: null
    // [pcp0...3] (kmem_cache#28-o0)->kstat_irqs: 0
    // (kmem_cache#28-o0)->irq_data.node: 0
    // (kmem_cache#28-o0)->irq_data.affinity.bits[0]: 0xF

    return desc;

err_kstat:
    free_percpu(desc->kstat_irqs);
err_desc:
    kfree(desc);
    return NULL;
}

slab.h::kzalloc_node()

// ARM10C 20141004
// sizeof(struct irq_desc): 156 bytes, gfp: GFP_KERNEL: 0xD0, node: 0
static inline void *kzalloc_node(size_t size, gfp_t flags, int node)
{
    // size: 156, flags: GFP_KERNEL: 0xD0, __GFP_ZERO: 0x8000u, node: 0
    // kmalloc_node(156, 0x80D0, 0): kmem_cache#28-o0
    return kmalloc_node(size, flags | __GFP_ZERO, node);
    // return kmem_cache#28-o0
}

slab.h::kmalloc_node()

// ARM10C 20141004
// size: 156, flags: 0x80D0, node: 0
static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
{
#ifndef CONFIG_SLOB // CONFIG_SLOB=n
    // size: 156, KMALLOC_MAX_CACHE_SIZE: 0x2000, flags: 0x80D0, GFP_DMA: 0x01u
    if (__builtin_constant_p(size) &&
        size <= KMALLOC_MAX_CACHE_SIZE && !(flags & GFP_DMA)) {
        // size: 156, kmalloc_index(156): 2
        int i = kmalloc_index(size);
        // i: 2

        // i: 2
        if (!i)
            return ZERO_SIZE_PTR;

        // i: 2, kmalloc_caches[2]: kmem_cache#28, flags: 0x80D0, node: 0, size: 156
        // kmem_cache_alloc_node_trace(kmem_cache#28, 0x80D0, 0, 156): kmem_cache#28-o0
        return kmem_cache_alloc_node_trace(kmalloc_caches[i],
                        flags, node, size);
        // return kmem_cache#28-o0
    }
#endif
    return __kmalloc_node(size, flags, node);
}

slab.h::kmalloc_index()

// ARM10C 20141004
// size: 16
static __always_inline int kmalloc_index(size_t size)
{
    // size: 16
    if (!size)
        return 0;

    // size: 16, KMALLOC_MIN_SIZE: 64
    if (size <= KMALLOC_MIN_SIZE)
        // KMALLOC_SHIFT_LOW: 6
        return KMALLOC_SHIFT_LOW;
        // return 6

    if (KMALLOC_MIN_SIZE <= 32 && size > 64 && size <= 96)
        return 1;

    if (KMALLOC_MIN_SIZE <= 64 && size > 128 && size <= 192)
        return 2;

    if (size <=          8) return 3;
    if (size <=         16) return 4;
    if (size <=         32) return 5;
    if (size <=         64) return 6;
    if (size <=        128) return 7;
    if (size <=        256) return 8;
    if (size <=        512) return 9;
    if (size <=       1024) return 10;
    if (size <=   2 * 1024) return 11;
    if (size <=   4 * 1024) return 12;
    if (size <=   8 * 1024) return 13;
    if (size <=  16 * 1024) return 14;
    if (size <=  32 * 1024) return 15;
    if (size <=  64 * 1024) return 16;
    if (size <= 128 * 1024) return 17;
    if (size <= 256 * 1024) return 18;
    if (size <= 512 * 1024) return 19;
    if (size <= 1024 * 1024) return 20;
    if (size <=  2 * 1024 * 1024) return 21;
    if (size <=  4 * 1024 * 1024) return 22;
    if (size <=  8 * 1024 * 1024) return 23;
    if (size <=  16 * 1024 * 1024) return 24;
    if (size <=  32 * 1024 * 1024) return 25;
    if (size <=  64 * 1024 * 1024) return 26;
    BUG();

    /* Will never be reached. Needed because the compiler may complain */
    return -1;
}

percpu.h::alloc_percpu()

// ARM10C 20141004
// unsigned int
#define alloc_percpu(type)  \
    (typeof(type) __percpu *)__alloc_percpu(sizeof(type), __alignof__(type))

irqdesc.c::alloc_masks()

#ifdef CONFIG_SMP // CONFIG_SMP=y
// ARM10C 20141004
// desc: kmem_cache#28-o0, gfp: GFP_KERNEL: 0xD0, node: 0
static int alloc_masks(struct irq_desc *desc, gfp_t gfp, int node)
{
    // desc->irq_data.affinity: &(kmem_cache#28-o0)->irq_data.affinity, gfp: GFP_KERNEL: 0xD0, node: 0
    // zalloc_cpumask_var_node(&(kmem_cache#28-o0)->irq_data.affinity, GFP_KERNEL: 0xD0, 0): true
    if (!zalloc_cpumask_var_node(&desc->irq_data.affinity, gfp, node))
        return -ENOMEM;
    // (kmem_cache#28-o0)->irq_data.affinity.bits[0]: 0

#ifdef CONFIG_GENERIC_PENDING_IRQ // CONFIG_GENERIC_PENDING_IRQ=n
    if (!zalloc_cpumask_var_node(&desc->pending_mask, gfp, node)) {
        free_cpumask_var(desc->irq_data.affinity);
        return -ENOMEM;
    }
#endif
    return 0;
}

cpumask.h::zalloc_cpumask_var_node()

// ARM10C 20141004
// &desc->irq_data.affinity: &(kmem_cache#28-o0)->irq_data.affinity, gfp: GFP_KERNEL: 0xD0, node: 0
static inline bool zalloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags,
                      int node)
{
    // *mask: (kmem_cache#28-o0)->irq_data.affinity
    cpumask_clear(*mask);
    // (kmem_cache#28-o0)->irq_data.affinity.bits[0]: 0

    return true;
}

cpumask.h::cpumask_clear()

// ARM10C 20141004
// *mask: (kmem_cache#28-o0)->irq_data.affinity
static inline void cpumask_clear(struct cpumask *dstp)
{
    // dstp: (kmem_cache#28-o0)->irq_data.affinity, nr_cpumask_bits: 4
    bitmap_zero(cpumask_bits(dstp), nr_cpumask_bits);
    // (kmem_cache#28-o0)->irq_data.affinity.bits[0]: 0
}

bitmap.h::bitmap_zero()

// ARM10C 20141004
// dstp: (kmem_cache#28-o0)->irq_data.affinity, nr_cpumask_bits: 4
static inline void bitmap_zero(unsigned long *dst, int nbits)
{
    if (small_const_nbits(nbits))
        *dst = 0UL;
    else {
        int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
        memset(dst, 0, len);
    }
}

spinlock.h::raw_spin_lock_init()

// ARM10C 20140830
// &rt_b->rt_runtime_lock: &(&def_rt_bandwidth)->rt_runtime_lock
# define raw_spin_lock_init(lock)               \
do {                                \
    static struct lock_class_key __key; /* struct lock_class_key { }; */    \
                                \
    __raw_spin_lock_init((lock), #lock, &__key);        \
} while (0)

#else
# define raw_spin_lock_init(lock)               \
    do { *(lock) = __RAW_SPIN_LOCK_UNLOCKED(lock); } while (0)
#endif

lockdep.h::lockdep_set_class_and_name()

# define lockdep_set_class_and_name(lock, key, name) \
        do { (void)(key); (void)(name); } while (0)

irqdesc.c::desc_set_defaults()

// ARM10C 20141004
// irq: 0, desc: kmem_cache#28-o0, node: 0, owner: null
static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
        struct module *owner)
{
    int cpu;

    // desc->irq_data.irq: (kmem_cache#28-o0)->irq_data.irq, irq: 0
    desc->irq_data.irq = irq;
    // desc->irq_data.irq: (kmem_cache#28-o0)->irq_data.irq: 0

    // desc->irq_data.chip: (kmem_cache#28-o0)->irq_data.chip
    desc->irq_data.chip = &no_irq_chip;
    // desc->irq_data.chip: (kmem_cache#28-o0)->irq_data.chip: &no_irq_chip

    // desc->irq_data.chip_data: (kmem_cache#28-o0)->irq_data.chip_data
    desc->irq_data.chip_data = NULL;
    // desc->irq_data.chip_data: (kmem_cache#28-o0)->irq_data.chip_data: NULL

    // desc->irq_data.handler_data: (kmem_cache#28-o0)->irq_data.handler_data
    desc->irq_data.handler_data = NULL;
    // desc->irq_data.handler_data: (kmem_cache#28-o0)->irq_data.handler_data: NULL

    // desc->irq_data.msi_desc: (kmem_cache#28-o0)->irq_data.msi_desc
    desc->irq_data.msi_desc = NULL;
    // desc->irq_data.msi_desc: (kmem_cache#28-o0)->irq_data.msi_desc: NULL

    // desc: kmem_cache#28-o0, 0xFFFFFFFF, _IRQ_DEFAULT_INIT_FLAGS: 0xc00
    irq_settings_clr_and_set(desc, ~0, _IRQ_DEFAULT_INIT_FLAGS);
    // irq_settings_clr_and_set에서 한일:
    // desc->status_use_accessors: (kmem_cache#28-o0)->status_use_accessors: 0xc00

    // &desc->irq_data: &(kmem_cache#28-o0)->irq_data, IRQD_IRQ_DISABLED: 0x10000
    irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
    // irqd_set에서 한일:
    // d->state_use_accessors: (&(kmem_cache#28-o0)->irq_data)->state_use_accessors: 0x10000

    // desc->handle_irq: (kmem_cache#28-o0)->handle_irq
    desc->handle_irq = handle_bad_irq;
    // desc->handle_irq: (kmem_cache#28-o0)->handle_irq: handle_bad_irq

    // desc->depth: (kmem_cache#28-o0)->depth
    desc->depth = 1;
    // desc->depth: (kmem_cache#28-o0)->depth: 1

    // desc->irq_count: (kmem_cache#28-o0)->irq_count
    desc->irq_count = 0;
    // desc->irq_count: (kmem_cache#28-o0)->irq_count: 0

    // desc->irqs_unhandled: (kmem_cache#28-o0)->irqs_unhandled
    desc->irqs_unhandled = 0;
    // desc->irqs_unhandled: (kmem_cache#28-o0)->irqs_unhandled: 0

    // desc->name: (kmem_cache#28-o0)->name
    desc->name = NULL;
    // desc->name: (kmem_cache#28-o0)->name: NULL

    // desc->owner: (kmem_cache#28-o0)->owner, owner: null
    desc->owner = owner;
    // desc->owner: (kmem_cache#28-o0)->owner: null

    for_each_possible_cpu(cpu)
    // for ((cpu) = -1; (cpu) = cpumask_next((cpu), (cpu_possible_mask)), (cpu) < nr_cpu_ids; )
        // desc->kstat_irqs: (kmem_cache#28-o0)->kstat_irqs, cpu: 0
        *per_cpu_ptr(desc->kstat_irqs, cpu) = 0;
        // [pcp0] (kmem_cache#28-o0)->kstat_irqs: 0
        // cpu: 1 .. 3 수행

    // desc: kmem_cache#28-o0, node: 0
    desc_smp_init(desc, node);
    // desc_smp_init에서 한일:
    // desc->irq_data.node: (kmem_cache#28-o0)->irq_data.node: 0
    // desc->irq_data.affinity: (kmem_cache#28-o0)->irq_data.affinity.bits[0]: 0xF
}

irqdesc.c::desc_smp_init()

  • desc->irq_data.node: (kmem_cache#28-o0)->irq_data.node: 0
  • desc->irq_data.affinity: (kmem_cache#28-o0)->irq_data.affinity.bits[0]: 0xF
// ARM10C 20141004
// desc: kmem_cache#28-o0, node: 0
static void desc_smp_init(struct irq_desc *desc, int node)
{
    // desc->irq_data.node: (kmem_cache#28-o0)->irq_data.node, node: 0
    desc->irq_data.node = node;
    // desc->irq_data.node: (kmem_cache#28-o0)->irq_data.node: 0

    // desc->irq_data.affinity: (kmem_cache#28-o0)->irq_data.affinity,
    // irq_default_affinity->bits[0]: 0xF
    cpumask_copy(desc->irq_data.affinity, irq_default_affinity);
    // desc->irq_data.affinity: (kmem_cache#28-o0)->irq_data.affinity.bits[0]: 0xF

#ifdef CONFIG_GENERIC_PENDING_IRQ // CONFIG_GENERIC_PENDING_IRQ=n
    cpumask_clear(desc->pending_mask);
#endif
}

bitops.h::set_bit()

// ARM10C 20141004
// 0, allocated_irqs
#define set_bit(nr,p)           ATOMIC_BITOP(set_bit,nr,p)  // _set_bit(nr,p)로 치환

irqdesc.c::irq_insert_desc()

// ARM10C 20141004
// i: 0, desc: kmem_cache#28-o0
static void irq_insert_desc(unsigned int irq, struct irq_desc *desc)
{
    // irq: 0, desc: kmem_cache#28-o0
    radix_tree_insert(&irq_desc_tree, irq, desc);
    // radix tree에 kmem_cache#28-o0를 노드로 추가
}

radix-tree.c::radix_tree_insert()

// ARM10C 20141004
// &irq_desc_tree, irq: 0, desc: kmem_cache#28-o0
int radix_tree_insert(struct radix_tree_root *root,
            unsigned long index, void *item)
{
    struct radix_tree_node *node = NULL, *slot;
    unsigned int height, shift;
    int offset;
    int error;

    BUG_ON(radix_tree_is_indirect_ptr(item));

    /* Make sure the tree is high enough.  */
    if (index > radix_tree_maxindex(root->height)) {
        error = radix_tree_extend(root, index);
        if (error)
            return error;
    }

    slot = indirect_to_ptr(root->rnode);

    height = root->height;
    shift = (height-1) * RADIX_TREE_MAP_SHIFT;

    offset = 0;         /* uninitialised var warning */
    while (height > 0) {
        if (slot == NULL) {
            /* Have to add a child node.  */
            if (!(slot = radix_tree_node_alloc(root)))
                return -ENOMEM;
            slot->height = height;
            slot->parent = node;
            if (node) {
                rcu_assign_pointer(node->slots[offset], slot);
                node->count++;
            } else
                rcu_assign_pointer(root->rnode, ptr_to_indirect(slot));
        }

        /* Go a level down */
        offset = (index >> shift) & RADIX_TREE_MAP_MASK;
        node = slot;
        slot = node->slots[offset];
        shift -= RADIX_TREE_MAP_SHIFT;
        height--;
    }

    if (slot != NULL)
        return -EEXIST;

    if (node) {
        node->count++;
        rcu_assign_pointer(node->slots[offset], item);
        BUG_ON(tag_get(node, 0, offset));
        BUG_ON(tag_get(node, 1, offset));
    } else {
        rcu_assign_pointer(root->rnode, item);
        BUG_ON(root_tag_get(root, 0));
        BUG_ON(root_tag_get(root, 1));
    }

    return 0;
}
EXPORT_SYMBOL(radix_tree_insert);

softirq.c::arch_early_irq_init()

// ARM10C 20141004
int __init __weak arch_early_irq_init(void)
{
    return 0;
}

irq.c::init_IRQ()

// ARM10C 20141004
void __init init_IRQ(void)
{
    // CONFIG_OF=y, machine_desc->init_irq: __mach_desc_EXYNOS5_DT.init_irq: 0
    if (IS_ENABLED(CONFIG_OF) && !machine_desc->init_irq)
        irqchip_init();
    else
        machine_desc->init_irq();
}

kconfig.h::IS_ENABLED()

#define IS_ENABLED(option) \
    (config_enabled(option) || config_enabled(option##_MODULE))

irqchip.h:irqchip_init()

#ifdef CONFIG_IRQCHIP // CONFIG_IRQCHIP=y
// ARM10C 20141004
void irqchip_init(void);
#else
static inline void irqchip_init(void) {}
#endif

irq.c::init_IRQ()

// ARM10C 20141004
void __init init_IRQ(void)
{
    // CONFIG_OF=y, machine_desc->init_irq: __mach_desc_EXYNOS5_DT.init_irq: 0
    if (IS_ENABLED(CONFIG_OF) && !machine_desc->init_irq)
        irqchip_init();
    else
        machine_desc->init_irq();
}

Git log

   6cd3763..d50372f  master     -> origin/master
Updating 6cd3763..d50372f
Fast-forward
arch/arm/include/asm/bitops.h     |   2 +
arch/arm/include/asm/hw_irq.h     |   3 +
arch/arm/include/asm/irq.h        |   7 +-
arch/arm/kernel/irq.c             |   9 +-
arch/arm/kernel/vmlinux.lds.S     |   5 +-
arch/arm/lib/setbit.S             |   4 +-
drivers/irqchip/exynos-combiner.c |   5 +
drivers/irqchip/irqchip.c         |   4 +
drivers/irqchip/irqchip.h         |   1 +
drivers/of/base.c                 | 107 ++++++++++++++++++++-
drivers/of/irq.c                  |  49 +++++++++-
include/asm-generic/vmlinux.lds.h |   3 +-
include/linux/bitmap.h            |  10 ++
include/linux/bitops.h            |   5 +
include/linux/compiler.h          |   1 +
include/linux/context_tracking.h  |   3 +-
include/linux/cpu.h               |   9 ++
include/linux/cpumask.h           |  18 ++++
include/linux/gfp.h               |   4 +
include/linux/irq.h               |  32 +++++++
include/linux/irqchip.h           |   3 +-
include/linux/irqdesc.h           |  10 +-
include/linux/kernel.h            |   2 +
include/linux/list.h              |   1 +
include/linux/lockdep.h           |   2 +
include/linux/mod_devicetable.h   |   1 +
include/linux/nodemask.h          |   2 +
include/linux/of.h                |  17 +++-
include/linux/percpu.h            |   2 +
include/linux/radix-tree.h        |  25 +++++
include/linux/slab.h              |  63 ++++++++++++-
include/linux/tick.h              |   3 +-
include/linux/types.h             |   3 +
include/linux/wait.h              |   4 +
init/main.c                       |  13 ++-
kernel/cpu.c                      |   7 ++
kernel/irq/dummychip.c            |   1 +
kernel/irq/handle.c               |   1 +
kernel/irq/internals.h            |   9 +-
kernel/irq/irqdesc.c              | 193 ++++++++++++++++++++++++++++++++++++--
kernel/irq/manage.c               |   3 +-
kernel/irq/settings.h             |  13 +++
kernel/notifier.c                 |   5 +
kernel/rcu/tree.c                 |   1 +
kernel/softirq.c                  |   1 +
lib/radix-tree.c                  |  81 ++++++++++++++++
mm/percpu.c                       |   2 +
mm/slab_common.c                  |   7 ++
mm/slub.c                         |   2 +
49 files changed, 730 insertions(+), 28 deletions(-)

댓글 없음:

댓글 쓰기