* RCU-protected list version
  */
 #include <linux/list.h>
+#include <linux/rcupdate.h>
 
 /*
  * Insert a new entry between two known consecutive entries.
 {
        new->next = next;
        new->prev = prev;
-       smp_wmb();
+       rcu_assign_pointer(prev->next, new);
        next->prev = new;
-       prev->next = new;
 }
 
 /**
 {
        new->next = old->next;
        new->prev = old->prev;
-       smp_wmb();
+       rcu_assign_pointer(new->prev->next, new);
        new->next->prev = new;
-       new->prev->next = new;
        old->prev = LIST_POISON2;
 }
 
         */
 
        last->next = at;
-       smp_wmb();
-       head->next = first;
+       rcu_assign_pointer(head->next, first);
        first->prev = head;
        at->prev = last;
 }
 
        new->next = next;
        new->pprev = old->pprev;
-       smp_wmb();
+       rcu_assign_pointer(*new->pprev, new);
        if (next)
                new->next->pprev = &new->next;
-       *new->pprev = new;
        old->pprev = LIST_POISON2;
 }
 
                                        struct hlist_head *h)
 {
        struct hlist_node *first = h->first;
+
        n->next = first;
        n->pprev = &h->first;
-       smp_wmb();
+       rcu_assign_pointer(h->first, n);
        if (first)
                first->pprev = &n->next;
-       h->first = n;
 }
 
 /**
 {
        n->pprev = next->pprev;
        n->next = next;
-       smp_wmb();
+       rcu_assign_pointer(*(n->pprev), n);
        next->pprev = &n->next;
-       *(n->pprev) = n;
 }
 
 /**
 {
        n->next = prev->next;
        n->pprev = &prev->next;
-       smp_wmb();
-       prev->next = n;
+       rcu_assign_pointer(prev->next, n);
        if (n->next)
                n->next->pprev = &n->next;
 }