On 04/18/2018 08:49 PM, Matthew Wilcox wrote: > From: Matthew Wilcox <mawilcox@xxxxxxxxxxxxx> > > By combining these three one-word unions into one three-word union, > we make it easier for users to add their own multi-word fields to struct > page, as well as making it obvious that SLUB needs to keep its double-word > alignment for its freelist & counters. > > No field moves position; verified with pahole. > > Signed-off-by: Matthew Wilcox <mawilcox@xxxxxxxxxxxxx> > --- > include/linux/mm_types.h | 65 ++++++++++++++++++++-------------------- > 1 file changed, 32 insertions(+), 33 deletions(-) > > diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h > index 04d9dc442029..39521b8385c1 100644 > --- a/include/linux/mm_types.h > +++ b/include/linux/mm_types.h > @@ -70,45 +70,44 @@ struct hmm; > #endif > > struct page { > - /* First double word block */ > unsigned long flags; /* Atomic flags, some possibly > * updated asynchronously */ > - union { > - /* See page-flags.h for the definition of PAGE_MAPPING_FLAGS */ > - struct address_space *mapping; > - > - struct kmem_cache *slab_cache; /* SL[AU]B: Pointer to slab */ > + union { /* This union is three words (12/24 bytes) in size */ > + struct { /* Page cache and anonymous pages */ > + /* See page-flags.h for PAGE_MAPPING_FLAGS */ > + struct address_space *mapping; > + pgoff_t index; /* Our offset within mapping. */ > + /** > + * @private: Mapping-private opaque data. > + * Usually used for buffer_heads if PagePrivate. > + * Used for swp_entry_t if PageSwapCache. > + * Indicates order in the buddy system if PageBuddy. > + */ > + unsigned long private; > + }; > + struct { /* slab and slob */ > + struct kmem_cache *slab_cache; > + void *freelist; /* first free object */ > + void *s_mem; /* first object */ > + }; > + struct { /* slub also uses some of the slab fields */ > + struct kmem_cache *slub_cache; > + /* Double-word boundary */ > + void *slub_freelist; Is slub going to switch to use those? Or maybe this is an overkill and we could merge the two sl*b structs and just have an union for s_mem and the 3 counters? > + unsigned inuse:16; > + unsigned objects:15; > + unsigned frozen:1; > + };