Re: [PATCH 1/1] documentation: seqlock: fix the wrong documentation of read_seqbegin_or_lock/need_seqretry

From: Waiman Long
Date: Wed Oct 01 2025 - 15:35:02 EST


On 10/1/25 3:24 PM, Waiman Long wrote:
On 10/1/25 3:06 PM, Oleg Nesterov wrote:
On 10/01, Waiman Long wrote:
On 9/28/25 12:20 PM, Oleg Nesterov wrote:
--- a/Documentation/locking/seqlock.rst
+++ b/Documentation/locking/seqlock.rst
@@ -218,13 +218,14 @@ Read path, three categories:
     according to a passed marker. This is used to avoid lockless readers
     starvation (too much retry loops) in case of a sharp spike in write
     activity. First, a lockless read is tried (even marker passed). If
-   that trial fails (odd sequence counter is returned, which is used as
-   the next iteration marker), the lockless read is transformed to a
-   full locking read and no retry loop is necessary::
+   that trial fails (sequence counter doesn't match), make the marker
+   odd for the next iteration, the lockless read is transformed to a
+   full locking read and no retry loop is necessary, for example::
      /* marker; even initialization */
-    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. But a) in this patch my only point is that the current documentation is
wrong, and b) the pseudo-code after this change becomes correct and the new
pattern already have the users. For example, do_io_accounting() and more.
Thank for letting me know, but I believe my suggested change will work with this modified loop iteration.

Perhaps we can do something like:
Perhaps. But could you please read the "RFC 2/1" thread? To me it is kind of
odd that the simple loops like this example have to even touch the sequence
counter inside the loop.

+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;
+}
And this is exactly what I tried to propose in "RFC 2/1". Plus more...

I had read that. You used _xxx() suffix which I think a good choice will be to use _once() to indicate that we only want one retry.

Note that with my suggested reading of the sequence count within read_seqbegin_or_lock(), we may not really need this extra helper. However, there is still a very slight chance that reader and writer are perfectly synchronized in such a way that an even sequence number is always read even though it is still increasing after each iteration. So this new helper is for users that is paranoid about this rare case.

Cheers,
Longman