radix_tree_init()
lib/radix-tree.c
void __init radix_tree_init(void) { radix_tree_node_cachep = kmem_cache_create("radix_tree_node", sizeof(struct radix_tree_node), 0, SLAB_PANIC | SLAB_RECLAIM_ACCOUNT, radix_tree_node_ctor); radix_tree_init_maxindex(); hotcpu_notifier(radix_tree_callback, 0); }
radix 트리 사용을 위해 초기화한다.
- raidx_tree_node 구조체용 slub 캐시를 만들고 생성자로 radix_tree_node_ctor 함수를 준비한다.
- height 별로 최대 인덱스 값을 산출하여 전역 height_to_maxindex[] 배열에 저장한다.
- cpu 상태 변화에 따라 radix_tree_callback 함수가 호출되도록 radix_tree_callback_nb를 구성하여 전역 cpu_chain 리스트에 우선 순위 0으로 추가한다.
radix_tree_node_ctor()
lib/radix-tree.c
radix_tree_node_ctor(void *arg) { struct radix_tree_node *node = arg; memset(node, 0, sizeof(*node)); INIT_LIST_HEAD(&node->private_list); }
radix 트리 노드를 0으로 만들고 private_list를 초기화한다.
radix_tree_init_maxindex()
lib/radix-tree.c
static __init void radix_tree_init_maxindex(void) { unsigned int i; for (i = 0; i < ARRAY_SIZE(height_to_maxindex); i++) height_to_maxindex[i] = __maxindex(i); }
height 별로 최대 인덱스 값을 산출하여 전역 height_to_maxindex[] 배열에 저장한다.
다음 그림은 height 별로 최대 인덱스 값을 산출하는 모습을 보여준다.
lib/radix-tree.c
/* * The height_to_maxindex array needs to be one deeper than the maximum * path as height 0 holds only 1 entry. */ static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH + 1] __read_mostly;
__maxindex()
lib/radix-tree.c
static __init unsigned long __maxindex(unsigned int height) { unsigned int width = height * RADIX_TREE_MAP_SHIFT; int shift = RADIX_TREE_INDEX_BITS - width; if (shift < 0) return ~0UL; if (shift >= BITS_PER_LONG) return 0UL; return ~0UL >> shift; }
height에 따른 최대 인덱스 값을 반환한다.
- 예) 32bit, height=2
- 4095 (0xfff)
- 예) 32bit, height=6
- 0xffff_ffff
radix_tree_callback()
lib/radix-tree.c
static int radix_tree_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { int cpu = (long)hcpu; struct radix_tree_preload *rtp; /* Free per-cpu pool of perloaded nodes */ if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { rtp = &per_cpu(radix_tree_preloads, cpu); while (rtp->nr) { kmem_cache_free(radix_tree_node_cachep, rtp->nodes[rtp->nr-1]); rtp->nodes[rtp->nr-1] = NULL; rtp->nr--; } } return NOTIFY_OK; }
cpu가 offline 상태로 변경되는 경우 per-cpu 타입의 전역 radix_tree_preloads 캐시에 미리 준비해둔 radix_tree_node를 slub 캐시에 반환한다.
참조
- Radix Tree | 문c