X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=include%2Flinux%2Frculist.h;h=eb4443c7e05be213f49596b81b50f209923ab4da;hb=ce04a6fe7d4fa103a0fe0daf7965da0703d5a9e1;hp=b0f39be08b6c31a6d723f107e52cc31a7f3b1f78;hpb=5b664cb235e97afbf34db9c4d77f08ebd725335e;p=linux-2.6-omap-h63xx.git diff --git a/include/linux/rculist.h b/include/linux/rculist.h index b0f39be08b6..eb4443c7e05 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h @@ -97,6 +97,34 @@ static inline void list_del_rcu(struct list_head *entry) entry->prev = LIST_POISON2; } +/** + * hlist_del_init_rcu - deletes entry from hash list with re-initialization + * @n: the element to delete from the hash list. + * + * Note: list_unhashed() on the node return true after this. It is + * useful for RCU based read lockfree traversal if the writer side + * must know if the list entry is still hashed or already unhashed. + * + * In particular, it means that we can not poison the forward pointers + * that may still be used for walking the hash list and we can only + * zero the pprev pointer so list_unhashed() will return true after + * this. + * + * The caller must take whatever precautions are necessary (such as + * holding appropriate locks) to avoid racing with another + * list-mutation primitive, such as hlist_add_head_rcu() or + * hlist_del_rcu(), running on this same list. However, it is + * perfectly legal to run concurrently with the _rcu list-traversal + * primitives, such as hlist_for_each_entry_rcu(). + */ +static inline void hlist_del_init_rcu(struct hlist_node *n) +{ + if (!hlist_unhashed(n)) { + __hlist_del(n); + n->pprev = NULL; + } +} + /** * list_replace_rcu - replace old entry by new one * @old : the element to be replaced