public inbox for linux-mm@kvack.org
 help / color / mirror / Atom feed
From: Dmitry Ilvokhin <d@ilvokhin.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: dan.j.williams@intel.com, Vlastimil Babka <vbabka@kernel.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	David Hildenbrand <david@kernel.org>,
	Lorenzo Stoakes <ljs@kernel.org>,
	"Liam R. Howlett" <Liam.Howlett@oracle.com>,
	Mike Rapoport <rppt@kernel.org>,
	Suren Baghdasaryan <surenb@google.com>,
	Michal Hocko <mhocko@suse.com>,
	Brendan Jackman <jackmanb@google.com>,
	Johannes Weiner <hannes@cmpxchg.org>, Zi Yan <ziy@nvidia.com>,
	linux-mm@kvack.org, linux-kernel@vger.kernel.org,
	kernel-team@meta.com
Subject: Re: [PATCH 1/8] mm: use zone lock guard in reserve_highatomic_pageblock()
Date: Tue, 28 Apr 2026 13:41:31 +0000	[thread overview]
Message-ID: <afC5C6fylF4AsITV@shell.ilvokhin.com> (raw)
In-Reply-To: <20260428114721.GV3102624@noisy.programming.kicks-ass.net>

On Tue, Apr 28, 2026 at 01:47:21PM +0200, Peter Zijlstra wrote:
> On Tue, Apr 28, 2026 at 10:58:41AM +0000, Dmitry Ilvokhin wrote:
> 
> > I re-tested my original patchset after rebasing and can still reproduce
> > the regression (though smaller). It appears to depend on compiler
> > inlining decisions: in some cases the compiler is able to deduplicate
> > the cleanup path across multiple return sites, while in others it is
> > not.
> 
> I'm confused, all this has __always_inline on. And the compilers should
> be able to track the assignment of the variable and eliminate the test
> themselves if value-tracking excludes NULL.

I'd expect that too, but seems it is not the case. I was looking at this
patchset rebased on top of the mm-stable build with GCC 16 with
defconfig.

    https://lore.kernel.org/all/cover.1775654118.git.d@ilvokhin.com/


$ ./scripts/bloat-o-meter /tmp/bloat-gcc-16/page_alloc.o.before /tmp/bloat-gcc-16/page_alloc.o.after | grep -v UNIQUE
add/remove: 24/24 grow/shrink: 2/1 up/down: 232/-193 (39)
Function                                     old     new   delta
free_pcppages_bulk                           577     601     +24
free_pages_exact                             153     169     +16
unreserve_highatomic_pageblock               608     607      -1
Total: Before=42366, After=42405, chg +0.09%

I looked at free_pcppages_bulk() generated code diff and got the
following differences (only relevant parts).

[...]

- mov 0x20(%rsp),%r12
- mov 0x28(%rsp),%r15
+ mov 0x20(%rsp),%r13
+ mov 0x28(%rsp),%r12
+ test %r13,%r13                       ; guard NULL branch
+ je 2ba6 <free_pcppages_bulk+0x246>

[...]

  add $0x30,%rsp
- mov %r15,%rsi
- mov %r12,%rdi
+ mov %r12,%rsi
+ mov %r13,%rdi
  pop %rbx
  pop %rbp
  pop %r12
  pop %r13
  pop %r14
  pop %r15
- jmp 2b8b <free_pcppages_bulk+0x22b>
+ jmp 2b90 <free_pcppages_bulk+0x230>
  mov $0x800,%eax
  jmp 2af3 <free_pcppages_bulk+0x193>
  mov 0x1c(%rsp),%edx
  mov %ebp,%r14d
  jmp 29ae <free_pcppages_bulk+0x4e>
- data16 cs nopw 0x0(%rax,%rax,1)
+ add $0x30,%rsp                      ; epilogue is duplicated once again.
+ pop %rbx
+ pop %rbp
+ pop %r12
+ pop %r13
+ pop %r14
+ pop %r15
+ jmp 2bb9 <free_pcppages_bulk+0x259>

So, NULL check is not eliminated and in addition compiler couldn't merge
two almost identical epilogues here. I suspect the function calls
between construction and destruction (e.g., __free_one_page()) prevent
the compiler from proving .lock is non-NULL across the scope, but this
is just speculation, I am not a compiler expert.

> 
> > Given that, I think we can go further than just removing
> > __GUARD_IS_ERR(). It should be possible to eliminate this branch
> > entirely and simplify the cleanup flow.
> > 
> >     https://lore.kernel.org/all/20260427165037.205337-1-d@ilvokhin.com/
> > 
> > Reposting here to increase visibility, as several people involved in
> > this code have participated in this thread already.
> > 
> > Any feedback would be appreciated.
> 
> This would require very careful audit of all the current users, it's had
> this behaviour from the start.

My thinking process was the following: the constructor doesn't check for
NULL either, so if something is passing NULL to begin with it should
already crash in constructor not even reaching the destructor.

The only case when we'd need the NULL check in the destructor is if
something changes .lock to NULL after construction, but before
destruction.

This can't happen:

- The guard infrastructure provides no API to clear a guard after
  construction (no_free_ptr()/retain_ptr() only work with __free, not
  guards).

- guard() creates an anonymous variable via __UNIQUE_ID, so user code                                                   
  can't reference it to modify .lock directly.

- CLASS_INIT() is the only macro that allows bypassing the constructor,                                                 
  but it is only used for fd_prepare in include/linux/file.h, not for
  any lock guards.

- Conditional (_try) variants have their own destructor via
  EXTEND_CLASS_COND() that checks __GUARD_IS_ERR() and returns early
  before reaching the base destructor. They are not affected by this
  change.


  reply	other threads:[~2026-04-28 13:41 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-06 16:05 [PATCH 0/8] mm: introduce zone lock guards Dmitry Ilvokhin
2026-03-06 16:05 ` [PATCH 1/8] mm: use zone lock guard in reserve_highatomic_pageblock() Dmitry Ilvokhin
2026-03-06 17:53   ` Andrew Morton
2026-03-06 18:00     ` Steven Rostedt
2026-03-06 18:24       ` Vlastimil Babka
2026-03-06 18:33         ` Andrew Morton
2026-03-06 18:46           ` Steven Rostedt
2026-03-07 13:16         ` Peter Zijlstra
2026-03-07 14:09           ` Dmitry Ilvokhin
2026-03-09 16:45             ` Peter Zijlstra
2026-03-10 12:57               ` Dmitry Ilvokhin
2026-03-12 23:40               ` Dan Williams
2026-03-13  8:36                 ` Peter Zijlstra
2026-04-28 10:58               ` Dmitry Ilvokhin
2026-04-28 11:47                 ` Peter Zijlstra
2026-04-28 13:41                   ` Dmitry Ilvokhin [this message]
2026-03-26 18:04     ` Dmitry Ilvokhin
2026-03-26 18:51       ` Andrew Morton
2026-03-06 16:05 ` [PATCH 2/8] mm: use zone lock guard in unset_migratetype_isolate() Dmitry Ilvokhin
2026-03-06 16:05 ` [PATCH 3/8] mm: use zone lock guard in unreserve_highatomic_pageblock() Dmitry Ilvokhin
2026-03-06 16:10   ` Steven Rostedt
2026-03-06 16:05 ` [PATCH 4/8] mm: use zone lock guard in set_migratetype_isolate() Dmitry Ilvokhin
2026-03-06 16:05 ` [PATCH 5/8] mm: use zone lock guard in take_page_off_buddy() Dmitry Ilvokhin
2026-03-06 16:05 ` [PATCH 6/8] mm: use zone lock guard in put_page_back_buddy() Dmitry Ilvokhin
2026-03-06 16:05 ` [PATCH 7/8] mm: use zone lock guard in free_pcppages_bulk() Dmitry Ilvokhin
2026-03-06 16:05 ` [PATCH 8/8] mm: use zone lock guard in __offline_isolated_pages() Dmitry Ilvokhin
2026-03-06 16:15 ` [PATCH 0/8] mm: introduce zone lock guards Steven Rostedt

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=afC5C6fylF4AsITV@shell.ilvokhin.com \
    --to=d@ilvokhin.com \
    --cc=Liam.Howlett@oracle.com \
    --cc=akpm@linux-foundation.org \
    --cc=dan.j.williams@intel.com \
    --cc=david@kernel.org \
    --cc=hannes@cmpxchg.org \
    --cc=jackmanb@google.com \
    --cc=kernel-team@meta.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=mhocko@suse.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=rppt@kernel.org \
    --cc=surenb@google.com \
    --cc=vbabka@kernel.org \
    --cc=ziy@nvidia.com \
    /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