idr用到了radix-tree。如果只有一个节点数据结构如下:
crash> idr ffff880b4d726dd0
struct idr {
idr_rt = {
gfp_mask = 0x6000000,
rnode = 0xffff880bd74d7909
},
idr_next = 0x0
}
crash> radix_tree_node ffff880bd74d7908
struct radix_tree_node {
shift = 0x0,
offset = 0x0,
count = 0x1,
exceptional = 0x0,
parent = 0x0,
root = 0xffff880b4d726dd0,
{
private_list = {
next = 0xffff880bd74d7920,
prev = 0xffff880bd74d7920
},
callback_head = {
next = 0xffff880bd74d7920,
func = 0xffff880bd74d7920
}
},
slots = {0x0, 0xffff880b4d726000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
tags = {{0xfffffffffffffffd}, {0x0}, {0x0}}
}
这里有几点需要注意。第一,如果node末位是1,说明不是叶子节点。dump的时候一定要把1去掉。
#define RADIX_TREE_ENTRY_MASK 3UL
#define RADIX_TREE_INTERNAL_NODE 1UL
static inline bool radix_tree_is_internal_node(void *ptr)
{
return ((unsigned long)ptr & RADIX_TREE_ENTRY_MASK) ==
RADIX_TREE_INTERNAL_NODE;
}
第二,count就是孩子的个数,包括中间节点和叶子节点。
第三,tags就是bitmap,是叶子节点置为0。否则为1。
再举个例子63个节点的例子:
crash> radix_tree_node ffff880bc1dc16d0
struct radix_tree_node {
shift = 0x0,
offset = 0x0,
count = 0x3f,
exceptional = 0x0,
parent = 0x0,
root = 0xffff880b5354add0,
{
private_list = {
next = 0xffff880bc1dc16e8,
prev = 0xffff880bc1dc16e8
},
callback_head = {
next = 0xffff880bc1dc16e8,
func = 0xffff880bc1dc16e8
}
},
slots = {0x0, 0xffff880b5354aa00, 0xffff880b5354b800, 0xffff880b5354ba00, 0xffff880b5354b600, 0xffff880b53548600, 0xffff880b5354b200, 0xffff880b53549a00, 0xffff880b5354a800, 0xffff880b53548400, 0xffff880b5354bc00, 0xffff880b5354b400, 0xffff880b5354be00, 0xffff880b5354ae00, 0xffff880b53549400, 0xffff880b53549e00, 0xffff880b53549200, 0xffff880b5354b000, 0xffff880b53549c00, 0xffff880b5354a400, 0xffff880b53548800, 0xffff880b53549800, 0xffff880b5354a000, 0xffff880b53549000, 0xffff880b53548c00, 0xffff880b53548200, 0xffff880b5354a200, 0xffff880b53548a00, 0xffff880b9a415600, 0xffff880b9a417600, 0xffff880b9a415800, 0xffff880b9a417200, 0xffff880b9a417800, 0xffff880b9a414800, 0xffff880b9a414200, 0xffff880b9a414000, 0xffff880b9a414e00, 0xffff880b9a415000, 0xffff880b9a417400, 0xffff880b9a414600, 0xffff880b9a416400, 0xffff880b9a414c00, 0xffff880b9a414a00, 0xffff880b9a415200, 0xffff880b5e3f7c00, 0xffff880b5e3f5400, 0xffff880b5e3f4400, 0xffff880b5e3f6e00, 0xffff880b5e3f5e00, 0xffff880b5e3f5c00, 0xffff880b5e3f7a00, 0xffff880b5e3f4c00, 0xffff880b5e3f6200, 0xffff880b5e3f5800, 0xffff880b5e3f6000, 0xffff880b5e3f7200, 0xffff880b5e3f6800, 0xffff880b5e3f5a00, 0xffff880b5e3f6400, 0xffff880b5e3f5000, 0xffff880b5e3f6c00, 0xffff880b5e3f4800, 0xffff880b5c46e000, 0xffff880b5c46ea00},
tags = {{0x1}, {0x0}, {0x0}}
}
那么offset是什么的?首先创建有200个节点的树。
crash> radix_tree_node ffff880bd74d76c0
struct radix_tree_node {
shift = 0x6,
offset = 0x0,
count = 0x4,
exceptional = 0x0,
parent = 0x0,
root = 0xffff880b4d7247d0,
{
private_list = {
next = 0xffff880bd74d76d8,
prev = 0xffff880bd74d76d8
},
callback_head = {
next = 0xffff880bd74d76d8,
func = 0xffff880bd74d76d8
}
},
slots = {0xffff880bd74d7b51, 0xffff880bd74d7479, 0xffff880bd74d6da1, 0xffff880bd74d6fe9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
tags = {{0xfffffffffffffff9}, {0x0}, {0x0}}
}
crash> radix_tree_node.offset 0xffff880bd74d7b50
offset = 0x0
crash> radix_tree_node.offset 0xffff880bd74d7478
offset = 0x1
crash> radix_tree_node.offset 0xffff880bd74d6da0
offset = 0x2
crash> radix_tree_node.offset 0xffff880bd74d6fe8
offset = 0x3
应该可以理解为孩子的编号,从0开始。