Thread (77 messages) 77 messages, 3 authors, 2021-10-14

Re: [PATCH 03/62] mm: Split slab into its own type

From: Matthew Wilcox <willy@infradead.org>
Date: 2021-10-05 18:49:08

On Tue, Oct 05, 2021 at 06:10:24PM +0200, David Hildenbrand wrote:
My 2 cents just from reading the first 3 mails:

I'm not particularly happy about the "/* Reuses the bits in struct page */"
part of thingy here, essentially really having to pay attention what
whenever we change something in "struct page" to not mess up all the other
special types we have. And I wasn't particularly happy scanning patch #1 and
#2 for the same reason. Can't we avoid that?
I've tried to mitigate that with the compile-time assertions.  They're
actually a bit stronger than what we have now.
What I can see is that we want (and must right now for generic
infrastructure) keep some members of the the struct page" (e.g., flags,
_refcount) at the very same place, because generic infrastructure relies on
them.

Maybe that has already been discussed somewhere deep down in folio mail
threads, but I would have expected that we keep struct-page generic inside
struct-page and only have inside "struct slab" what's special for "struct
slab".

I would have thought that we want something like this (but absolutely not
this):

struct page_header {
	unsigned long flags;
}

struct page_footer {
	atomic_t _refcount;
#ifdef CONFIG_MEMCG
	unsigned long memcg_data;
#endif
}

struct page {
	struct page_header header;
	uint8_t reserved[$DO_THE_MATH]
	struct page_footer footer;
};
The problem with this definition is the number of places which refer
to page->flags and must now be churned to page->header.flags.
_refcount is rather better encapsulated, and I'm not entirely sure
how much we'd have to do for memcg_data.  Maybe that was what you meant
by "this but absolutely not this"?  I don't quite understand what that
was supposed to mean.
struct slab {
	...
};

struct slab_page {
	struct page_header header;
	struct slab;
	struct page_footer footer;
};

Instead of providing helpers for struct slab_page, simply cast to struct
page and replace the structs in struct slab_page by simple placeholders with
the same size.

That would to me look like a nice cleanup itself, ignoring all the other
parallel discussions that are going on. But I imagine the problem is more
involved, and a simple header/footer might not be sufficient.
Yes, exactly, the problems are more involved.  The location/contents of
page->mapping are special, the contents of bit zero of the second word
are special (determines compound_head or not) and slub particularly
relies on the 128-bit alignment of the { freelist, counters } pair.

The ultimate destination (and I think Kent/Johannes/I all agree
on this) is to dynamically allocate struct slab.  At _that_ point,
we can actually drop _refcount from struct slab and even change how
struct slab is defined based on CONFIG_SLUB / CONFIG_SLOB / CONFIG_SLAB.
I think we'll still need ->flags to be the first element of struct slab,
but bit 0 of the second word stops being special, we won't need to care
about where page->mapping aliases, and the 128-bit alignment becomes
solely the concern of the slub allocator instead of affecting everyone
who uses struct page.

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help