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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 05.10.21 20:48, Matthew Wilcox wrote:
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.

Sorry for the late reply.

Okay, that's at least something :)


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.

Exactly what you mentioned above (changing all callers) is what I didn't want :)

I was thinking of a way to have these "fixed fields" be defined only once, and ideally, perform any access to these fields via the "struct page" instead of via the "struct slab".

Like, when wanting to set a page flag with a slab, access them

((struct page *)slab)->flags

instead of using slab->flags. Essentially not duplicating these fields and accessing them via the "refined" page types, but only putting a "reserved" placeholder in. That would mean that we wouldn't need patch #1 and #2, because we wouldn't be passing around pgflags (using whatever fancy type we will decide on), all such accesses would continue going via the "struct page" -- because that's where these common fields actually reside in right now at places we cannot simply change -- because common infrastructure (PFN walkers, ...) heavily relyies on the flags, the refcount and even the mapcount (page types) being set accordingly.


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'm also sold on the idea of simplifying "struct page" (even when not shrinking it!) by moving out these "struct slab" parts that dictate the "struct page" layout heavily.

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.

Yes, that sounds good to me.

--
Thanks,

David / dhildenb






[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux