1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Macros for manipulating and testing flags related to a |
4 | * pageblock_nr_pages number of pages. |
5 | * |
6 | * Copyright (C) IBM Corporation, 2006 |
7 | * |
8 | * Original author, Mel Gorman |
9 | * Major cleanups and reduction of bit operations, Andy Whitcroft |
10 | */ |
11 | #ifndef PAGEBLOCK_FLAGS_H |
12 | #define PAGEBLOCK_FLAGS_H |
13 | |
14 | #include <linux/types.h> |
15 | |
16 | #define PB_migratetype_bits 3 |
17 | /* Bit indices that affect a whole block of pages */ |
18 | enum pageblock_bits { |
19 | PB_migrate, |
20 | PB_migrate_end = PB_migrate + PB_migratetype_bits - 1, |
21 | /* 3 bits required for migrate types */ |
22 | PB_migrate_skip,/* If set the block is skipped by compaction */ |
23 | |
24 | /* |
25 | * Assume the bits will always align on a word. If this assumption |
26 | * changes then get/set pageblock needs updating. |
27 | */ |
28 | NR_PAGEBLOCK_BITS |
29 | }; |
30 | |
31 | #ifdef CONFIG_HUGETLB_PAGE |
32 | |
33 | #ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE |
34 | |
35 | /* Huge page sizes are variable */ |
36 | extern unsigned int pageblock_order; |
37 | |
38 | #else /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */ |
39 | |
40 | /* |
41 | * Huge pages are a constant size, but don't exceed the maximum allocation |
42 | * granularity. |
43 | */ |
44 | #define pageblock_order min_t(unsigned int, HUGETLB_PAGE_ORDER, MAX_ORDER) |
45 | |
46 | #endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */ |
47 | |
48 | #else /* CONFIG_HUGETLB_PAGE */ |
49 | |
50 | /* If huge pages are not used, group by MAX_ORDER_NR_PAGES */ |
51 | #define pageblock_order MAX_ORDER |
52 | |
53 | #endif /* CONFIG_HUGETLB_PAGE */ |
54 | |
55 | #define pageblock_nr_pages (1UL << pageblock_order) |
56 | #define pageblock_align(pfn) ALIGN((pfn), pageblock_nr_pages) |
57 | #define pageblock_aligned(pfn) IS_ALIGNED((pfn), pageblock_nr_pages) |
58 | #define pageblock_start_pfn(pfn) ALIGN_DOWN((pfn), pageblock_nr_pages) |
59 | #define pageblock_end_pfn(pfn) ALIGN((pfn) + 1, pageblock_nr_pages) |
60 | |
61 | /* Forward declaration */ |
62 | struct page; |
63 | |
64 | unsigned long get_pfnblock_flags_mask(const struct page *page, |
65 | unsigned long pfn, |
66 | unsigned long mask); |
67 | |
68 | void set_pfnblock_flags_mask(struct page *page, |
69 | unsigned long flags, |
70 | unsigned long pfn, |
71 | unsigned long mask); |
72 | |
73 | /* Declarations for getting and setting flags. See mm/page_alloc.c */ |
74 | #ifdef CONFIG_COMPACTION |
75 | #define get_pageblock_skip(page) \ |
76 | get_pfnblock_flags_mask(page, page_to_pfn(page), \ |
77 | (1 << (PB_migrate_skip))) |
78 | #define clear_pageblock_skip(page) \ |
79 | set_pfnblock_flags_mask(page, 0, page_to_pfn(page), \ |
80 | (1 << PB_migrate_skip)) |
81 | #define set_pageblock_skip(page) \ |
82 | set_pfnblock_flags_mask(page, (1 << PB_migrate_skip), \ |
83 | page_to_pfn(page), \ |
84 | (1 << PB_migrate_skip)) |
85 | #else |
86 | static inline bool get_pageblock_skip(struct page *page) |
87 | { |
88 | return false; |
89 | } |
90 | static inline void clear_pageblock_skip(struct page *page) |
91 | { |
92 | } |
93 | static inline void set_pageblock_skip(struct page *page) |
94 | { |
95 | } |
96 | #endif /* CONFIG_COMPACTION */ |
97 | |
98 | #endif /* PAGEBLOCK_FLAGS_H */ |
99 | |