From 9be99d4ad3a507adf0fb01ecb361e8efff3f130f Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 30 May 2013 22:10:38 -0400 Subject: [PATCH] rcuja fix: perform lookup in attach node Handles case where the existing location is not yet reserved. Therefore, a pointer check cannot be used to check if it has been concurrently populated. A full-blown lookup is therefore required. Signed-off-by: Mathieu Desnoyers --- rcuja/rcuja.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/rcuja/rcuja.c b/rcuja/rcuja.c index 84c1fb7..b0d3322 100644 --- a/rcuja/rcuja.c +++ b/rcuja/rcuja.c @@ -1674,6 +1674,27 @@ int ja_attach_node(struct cds_ja *ja, goto unlock_parent; } + /* + * Perform a lookup query to handle the case where + * old_node_flag_ptr is NULL. We cannot use it to check if the + * node has been populated between RCU lookup and mutex + * acquisition. + */ + if (!old_node_flag_ptr) { + uint8_t iter_key; + struct cds_ja_inode_flag *lookup_node_flag; + struct cds_ja_inode_flag **lookup_node_flag_ptr; + + iter_key = (uint8_t) (key >> (JA_BITS_PER_BYTE * (ja->tree_depth - level))); + lookup_node_flag = ja_node_get_nth(attach_node_flag, + &lookup_node_flag_ptr, + iter_key); + if (lookup_node_flag) { + ret = -EEXIST; + goto unlock_parent; + } + } + if (attach_node_flag_ptr && ja_node_ptr(*attach_node_flag_ptr) != ja_node_ptr(attach_node_flag)) { /* @@ -1701,8 +1722,10 @@ int ja_attach_node(struct cds_ja *ja, iter_key, iter_node_flag, NULL, i); - if (ret) + if (ret) { + dbg_printf("branch creation error %d\n", ret); goto check_error; + } created_nodes[nr_created_nodes++] = iter_dest_node_flag; iter_node_flag = iter_dest_node_flag; } @@ -1726,8 +1749,10 @@ int ja_attach_node(struct cds_ja *ja, iter_key, iter_node_flag, shadow_node, level - 1); - if (ret) + if (ret) { + dbg_printf("branch publish error %d\n", ret); goto check_error; + } /* * Attach branch */ -- 2.34.1