mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Oleg Nesterov <oleg@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	Boqun Feng <boqun.feng@gmail.com>,
	David Howells <dhowells@redhat.com>,
	Ingo Molnar <mingo@redhat.com>,
	Li RongQing <lirongqing@baidu.com>,
	Waiman Long <longman@redhat.com>, Will Deacon <will@kernel.org>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 1/4] seqlock: introduce scoped_seqlock_read() and scoped_seqlock_read_irqsave()
Date: Mon, 13 Oct 2025 11:03:13 +0200	[thread overview]
Message-ID: <20251013090313.GI4067720@noisy.programming.kicks-ass.net> (raw)
In-Reply-To: <20251010131439.GB8798@redhat.com>

On Fri, Oct 10, 2025 at 03:14:39PM +0200, Oleg Nesterov wrote:
> On 10/10, Oleg Nesterov wrote:
> >
> > On 10/10, Peter Zijlstra wrote:
> > >
> > > I reordered the code, it is happier now.
> > >
> > > Anyway, the below seems to generate decent code for
> > > {-O2,-Os}x{gcc-14,clang-22}. Yay for optimizing compilers I suppose :-)
> >
> > Another approach which looks better than mine ;)
> >
> > Linus's version is simpler, but yours can handle break/return and
> > the "only lockless" case, good.
> >
> > I leave this patch to you and Linus, he seems to like your code too.
> >
> > Reviewed-by: Oleg Nesterov <oleg@redhat.com>
> >
> >
> > But... perhaps we should not "export" the _target names and instead
> > add the additional defines, something like
> >
> > 	scoped_seqlock_read()
> > 	scoped_seqlock_read_or_lock()
> > 	scoped_seqlock_read_or_lock_irqsave()
> >
> > ?
> 
> And... perhaps we can simplify this code a little bit? I mean
> 
> 	enum ss_state {
> 		ss_lockless	= 0,
> 		ss_lock		= 1,
> 		ss_lock_irqsave	= 2,
> 		ss_done		= 4,
> 	};
> 
> 	struct ss_tmp {
> 		enum ss_state	state;
> 		unsigned long	data;
> 		seqlock_t	*lock;
> 	};
> 
> 	static inline void __scoped_seqlock_cleanup(struct ss_tmp *sst)
> 	{
> 		if (sst->state & ss_lock)
> 			spin_unlock(&sst->lock.lock);
> 		if (sst->state & ss_lock_irqsave)
> 			spin_unlock_irqrestore(&sst->lock.lock, sst->data);
> 	}
> 
> 	static inline void
> 	__scoped_seqlock_next(struct ss_tmp *sst, enum ss_state target)
> 	{
> 		switch (sst->state) {
> 		case ss_lock:
> 		case ss_lock_irqsave:
> 			sst->state |= ss_done;
> 			return;
> 
> 		case ss_lockless:
> 			if (!read_seqretry(sst->lock, sst->data)) {
> 				sst->state = ss_done;
> 				return;
> 			}
> 			break;
> 		}
> 
> 		switch (target) {
> 		case ss_lock:
> 			spin_lock(&sst->lock.lock);
> 			sst->state = ss_lock;
> 			return;
> 
> 		case ss_lock_irqsave:
> 			spin_lock_irqsave(&sst->lock.lock, sst->data);
> 			sst->state = ss_lock_irqsave;
> 			return;
> 
> 		case ss_lockless:
> 			sst->data = read_seqbegin(sst->lock);
> 			return;
> 		}
> 	}
> 
> 	#define __scoped_seqlock_read(_seqlock, _target, _s)			\
> 		for (struct ss_tmp _s __cleanup(__scoped_seqlock_cleanup) =				\
> 		     { .state = ss_lockless, .data = read_seqbegin(_seqlock), .lock = __seqlock };	\
> 		     !(_s.state & ss_done);								\
> 		     __scoped_seqlock_next(&_s, _target))
> 
> 
> (I removed __scoped_seqlock_invalid_target/__scoped_seqlock_bug to lessen the code).
> 
> Not sure this makes sense. Plus I didn't even try to compile this code and I have
> no idea how this change can affect the code generation. But let me ask anyway...

So GCC is clever enough to see through this scheme, but Clang gets
confused and generates worse code. Specifically it emits the whole
__scoped_seqlock_cleanup() sequence, testing both bits and both unlock
options.

Where previously it would only have to discover which field was written
to and could delete all code for the unwritten field, it now has to
track the state and discover ss_lock|ss_done is not possible while
ss_lock_irqsave|ss_done is.

