33 Beware that lockless_lookup(key) cannot use traditional hlist_for_each_entry_rcu()
34 but a version 【with an additional memory barrier (smp_rmb())】
35
36 lockless_lookup(key)
37 {
38 struct hlist_node *node, *next;
39 for (pos = rcu_dereference((head)->first);
40 pos && ({ next = pos->next; smp_rmb(); prefetch(next); 1; }) &&
41 ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; });
42 pos = rcu_dereference(next))
43 if (obj->key == key)
44 return obj;
45 return NULL;
后面引用了一句話:
59 Quoting Corey Minyard :
60
.66 。。。。。。。。。。。。。。。。。。。。。 I think that this can be
67 solved 【by pre-fetching the "next" field (with proper barriers) before
68 checking the key】."
最后,在介紹hlist_null優(yōu)勢的時(shí)候,是這么說的
112 With hlist_nulls we can 【avoid extra smp_rmb()】 in lockless_lookup()
113 and 【extra smp_wmb()】in insert function.
插入的時(shí)候特別強(qiáng)調(diào)了新的key必須在新的next之前可見,不知道是不是問題的關(guān)鍵?
73 We need to make sure a reader cannot read the new 'obj->obj_next' value
74 and previous value of 'obj->key'. Or else, an item could be deleted
75 from a chain, and inserted into another chain. If new chain was empty
76 before the move, 'next' pointer is NULL, and lockless reader can
77 not detect it missed following items in original chain.