Re: [PATCH 1/1] documentation: seqlock: fix the wrong documentation of read_seqbegin_or_lock/need_seqretry
From: Oleg Nesterov
Date: Thu Oct 02 2025 - 07:03:28 EST
Hi Waiman,
This is probably my fault, but I can't understand your emails. So let me start
from the very beginning and write another reply to this email.
I don't think that we can change include/linux/seqlock.h so that this change
will make the documentation correct without changing/breaking the existing code.
But perhaps I misunderstood you...
And just in case... of course need_seqretry_xxx() and/or XXX() must be renamed.
On 10/01, Waiman Long wrote:
>
> On 9/28/25 12:20 PM, Oleg Nesterov wrote:
> >- int seq = 0;
> >+ int seq = 1;
> > do {
> >+ seq++; /* 2 on the 1st/lockless path, otherwise odd */
> > read_seqbegin_or_lock(&foo_seqlock, &seq);
> > /* ... [[read-side critical section]] ... */
>
> It is kind of odd to initialize the sequence to 1 and add an sequence
> increment inside the loop.
Sure. That is why I am proposing the new helper which can be used instead
need_seqretry(). You named it need_seqretry_once() below.
Now, from Documentation/locking/seqlock.rst before this patch:
/* marker; even initialization */
int seq = 0;
do {
read_seqbegin_or_lock(&foo_seqlock, &seq);
/* ... [[read-side critical section]] ... */
} while (need_seqretry(&foo_seqlock, seq));
done_seqretry(&foo_seqlock, seq);
> Perhaps we can do something like:
>
> --- a/include/linux/seqlock.h
> +++ b/include/linux/seqlock.h
> @@ -1126,6 +1126,9 @@ read_sequnlock_excl_irqrestore(seqlock_t *sl, unsigned
> long flags)
> */
> static inline void read_seqbegin_or_lock(seqlock_t *lock, int *seq)
> {
> + if (!(*seq & 1)) /* Reread sequence # if even */
> + *seq = seqprop_sequence(&lock->seqcount);
> +
Why? I don't understand this change...
> +static inline int need_seqretry_once(seqlock_t *lock, int *seq)
> +{
> + int ret = !(*seq & 1) && read_seqretry(lock, *seq);
> +
> + if (ret)
> + *seq = 1; /* Enforce locking in next iteration */
> + return ret;
> +}
>
> With this, the current document should be good.
No? How can this change make the pseudo code above correct? It will never
take the lock. OK, unless CONFIG_PREEMPT_RT=y but this is another story.
And the documentation is still wrong in this respect.
> Users have the option of
> using need_seqretry_once() to enforce at most 1 iteration.
So we need to change the pseudo code above
- } while (need_seqretry(&foo_seqlock, seq));
+ } while (need_seqretry_once(&foo_seqlock, &seq));
and this is exactly what I am trying to suggest in "RFC 2/1".
So I think we should fix the docs, and the new helper(s), and update the
current users one-by-one.
Oleg.