On 07/10/2018 07:53 PM, Matthew Wilcox wrote: > diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h > index 21e1b6a9f113..8a4698b368de 100644 > --- a/include/linux/mm_types.h > +++ b/include/linux/mm_types.h > @@ -153,6 +153,11 @@ struct page { > spinlock_t ptl; > #endif > }; > + struct { /* VMalloc pages */ > + struct vm_struct *vm_area; > + unsigned long vm_offset; > + unsigned long _vm_id; /* MAPPING_VMalloc */ > + }; > struct { /* ZONE_DEVICE pages */ > /** @pgmap: Points to the hosting device page map. */ > struct dev_pagemap *pgmap; > diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h > index 901943e4754b..588b8dd28a85 100644 > --- a/include/linux/page-flags.h > +++ b/include/linux/page-flags.h > @@ -699,6 +699,32 @@ PAGE_TYPE_OPS(Kmemcg, kmemcg) > */ > PAGE_TYPE_OPS(Table, table) > > +/* > + * vmalloc pages may be mapped to userspace, so we need some other way > + * to distinguish them from other kinds of pages. Use page->mapping for > + * this purpose. Values below 0x1000 cannot be real pointers. Setting > + * the bottom bit makes page_mapping() return NULL, which is what we want. > + */ > +#define MAPPING_VMalloc (void *)0x441 So this makes the vmalloc pages look like anon pages, while previously they were !PageAnon. I'm pretty sure this is not going to work. > + > +#define PAGE_MAPPING_OPS(name) \ > +static __always_inline int Page##name(struct page *page) \ > +{ \ > + return page->mapping == MAPPING_##name; \ > +} \ > +static __always_inline void __SetPage##name(struct page *page) \ > +{ \ > + VM_BUG_ON_PAGE(page->mapping != NULL, page); \ > + page->mapping = MAPPING_##name; \ > +} \ > +static __always_inline void __ClearPage##name(struct page *page) \ > +{ \ > + VM_BUG_ON_PAGE(page->mapping != MAPPING_##name, page); \ > + page->mapping = NULL; \ > +} > + > +PAGE_MAPPING_OPS(VMalloc) > +