BUG/MAJOR: ebtree/scope: properly tag upper nodes during insertion

Christopher found a case where some tasks would remain unseen in the run
queue and would spontaneously appear after certain apparently unrelated
operations performed by the other thread.

It's in fact the insertion which is not correct, the node serving as the
top of duplicate tree wasn't properly updated, just like the each top of
subtree in a duplicate tree. This had the effect that after some removals,
the incorrectly tagged node would hide the underlying ones, which would
then suddenly re-appear once they were removed.

This is 1.8-specific, no backport is needed.
This commit is contained in:
Willy Tarreau 2017-11-15 19:38:29 +01:00
parent 9c1e15d8cd
commit 318d0c2055

View File

@ -57,6 +57,8 @@ REGPRM1 struct eb32sc_node *eb32sc_insert_dup(struct eb_node *sub, struct eb_nod
} }
eb32 = container_of(head, struct eb32sc_node, node); eb32 = container_of(head, struct eb32sc_node, node);
if (!(eb32->node_s & scope))
eb32->node_s |= scope;
} }
/* Here we have a leaf attached to (head)->b[EB_RGHT] */ /* Here we have a leaf attached to (head)->b[EB_RGHT] */
@ -154,6 +156,10 @@ REGPRM2 struct eb32sc_node *eb32sc_insert(struct eb_root *root, struct eb32sc_no
struct eb32sc_node, node.branches); struct eb32sc_node, node.branches);
old_node_bit = old->node.bit; old_node_bit = old->node.bit;
/* our new node will be found through this one, we must mark it */
if ((old->node_s | scope) != old->node_s)
old->node_s |= scope;
/* Stop going down when we don't have common bits anymore. We /* Stop going down when we don't have common bits anymore. We
* also stop in front of a duplicates tree because it means we * also stop in front of a duplicates tree because it means we
* have to insert above. * have to insert above.
@ -172,9 +178,6 @@ REGPRM2 struct eb32sc_node *eb32sc_insert(struct eb_root *root, struct eb32sc_no
} }
/* walk down */ /* walk down */
if ((old->node_s | scope) != old->node_s)
old->node_s |= scope;
root = &old->node.branches; root = &old->node.branches;
side = (newkey >> old_node_bit) & EB_NODE_BRANCH_MASK; side = (newkey >> old_node_bit) & EB_NODE_BRANCH_MASK;
troot = root->b[side]; troot = root->b[side];