Skip to content

Latest commit

 

History

History
1021 lines (848 loc) · 27.6 KB

a10c_72.md

File metadata and controls

1021 lines (848 loc) · 27.6 KB

ARM10C 72주차 후기

일시 : 2014.10.04 (72주차)
모임명 : NAVER개발자커뮤니티지원_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();

  • exynos-combiner.c 에 정의된 함수를 사용하여 초기화 수행

  • __irqchip_begin: irqchip_of_match_exynos4210_combiner

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();
}

irqchip.c::irqchip_init()

// ARM10C 20141004
void __init irqchip_init(void)
{
	// exynos-combiner.c 에 정의된 함수를 사용하여 초기화 수행
	// __irqchip_begin: irqchip_of_match_exynos4210_combiner
	of_irq_init(__irqchip_begin);
}

irq.c::of_irq_init()

// ARM10C 20141004
// __irqchip_begin: irqchip_of_match_exynos4210_combiner
void __init of_irq_init(const struct of_device_id *matches)
{
	struct device_node *np, *parent = NULL;
	// parent: NULL
	struct intc_desc *desc, *temp_desc;
	struct list_head intc_desc_list, intc_parent_list;

	INIT_LIST_HEAD(&intc_desc_list);
	// intc_desc_list 리스트 초기화 수행

	INIT_LIST_HEAD(&intc_parent_list);
	// intc_parent_list 리스트 초기화 수행

	// matches: irqchip_of_match_exynos4210_combiner
	for_each_matching_node(np, matches) {
	// for (np = of_find_matching_node(NULL, matches); np; np = of_find_matching_node(np, matches))

		// np: devtree에서 allnext로 순회 하면서 찾은 combiner node의 주소
		// of_find_property(devtree에서 allnext로 순회 하면서 찾은 combiner node의 주소, "interrupt-controller", NULL):
		// combiner node의 "interrupt-controller" property의 주소
		if (!of_find_property(np, "interrupt-controller", NULL))
			continue;
		/*
		 * Here, we allocate and populate an intc_desc with the node
		 * pointer, interrupt-parent device_node etc.
		 */
		// sizeof(struct intc_desc): 16 bytes, GFP_KERNEL: 0xD0
		// kzalloc(16, GFP_KERNEL: 0xD0): kmem_cache#30-o10
		desc = kzalloc(sizeof(*desc), GFP_KERNEL);
		// desc: kmem_cache#30-o10

		// desc: kmem_cache#30-o10
		if (WARN_ON(!desc))
			goto err;

		// desc->dev: (kmem_cache#30-o10)->dev, np: devtree에서 allnext로 순회 하면서 찾은 combiner node의 주소
		desc->dev = np;
		// desc->dev: (kmem_cache#30-o10)->dev: devtree에서 allnext로 순회 하면서 찾은 combiner node의 주소

// 2014/10/04 종료

		// desc->interrupt_parent: (kmem_cache#30-o10)->interrupt_parent, np: devtree에서 allnext로 순회 하면서 찾은 combiner node의 주소
		desc->interrupt_parent = of_irq_find_parent(np);
		if (desc->interrupt_parent == np)
			desc->interrupt_parent = NULL;
		list_add_tail(&desc->list, &intc_desc_list);
	}

	/*
	 * The root irq controller is the one without an interrupt-parent.
	 * That one goes first, followed by the controllers that reference it,
	 * followed by the ones that reference the 2nd level controllers, etc.
	 */
	while (!list_empty(&intc_desc_list)) {
		/*
		 * Process all controllers with the current 'parent'.
		 * First pass will be looking for NULL as the parent.
		 * The assumption is that NULL parent means a root controller.
		 */
		list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
			const struct of_device_id *match;
			int ret;
			of_irq_init_cb_t irq_init_cb;

			if (desc->interrupt_parent != parent)
				continue;

			list_del(&desc->list);
			match = of_match_node(matches, desc->dev);
			if (WARN(!match->data,
			    "of_irq_init: no init function for %s\n",
			    match->compatible)) {
				kfree(desc);
				continue;
			}

			pr_debug("of_irq_init: init %s @ %p, parent %p\n",
				 match->compatible,
				 desc->dev, desc->interrupt_parent);
			irq_init_cb = (of_irq_init_cb_t)match->data;
			ret = irq_init_cb(desc->dev, desc->interrupt_parent);
			if (ret) {
				kfree(desc);
				continue;
			}

			/*
			 * This one is now set up; add it to the parent list so
			 * its children can get processed in a subsequent pass.
			 */
			list_add_tail(&desc->list, &intc_parent_list);
		}

		/* Get the next pending parent that might have children */
		desc = list_first_entry_or_null(&intc_parent_list,
						typeof(*desc), list);
		if (!desc) {
			pr_err("of_irq_init: children remain, but no parents\n");
			break;
		}
		list_del(&desc->list);
		parent = desc->dev;
		kfree(desc);
	}

	list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {
		list_del(&desc->list);
		kfree(desc);
	}
err:
	list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
		list_del(&desc->list);
		kfree(desc);
	}
}

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(-)