[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251001134628.GD20441@redhat.com>
Date: Wed, 1 Oct 2025 15:46:31 +0200
From: Oleg Nesterov <oleg@...hat.com>
To: Peter Zijlstra <peterz@...radead.org>
Cc: Boqun Feng <boqun.feng@...il.com>, David Howells <dhowells@...hat.com>,
Ingo Molnar <mingo@...hat.com>, Li RongQing <lirongqing@...du.com>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Waiman Long <longman@...hat.com>, Will Deacon <will@...nel.org>,
linux-kernel@...r.kernel.org
Subject: Re: [RFC 2/1] seqlock: make the read_seqbegin_or_lock() API more
simple and less error-prone ?
On 10/01, Oleg Nesterov wrote:
>
> +static inline int xxx(seqlock_t *lock, int lockless, int *seq, unsigned long *flags)
> +{
> + if (lockless) {
> + *seq = read_seqbegin(lock);
> + return 1;
> + } else if (*seq & 1) {
> + if (flags)
> + read_sequnlock_excl_irqrestore(lock, *flags);
> + else
> + read_sequnlock_excl(lock);
> + return 0;
> + } else if (read_seqretry(lock, *seq)) {
> + if (flags)
> + read_seqlock_excl_irqsave(lock, *flags);
> + else
> + read_seqlock_excl(lock);
> + *seq = 1;
> + return 1;
> + } else {
> + return 0;
> + }
> +}
> +
> +#define __XXX(lock, lockless, seq, flags) \
> + for (int lockless = 1, seq; xxx(lock, lockless, &seq, flags); lockless = 0)
> +
> +#define XXX(lock, flags) \
> + __XXX(lock, __UNIQUE_ID(lockless), __UNIQUE_ID(seq), flags)
Note that __XXX() can have users too. See the patch below. Not that it makes a
lot of sense, just for example.
Oleg.
diff --git a/fs/d_path.c b/fs/d_path.c
index bb365511066b..b4cde188be4f 100644
--- a/fs/d_path.c
+++ b/fs/d_path.c
@@ -332,28 +332,23 @@ static char *__dentry_path(const struct dentry *d, struct prepend_buffer *p)
{
const struct dentry *dentry;
struct prepend_buffer b;
- int seq = 0;
rcu_read_lock();
-restart:
- dentry = d;
- b = *p;
- read_seqbegin_or_lock(&rename_lock, &seq);
- while (!IS_ROOT(dentry)) {
- const struct dentry *parent = dentry->d_parent;
+ __XXX(&rename_lock, lockless, seq, NULL) {
+ dentry = d;
+ b = *p;
+ while (!IS_ROOT(dentry)) {
+ const struct dentry *parent = dentry->d_parent;
- prefetch(parent);
- if (!prepend_name(&b, &dentry->d_name))
- break;
- dentry = parent;
- }
- if (!(seq & 1))
- rcu_read_unlock();
- if (need_seqretry(&rename_lock, seq)) {
- seq = 1;
- goto restart;
+ prefetch(parent);
+ if (!prepend_name(&b, &dentry->d_name))
+ break;
+ dentry = parent;
+ }
+ if (lockless)
+ rcu_read_unlock();
}
- done_seqretry(&rename_lock, seq);
+
if (b.len == p->len)
prepend_char(&b, '/');
return extract_string(&b);
Powered by blists - more mailing lists