Commit dd12805ed1db7 ("XArray: Remove radix tree compatibility") on
linux-next changes the definition of 'radix_tree_root' back to be a struct.
The content however differs from the original 'struct radix_tree_root'.
Thus attempts to debug current linux-next kernels fail with 'radix trees do
not exist or have changed their format'. Because the new 'struct
radix_tree_root' and 'struct xarray' have nearly the same layout the
functionality for XArrays can be reused.
Signed-off-by: Philipp Rudo <prudo(a)linux.ibm.com>
---
bpf.c | 7 ++++++-
filesys.c | 4 +++-
ipcs.c | 5 ++++-
kernel.c | 11 ++++++++---
task.c | 15 +++++++++++----
tools.c | 5 ++++-
6 files changed, 36 insertions(+), 11 deletions(-)
diff --git a/bpf.c b/bpf.c
index 6eacb9a..056e286 100644
--- a/bpf.c
+++ b/bpf.c
@@ -221,7 +221,12 @@ bpf_init(struct bpf_info *bpf)
bpf->idr_type = IDR_ORIG;
do_old_idr(IDR_ORIG_INIT, 0, NULL);
} else if (STREQ(MEMBER_TYPE_NAME("idr", "idr_rt"),
"radix_tree_root"))
- bpf->idr_type = IDR_RADIX;
+ if (MEMBER_EXISTS("radix_tree_root", "rnode"))
+ bpf->idr_type = IDR_RADIX;
+ else if (MEMBER_EXISTS("radix_tree_root", "xa_head"))
+ bpf->idr_type = IDR_XARRAY;
+ else
+ error(FATAL, "cannot determine IDR list type\n");
else if (STREQ(MEMBER_TYPE_NAME("idr", "idr_rt"),
"xarray"))
bpf->idr_type = IDR_XARRAY;
else
diff --git a/filesys.c b/filesys.c
index 9305627..6abba0b 100644
--- a/filesys.c
+++ b/filesys.c
@@ -2217,7 +2217,9 @@ dump_inode_page_cache_info(ulong inode)
xarray = root_rnode = count = 0;
if (MEMBER_EXISTS("address_space", "i_pages") &&
- STREQ(MEMBER_TYPE_NAME("address_space", "i_pages"),
"xarray"))
+ (STREQ(MEMBER_TYPE_NAME("address_space", "i_pages"),
"xarray") ||
+ (STREQ(MEMBER_TYPE_NAME("address_space", "i_pages"),
"radix_tree_root") &&
+ MEMBER_EXISTS("radix_tree_root", "xa_head"))))
xarray = i_mapping + OFFSET(address_space_page_tree);
else
root_rnode = i_mapping + OFFSET(address_space_page_tree);
diff --git a/ipcs.c b/ipcs.c
index 2553bac..3c26620 100644
--- a/ipcs.c
+++ b/ipcs.c
@@ -206,7 +206,10 @@ ipcs_init(void)
if (STREQ(MEMBER_TYPE_NAME("idr", "idr_rt"), "xarray"))
ipcs_table.init_flags |= IDR_XARRAY;
else
- ipcs_table.init_flags |= IDR_RADIX;
+ if (MEMBER_EXISTS("radix_tree_root", "rnode"))
+ ipcs_table.init_flags |= IDR_RADIX;
+ else if (MEMBER_EXISTS("radix_tree_root", "xa_head"))
+ ipcs_table.init_flags |= IDR_XARRAY;
} else
ipcs_table.init_flags |= IDR_ORIG;
diff --git a/kernel.c b/kernel.c
index 9f5ba89..8080097 100644
--- a/kernel.c
+++ b/kernel.c
@@ -534,9 +534,14 @@ kernel_init()
if (kernel_symbol_exists("irq_desc_tree")) {
get_symbol_type("irq_desc_tree", NULL, &req);
- kt->flags2 |= STREQ(req.type_tag_name, "xarray") ?
- IRQ_DESC_TREE_XARRAY : IRQ_DESC_TREE_RADIX;
-
+ if (STREQ(req.type_tag_name, "xarray")) {
+ kt->flags2 |= IRQ_DESC_TREE_XARRAY;
+ } else {
+ if (MEMBER_EXISTS("radix_tree_root", "xa_head"))
+ kt->flags2 |= IRQ_DESC_TREE_XARRAY;
+ else
+ kt->flags2 |= IRQ_DESC_TREE_RADIX;
+ }
}
STRUCT_SIZE_INIT(irq_data, "irq_data");
if (VALID_STRUCT(irq_data)) {
diff --git a/task.c b/task.c
index cd118e5..36a90d6 100644
--- a/task.c
+++ b/task.c
@@ -507,10 +507,17 @@ task_init(void)
OFFSET(pid_namespace_idr) + OFFSET(idr_idr_rt);
tt->flags |= PID_XARRAY;
} else if STREQ(MEMBER_TYPE_NAME("idr", "idr_rt"),
"radix_tree_root") {
- tt->refresh_task_table = refresh_radix_tree_task_table;
- tt->pid_radix_tree = symbol_value("init_pid_ns") +
- OFFSET(pid_namespace_idr) + OFFSET(idr_idr_rt);
- tt->flags |= PID_RADIX_TREE;
+ if (MEMBER_EXISTS("radix_tree_root", "rnode")) {
+ tt->refresh_task_table = refresh_radix_tree_task_table;
+ tt->pid_radix_tree = symbol_value("init_pid_ns") +
+ OFFSET(pid_namespace_idr) + OFFSET(idr_idr_rt);
+ tt->flags |= PID_RADIX_TREE;
+ } else if (MEMBER_EXISTS("radix_tree_root", "xa_head")) {
+ tt->refresh_task_table = refresh_xarray_task_table;
+ tt->pid_xarray = symbol_value("init_pid_ns") +
+ OFFSET(pid_namespace_idr) + OFFSET(idr_idr_rt);
+ tt->flags |= PID_XARRAY;
+ }
} else
error(FATAL, "unknown pid_namespace.idr type: %s\n",
MEMBER_TYPE_NAME("idr", "idr_rt"));
diff --git a/tools.c b/tools.c
index 72ec76a..43b838a 100644
--- a/tools.c
+++ b/tools.c
@@ -4241,7 +4241,10 @@ cmd_tree()
}
if (STRNEQ(optarg, "ra"))
- type_flag = RADIXTREE_REQUEST;
+ if (MEMBER_EXISTS("radix_tree_root", "xa_head"))
+ type_flag = XARRAY_REQUEST;
+ else
+ type_flag = RADIXTREE_REQUEST;
else if (STRNEQ(optarg, "rb"))
type_flag = RBTREE_REQUEST;
else if (STRNEQ(optarg, "x"))
--
2.16.4