WRITE_ONCE in linux kernel lists
<p>I am reading the <a href="https://github.com/torvalds/linux/blob/master/include/linux/list.h">linux kernel implementation</a> of doubled linked list. I do not understand the use of the macro <code>WRITE_ONCE(x, val)</code>. It is defined as follow in compiler.h:</p>

<pre><code>#define WRITE_ONCE(x, val) x=(val)
</code></pre>

<p>It is used seven times in the file, such as</p>

<pre><code>static inline void __list_add(struct list_head *new,
                  struct list_head *prev,
                  struct list_head *next)
{
    next-&gt;prev = new;
    new-&gt;next = next;
    new-&gt;prev = prev;
    WRITE_ONCE(prev-&gt;next, new);
}
</code></pre>

<p>I have read that it is used for avoiding race conditions.</p>

<p>I have two questions:<br>
1/ I thought macro was replace by code at compile time. So how this code differs to the following one ? How this macro can avoid race conditions ?</p>

<pre><code>static inline void __list_add(struct list_head *new,
                  struct list_head *prev,
                  struct list_head *next)
{
    next-&gt;prev = new;
    new-&gt;next = next;
    new-&gt;prev = prev;
    prev-&gt;next = new;
}
</code></pre>

<p>2/ How to know when we should use it ? For instance, it is used for <code>__lst_add()</code> but not for <code>__lst_splice()</code>:</p>

<pre><code>static inline void __list_splice(const struct list_head *list,
                 struct list_head *prev,
                 struct list_head *next)
{
    struct list_head *first = list-&gt;next;
    struct list_head *last = list-&gt;prev;

    first-&gt;prev = prev;
    prev-&gt;next = first;

    last-&gt;next = next;
    next-&gt;prev = last;
}
</code></pre>

<p>edit:<br>
Here is a commit message concerning this file and <code>WRITE_ONCE</code>, but it does not help me to understand anything...</p>

<blockquote>
  <p><strong>list: Use WRITE_ONCE() when initializing list_head structures</strong><br>
  Code that does lockless emptiness testing of non-RCU lists is relying
  on INIT_LIST_HEAD() to write the list head's ->next pointer
  atomically, particularly when INIT_LIST_HEAD() is invoked from
  list_del_init(). This commit therefore adds WRITE_ONCE() to this
  function's pointer stores that could affect the head's ->next pointer.</p>
</blockquote>