From: Willy Tarreau Date: Wed, 15 Nov 2017 18:38:29 +0000 (+0100) Subject: BUG/MAJOR: ebtree/scope: properly tag upper nodes during insertion X-Git-Tag: v1.8-rc4~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=318d0c205581aa1bbc493872b84e683f3bc3034b;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/ebtree/eb32sctree.c b/ebtree/eb32sctree.c index a8a38f8ce5..e703434350 100644 --- a/ebtree/eb32sctree.c +++ b/ebtree/eb32sctree.c @@ -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); + if (!(eb32->node_s & scope)) + eb32->node_s |= scope; } /* 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); 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 * also stop in front of a duplicates tree because it means we * have to insert above. @@ -172,9 +178,6 @@ REGPRM2 struct eb32sc_node *eb32sc_insert(struct eb_root *root, struct eb32sc_no } /* walk down */ - if ((old->node_s | scope) != old->node_s) - old->node_s |= scope; - root = &old->node.branches; side = (newkey >> old_node_bit) & EB_NODE_BRANCH_MASK; troot = root->b[side];