----- Original Message -----
----- Original Message -----
As it turns out, the radix tree problem I reported seems to be an
issue
associated with the kernel version.
But when I try the same thing on a RHEL5 kernel, it always fails
like
this:
crash> tree -t radix -r address_space.page_tree ffff81012eab2e00
radix_tree_node at ffff81011f9932e8
struct radix_tree_node {
count = 0x6,
slots = {0xffff810103c06490, 0xffff810103c1c760,
0xffff810103c58580, 0xffff810103bfb750, 0xffff810103e84cd8,
0xffff810103bf8b5
8, 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 = {{0x0}, {0x0}}
}
tree: height 1536 is greater than height_to_maxindex[]
index 12
crash>
The reason that the command fails on RHEL5 is due to this part of
your patch:
3766 void rdtree_iteration(ulong node_p, struct tree_data *td, char * ppos, ulong
indexnum)
3767 {
3768 uint height;
3769 ulong slot;
3770 int index;
3771 int i;
3772 char pos[BUFSIZE];
3773
3774 if (indexnum != -1)
3775 sprintf(pos, "%s/%ld", ppos, indexnum);
3776 else
3777 sprintf(pos, "%s", ppos);
3778
3779 readmem(node_p + MEMBER_OFFSET("radix_tree_node",
"height"), KVADDR,
3780 &height, sizeof(uint), "radix_tree_node height",
FAULT_ON_ERROR);
3781
3782 if (height > ARRAY_LENGTH(height_to_maxindex)) {
3783 fprintf(fp, "radix_tree_node at %lx\n", node_p);
3784 dump_struct("radix_tree_node", node_p, RADIX(16));
3785 error(FATAL, "height %d is greater than height_to_maxindex[]
\
3786 index %ld\n", height,
ARRAY_LENGTH(height_to_maxindex));
3787 }
In line 3779, you calculate "height" using:
MEMBER_OFFSET("radix_tree_node", "height")
which returns -1, because RHEL5's radix_tree_node does not have a "height"
member:
crash> radix_tree_node
struct radix_tree_node {
unsigned int count;
void *slots[64];
long unsigned int tags[2][1];
}
SIZE: 536
crash>
In RHEL6, a radix_tree_node structure does have a "height" member:
crash> radix_tree_node
struct radix_tree_node {
unsigned int height;
unsigned int count;
struct rcu_head rcu_head;
void *slots[64];
long unsigned int tags[3][1];
}
SIZE: 560
crash>
In any case, I now see that your patch uses MEMBER_OFFSET(...) in 4 places:
$ grep MEMBER_OFFSET 0001-add-a-new-command-tree.patch
+ readmem(node_p + MEMBER_OFFSET("radix_tree_node", "height"),
KVADDR,
+ readmem(td->start + MEMBER_OFFSET("rb_root",
"rb_node"), KVADDR,
+ readmem(node_p+MEMBER_OFFSET("rb_node", "rb_left"), KVADDR,
&left_p,
+ readmem(node_p+MEMBER_OFFSET("rb_node", "rb_right"), KVADDR,
&right_p,
$
which is not acceptable, because it hides these kinds of programming errors.
For each of the 4 structure members above, add them to the offset_table[] array,
initialize them with MEMBER_OFFSET_INIT(), and use OFFSET(...) instead of
MEMBER_OFFSET(). Then if your code is incorrect as above, it will fail
immediately and show a meaningful error message.
Dave