So while that additional pointer might seem wasteful, it actually makes
the state tracking easier and allows the compiler to more easily throw
away stuff.


  reply	other threads:[~2025-10-13  9:03 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-28 16:19 [PATCH 0/1] documentation: seqlock: fix the wrong documentation of read_seqbegin_or_lock/need_seqretry Oleg Nesterov
2025-09-28 16:20 ` [PATCH 1/1] " Oleg Nesterov
2025-10-01 18:21   ` Waiman Long
2025-10-01 19:06     ` Oleg Nesterov
2025-10-01 19:24       ` Waiman Long
2025-10-01 19:34         ` Waiman Long
2025-10-02 11:01     ` Oleg Nesterov
2025-10-21 10:35   ` [tip: locking/core] " tip-bot2 for Oleg Nesterov
2025-09-28 16:20 ` [RFC 2/1] seqlock: make the read_seqbegin_or_lock() API more simple and less error-prone ? Oleg Nesterov
2025-09-29  0:41   ` [????] " Li,Rongqing
2025-09-29  6:47     ` Oleg Nesterov
2025-10-01 13:02   ` Peter Zijlstra
2025-10-01 13:13     ` Oleg Nesterov
2025-10-01 13:46       ` Oleg Nesterov
2025-10-02 12:58       ` Oleg Nesterov
2025-09-30 22:09 ` David Howells
2025-10-01 11:51   ` Oleg Nesterov
2025-10-05 14:47 ` [PATCH 0/5] seqlock: introduce SEQLOCK_READ_SECTION() Oleg Nesterov
2025-10-05 14:49 ` Oleg Nesterov
2025-10-05 14:50   ` [PATCH 1/5] " Oleg Nesterov
2025-10-05 15:34     ` Linus Torvalds
2025-10-05 16:07       ` Oleg Nesterov
2025-10-05 16:35         ` Linus Torvalds
2025-10-05 14:50   ` [PATCH 2/5] seqlock: change thread_group_cputime() to use SEQLOCK_READ_SECTION() Oleg Nesterov
2025-10-05 14:50   ` [PATCH 3/5] seqlock: change do_task_stat() " Oleg Nesterov
2025-10-05 14:50   ` [PATCH 4/5] seqlock: change do_io_accounting() " Oleg Nesterov
2025-10-05 14:50   ` [PATCH 5/5] seqlock: change __dentry_path() to use __SEQLOCK_READ_SECTION() Oleg Nesterov
2025-10-05 15:48     ` Linus Torvalds
2025-10-05 15:30   ` [PATCH 0/5] seqlock: introduce SEQLOCK_READ_SECTION() Al Viro
2025-10-05 17:40     ` Oleg Nesterov
2025-10-07 14:20 ` [PATCH 0/4] seqlock: introduce scoped_seqlock_read() and scoped_seqlock_read_irqsave() Oleg Nesterov
2025-10-07 14:21   ` [PATCH 1/4] " Oleg Nesterov
2025-10-07 16:35     ` Waiman Long
2025-10-07 17:18       ` Oleg Nesterov
2025-10-07 17:21         ` Waiman Long
2025-10-07 14:21   ` [PATCH 2/4] seqlock: change thread_group_cputime() to use scoped_seqlock_read_irqsave() Oleg Nesterov
2025-10-07 14:21   ` [PATCH 3/4] seqlock: change do_task_stat() " Oleg Nesterov
2025-10-07 14:21   ` [PATCH 4/4] seqlock: change do_io_accounting() " Oleg Nesterov
2025-10-07 15:38   ` [PATCH 0/4] seqlock: introduce scoped_seqlock_read() and scoped_seqlock_read_irqsave() Linus Torvalds
2025-10-07 16:34     ` Oleg Nesterov
2025-10-08 12:30 ` [PATCH v2 " Oleg Nesterov
2025-10-08 12:30   ` [PATCH v2 1/4] " Oleg Nesterov
2025-10-08 12:55     ` Peter Zijlstra
2025-10-08 12:59       ` Oleg Nesterov
2025-10-08 13:54         ` Peter Zijlstra
2025-10-08 16:05     ` Linus Torvalds
2025-10-08 16:55       ` Oleg Nesterov
2025-10-09  5:31       ` Linus Torvalds
2025-10-09  7:04         ` Linus Torvalds
2025-10-09 14:37           ` Oleg Nesterov
2025-10-09 16:18             ` Linus Torvalds
2025-10-09 19:50             ` Peter Zijlstra
2025-10-09 20:11               ` Peter Zijlstra
2025-10-09 20:24                 ` Linus Torvalds
2025-10-09 22:12                   ` Peter Zijlstra
2025-10-09 22:55                     ` Linus Torvalds
2025-10-10  8:03                       ` Peter Zijlstra
2025-10-10 12:32                         ` Oleg Nesterov
2025-10-10 13:14                           ` Oleg Nesterov
2025-10-13  9:03                             ` Peter Zijlstra [this message]
2025-10-13 11:50                               ` Oleg Nesterov
2025-10-10 15:30                           ` Linus Torvalds
2025-10-09 23:20                     ` Peter Zijlstra
2025-10-09 23:26                       ` Linus Torvalds
2025-10-21 10:35                 ` [tip: locking/core] seqlock: Introduce scoped_seqlock_read() tip-bot2 for Peter Zijlstra
2025-10-08 12:30   ` [PATCH v2 2/4] seqlock: change thread_group_cputime() to use scoped_seqlock_read_irqsave() Oleg Nesterov
2025-10-21 10:35     ` [tip: locking/core] seqlock: Change thread_group_cputime() to use scoped_seqlock_read() tip-bot2 for Oleg Nesterov
2025-10-08 12:30   ` [PATCH v2 3/4] seqlock: change do_task_stat() to use scoped_seqlock_read_irqsave() Oleg Nesterov
2025-10-21 10:35     ` [tip: locking/core] seqlock: Change do_task_stat() to use scoped_seqlock_read() tip-bot2 for Oleg Nesterov
2025-10-08 12:31   ` [PATCH v2 4/4] seqlock: change do_io_accounting() to use scoped_seqlock_read_irqsave() Oleg Nesterov
2025-10-21 10:35     ` [tip: locking/core] seqlock: Change do_io_accounting() to use scoped_seqlock_read() tip-bot2 for Oleg Nesterov
2025-10-08 12:56   ` [PATCH v2 0/4] seqlock: introduce scoped_seqlock_read() and scoped_seqlock_read_irqsave() Peter Zijlstra
2025-10-08 13:13     ` Oleg Nesterov
2025-10-08 13:55       ` Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251013090313.GI4067720@noisy.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=boqun.feng@gmail.com \
    --cc=dhowells@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lirongqing@baidu.com \
    --cc=longman@redhat.com \
    --cc=mingo@redhat.com \
    --cc=oleg@redhat.com \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome