All of lore.kernel.org
 help / color / mirror / Atom feed
* + mm-introduce-encoded-page-pointers-with-embedded-extra-bits.patch added to mm-unstable branch
@ 2022-11-10  0:09 Andrew Morton
  2022-11-10  1:14 ` Linus Torvalds
  0 siblings, 1 reply; 2+ messages in thread
From: Andrew Morton @ 2022-11-10  0:09 UTC (permalink / raw)
  To: mm-commits, will, svens, peterz, npiggin, nadav.amit, hughd, hca,
	hannes, gor, gerald.schaefer, borntraeger, aneesh.kumar,
	agordeev, torvalds, akpm


The patch titled
     Subject: mm: introduce 'encoded' page pointers with embedded extra bits
has been added to the -mm mm-unstable branch.  Its filename is
     mm-introduce-encoded-page-pointers-with-embedded-extra-bits.patch

This patch will shortly appear at
     https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-introduce-encoded-page-pointers-with-embedded-extra-bits.patch

This patch will later appear in the mm-unstable branch at
    git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days

------------------------------------------------------
From: Linus Torvalds <torvalds@linux-foundation.org>
Subject: mm: introduce 'encoded' page pointers with embedded extra bits
Date: Wed, 9 Nov 2022 12:30:48 -0800

We already have this notion in parts of the MM code (see the mlock code
with the LRU_PAGE and NEW_PAGE bits), but I'm going to introduce a new
case, and I refuse to do the same thing we've done before where we just
put bits in the raw pointer and say it's still a normal pointer.

So this introduces a 'struct encoded_page' pointer that cannot be used for
anything else than to encode a real page pointer and a couple of extra
bits in the low bits.  That way the compiler can trivially track the state
of the pointer and you just explicitly encode and decode the extra bits.

Note that this makes the alignment of 'struct page' explicit even for the
case where CONFIG_HAVE_ALIGNED_STRUCT_PAGE is not set.  That is entirely
redundant in almost all cases, since the page structure already contains
several word-sized entries.

However, on m68k, the alignment of even 32-bit data is just 16 bits, and
as such in theory the alignment of 'struct page' could be too.  So let's
just make it very very explicit that the alignment needs to be at least 32
bits, giving us a guarantee of two unused low bits in the pointer.

Now, in practice, our page struct array is aligned much more than that
anyway, even on m68k, and our existing code in mm/mlock.c obviously
already depended on that.  But since the whole point of this change is to
be careful about the type system when hiding extra bits in the pointer,
let's also be explicit about the assumptions we make.

NOTE!  This is being very careful in another way too: it has a build-time
assertion that the 'flags' added to the page pointer actually fit in the
two bits.  That means that this helper must be inlined, and can only be
used in contexts where the compiler can statically determine that the
value fits in the available bits.

Link: https://lore.kernel.org/all/Y2tKixpO4RO6DgW5@tuxmaker.boeblingen.de.ibm.com/
Link: https://lkml.kernel.org/r/20221109203051.1835763-1-torvalds@linux-foundation.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Hugh Dickins <hughd@google.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Cc: Heiko Carstens <hca@linux.ibm.com> [s390]
Cc: Nadav Amit <nadav.amit@gmail.com>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 include/linux/mm_types.h |   34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

--- a/include/linux/mm_types.h~mm-introduce-encoded-page-pointers-with-embedded-extra-bits
+++ a/include/linux/mm_types.h
@@ -68,7 +68,7 @@ struct mem_cgroup;
 #ifdef CONFIG_HAVE_ALIGNED_STRUCT_PAGE
 #define _struct_page_alignment	__aligned(2 * sizeof(unsigned long))
 #else
-#define _struct_page_alignment
+#define _struct_page_alignment	__aligned(sizeof(unsigned long))
 #endif
 
 struct page {
@@ -252,6 +252,38 @@ struct page {
 } _struct_page_alignment;
 
 /**
+ * struct encoded_page - a nonexistent type marking this pointer
+ *
+ * An 'encoded_page' pointer is a pointer to a regular 'struct page', but
+ * with the low bits of the pointer indicating extra context-dependent
+ * information. Not super-common, but happens in mmu_gather and mlock
+ * handling, and this acts as a type system check on that use.
+ *
+ * We only really have two guaranteed bits in general, although you could
+ * play with 'struct page' alignment (see CONFIG_HAVE_ALIGNED_STRUCT_PAGE)
+ * for more.
+ *
+ * Use the supplied helper functions to endcode/decode the pointer and bits.
+ */
+struct encoded_page;
+#define ENCODE_PAGE_BITS 3ul
+static __always_inline struct encoded_page *encode_page(struct page *page, unsigned long flags)
+{
+	BUILD_BUG_ON(flags > ENCODE_PAGE_BITS);
+	return (struct encoded_page *)(flags | (unsigned long)page);
+}
+
+static inline unsigned long encoded_page_flags(struct encoded_page *page)
+{
+	return ENCODE_PAGE_BITS & (unsigned long)page;
+}
+
+static inline struct page *encoded_page_ptr(struct encoded_page *page)
+{
+	return (struct page *)(~ENCODE_PAGE_BITS & (unsigned long)page);
+}
+
+/**
  * struct folio - Represents a contiguous set of bytes.
  * @flags: Identical to the page flags.
  * @lru: Least Recently Used list; tracks how recently this folio was used.
_

Patches currently in -mm which might be from torvalds@linux-foundation.org are

mm-introduce-encoded-page-pointers-with-embedded-extra-bits.patch
mm-teach-release_pages-to-take-an-array-of-encoded-page-pointers-too.patch
mm-mmu_gather-prepare-to-gather-encoded-page-pointers-with-flags.patch
mm-delay-page_remove_rmap-until-after-the-tlb-has-been-flushed.patch


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: + mm-introduce-encoded-page-pointers-with-embedded-extra-bits.patch added to mm-unstable branch
  2022-11-10  0:09 + mm-introduce-encoded-page-pointers-with-embedded-extra-bits.patch added to mm-unstable branch Andrew Morton
@ 2022-11-10  1:14 ` Linus Torvalds
  0 siblings, 0 replies; 2+ messages in thread
From: Linus Torvalds @ 2022-11-10  1:14 UTC (permalink / raw)
  To: Andrew Morton
  Cc: mm-commits, will, svens, peterz, npiggin, nadav.amit, hughd, hca,
	hannes, gor, gerald.schaefer, borntraeger, aneesh.kumar,
	agordeev

On Wed, Nov 9, 2022 at 4:09 PM Andrew Morton <akpm@linux-foundation.org> wrote:
>
> +       BUILD_BUG_ON(flags > ENCODE_PAGE_BITS);

Note that if this causes any problems with some compiler version in
linux-next, just remove that line. It definitely is just a "nice to
have, let's try it" kind of thing.

If that happens, I'd be interested to know which compiler and config
causes it to blow up, though. Just out of morbid curiosity.

                 Linus

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-11-10  1:15 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-10  0:09 + mm-introduce-encoded-page-pointers-with-embedded-extra-bits.patch added to mm-unstable branch Andrew Morton
2022-11-10  1:14 ` Linus Torvalds

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.