On Thu, May 22, 2014 at 05:37:41PM -0700, Jarno Rajahalme wrote:
> Add cmap_replace() and cmap_first(), as well as CMAP_FOR_EACH_SAFE and
> CMAP_FOR_EACH_CONTINUE to make porting existing hmap using code a bit
> easier.
> 
> CMAP_FOR_EACH_SAFE is useful in RCU postponed destructors, when it is
> known that additional postponing is not needed.
> 
> Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>

I am not sure that ovsrcu_init() may be used in cmap_replace__() here.
I believe that we need to make sure that the store to replacement->next
becomes visible before the store to b->nodes[slot].  I am not sure that
a single release fence is sufficient, because I believe that the write
to replacement->next could still get reordered after the write to
b->nodes[slot].  After all, both are on the same side of the release
fence:

    /* The pointer to 'node' is changed to point to 'replacement',
     * which is the next node if no replacement node is given. */
    if (!replacement) {
        replacement = cmap_node_next_protected(node);
    } else {
        /* 'replacement' takes the position of 'node' in the list. */
        ovsrcu_init(&replacement->next, cmap_node_next_protected(node));
    }

    if (b->nodes[slot] == node) {
        b->nodes[slot] = replacement;
        atomic_thread_fence(memory_order_release);

The purpose of CMAP_FOR_EACH_SAFE in cmap is different enough from the
typical use to deserve an explanatory comment.  (At least, the comment
claiming that there is no CMAP_FOR_EACH_SAFE macro needs to be fixed.)

Thanks,

Ben.
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to