On 12/05/2018 11:44 AM, Matthew Wilcox wrote: > On Wed, Dec 05, 2018 at 11:40:51AM -0800, Anthony Yznaga wrote: >> On 12/04/2018 05:25 PM, Matthew Wilcox wrote: >>> On Tue, Dec 04, 2018 at 05:18:32PM -0800, anthony.yznaga@xxxxxxxxxx wrote: >>>> On 12/04/2018 04:48 PM, Matthew Wilcox wrote: >>>>> On Tue, Dec 04, 2018 at 02:45:26PM -0800, Anthony Yznaga wrote: >>>>>> +static inline int page_has_type(struct page *page) >>>>>> +{ >>>>>> + return (PageType(page, 0) && >>>>>> + ((page->page_type & PAGE_TYPE_ALL) != PAGE_TYPE_ALL)); >>>>>> +} >>>>>> + >>>>> I think this is a bit complex, and a bit of a pain to update as we add >>>>> new page types. How about this? >>>>> >>>>> return (int)page_type < -128; >>>>> >>>>> (I'm open to appropriate #defines to make this more obvious that it's ~0x7F) >>>> I thought about having this: >>>> >>>> #define PAGE_TYPE_END 0xffffff80 >>>> >>>> static int inline page_has_type(struct page *page) >>>> { >>>> return page->page_type > PAGE_TYPE_BASE && >>>> page->page_type < PAGE_TYPE_END; >>>> } >>>> >>>> But I opted for the additional complexity to avoid more false-positives from >>>> possibly corrupted values. I'm certainly fine with a simple approach, though. >>> The way I'm thinking about this field is that usually it's _mapcount >>> which is 0xffffffff to represent 0. We allow a certain small amount >>> of underflow and still treat it as a mapcount. We also allow for some >>> amount of overflow. So to be utterly precise, what you had there would >>> have been fine, but for simplicity, I'd rather just do a signed compare >>> against -128. >> The signed compare does not allow for mapcount overflow. Is that acceptable? >> False-positives would be benign for /proc/kpagecount though from a debug >> perspective it could be helpful to see overflowed mapcounts. Some future >> caller would need separate consideration. > Nobody seems terribly interested in mapcount overflows. I got no response > to https://lkml.org/lkml/2018/3/2/991 Okay. Thanks for the background. How about this, then: diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 50ce1bddaf56..39b4494e29f1 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -669,6 +669,7 @@ static inline int TestClearPageDoubleMap(struct page *page) #define PAGE_TYPE_BASE 0xf0000000 /* Reserve 0x0000007f to catch underflows of page_mapcount */ +#define PAGE_MAPCOUNT_RESERVE -128 #define PG_buddy 0x00000080 #define PG_balloon 0x00000100 #define PG_kmemcg 0x00000200 @@ -677,6 +678,11 @@ static inline int TestClearPageDoubleMap(struct page *page) #define PageType(page, flag) \ ((page->page_type & (PAGE_TYPE_BASE | flag)) == PAGE_TYPE_BASE) +static inline int page_has_type(struct page *page) +{ + return (int)page->page_type < PAGE_MAPCOUNT_RESERVE; +} + #define PAGE_TYPE_OPS(uname, lname) \ static __always_inline int Page##uname(struct page *page) \ { \