Commit dd12805ed1db7 in the linux-next kernel repository, titled

"XArray: Remove radix tree compatibility", changes the definition
of "radix_tree_root" back to be a struct.  However, the content of
the new structure differs from the original structure, so without
the patch, current linux-next kernels fail during initialization
with the error message "radix trees do not exist or have changed
their format".  Because the new "radix_tree_root" and "xarray"
structures have nearly the same layout, the existing functionality
for XArrays can be reused.
(prudo@linux.ibm.com)
This commit is contained in:
Dave Anderson 2019-03-22 15:50:40 -04:00
parent 2eadad07aa
commit 4d55112701
6 changed files with 38 additions and 12 deletions

7
bpf.c
View File

@ -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

View File

@ -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);

8
ipcs.c
View File

@ -205,8 +205,12 @@ ipcs_init(void)
if (VALID_MEMBER(idr_idr_rt)) {
if (STREQ(MEMBER_TYPE_NAME("idr", "idr_rt"), "xarray"))
ipcs_table.init_flags |= IDR_XARRAY;
else
ipcs_table.init_flags |= IDR_RADIX;
else {
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;

View File

@ -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)) {

15
task.c
View File

@ -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"));

View File

@ -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"))