Re: [PATCH] rxrpc_find_service_conn_rcu: use read_seqbegin() rather than read_seqbegin_or_lock()

From: Oleg Nesterov
Date: Wed Nov 01 2023 - 19:18:56 EST


On 11/01, Al Viro wrote:
>
> On Wed, Nov 01, 2023 at 10:52:15PM +0100, Oleg Nesterov wrote:
>
> > > Why would you want to force that "switch to locked on the second pass" policy
> > > on every possible caller?
> >
> > Because this is what (I think) read_seqbegin_or_lock() is supposed to do.
> > It should take the lock for writing if the lockless access failed. At least
> > according to the documentation.
>
> Not really - it's literally seqbegin or lock, depending upon what the caller
> tells it...

OK, I won't argue right now. But again, this patch doesn't change the current
behaviour. Exactly because the caller does NOT tell read_seqbegin_or_lock() that
it wants "or lock" on the 2nd pass.

> Take a look at d_walk() and try to shoehorn that into your variant. Especially
> the D_WALK_NORETRY handling...

I am already sleeping, quite possibly I am wrong. But it seems that if we change
done_seqretry() then d_walk() needs something like

--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1420,7 +1420,7 @@ static void d_walk(struct dentry *parent, void *data,
spin_lock(&this_parent->d_lock);

/* might go back up the wrong parent if we have had a rename. */
- if (need_seqretry(&rename_lock, seq))
+ if (need_seqretry(&rename_lock, &seq))
goto rename_retry;
/* go into the first sibling still alive */
do {
@@ -1432,22 +1432,20 @@ static void d_walk(struct dentry *parent, void *data,
rcu_read_unlock();
goto resume;
}
- if (need_seqretry(&rename_lock, seq))
+ if (need_seqretry(&rename_lock, &seq))
goto rename_retry;
rcu_read_unlock();

out_unlock:
spin_unlock(&this_parent->d_lock);
- done_seqretry(&rename_lock, seq);
+ done_seqretry(&rename_lock, &seq);
return;

rename_retry:
spin_unlock(&this_parent->d_lock);
rcu_read_unlock();
- BUG_ON(seq & 1);
if (!retry)
return;
- seq = 1;
goto again;
}


But again, again, this is off-topic and needs another discussion. Right now I am just
trying to audit the users of read_seqbegin_or_lock/need_seqretry and change those who
use them incorrectly.

Oleg.