Daniel Xu wrote:
> Hi Akira,
>
> Thanks for taking a look!
>
> On Tue, Dec 17, 2024, at 5:53 PM, Akira Yokosawa wrote:
>> Hello,
>>
>> Daniel Xu wrote:
>>> WRITE_ONCE() is needed here to prevent store tears and other unwanted
>>> compiler optimizations.
>>
>> That might be true if there were chances of these two accesses to
>> race with each other.
>>
>> I don't see any possibility of such races.
>>
>> Can you elaborate?
>
> My understanding is that read_seqbegin() and read_seqretry()
> can execute at any time. That means the read side access of
> the sequence number can occur doing an increment.
>
> To prevent the reader from reading a partially written value,
> we need the WRITE_ONCE() to ensure the relaxed atomic
> write.
OK, now I see the race there.
But see below.
> --- a/CodeSamples/defer/seqlock.h
> +++ b/CodeSamples/defer/seqlock.h
> @@ -60,14 +60,14 @@ static inline int read_seqretry(seqlock_t *slp,
> //\lnlbl{read_seqretry:b}
> static inline void write_seqlock(seqlock_t *slp)
> //\lnlbl{write_seqlock:b}
> {
> spin_lock(&slp->lock);
> - ++slp->seq;
> + WRITE_ONCE(slp->seq, READ_ONCE(slp->seq) + 1);
^^^^^^^^^
> smp_mb();
> }
> //\lnlbl{write_seqlock:e}
>
> static inline void write_sequnlock(seqlock_t *slp)
> //\lnlbl{write_sequnlock:b}
> {
> smp_mb();
> //\lnlbl{write_sequnlock:mb}
> - ++slp->seq;
> //\lnlbl{write_sequnlock:inc}
> + WRITE_ONCE(slp->seq, READ_ONCE(slp->seq) + 1);
> //\lnlbl{write_sequnlock:inc}
^^^^^^^^^
> spin_unlock(&slp->lock);
> }
> //\lnlbl{write_sequnlock:e}
> //\end{snippet}
Those two READ_ONCE()s don't have any concurrent writes.
So there seems to be no need of them, IIUC.
Thanks, Akira