.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * mm/balloon_compaction.c |
---|
3 | 4 | * |
---|
.. | .. |
---|
10 | 11 | #include <linux/export.h> |
---|
11 | 12 | #include <linux/balloon_compaction.h> |
---|
12 | 13 | |
---|
| 14 | +static void balloon_page_enqueue_one(struct balloon_dev_info *b_dev_info, |
---|
| 15 | + struct page *page) |
---|
| 16 | +{ |
---|
| 17 | + /* |
---|
| 18 | + * Block others from accessing the 'page' when we get around to |
---|
| 19 | + * establishing additional references. We should be the only one |
---|
| 20 | + * holding a reference to the 'page' at this point. If we are not, then |
---|
| 21 | + * memory corruption is possible and we should stop execution. |
---|
| 22 | + */ |
---|
| 23 | + BUG_ON(!trylock_page(page)); |
---|
| 24 | + balloon_page_insert(b_dev_info, page); |
---|
| 25 | + unlock_page(page); |
---|
| 26 | + __count_vm_event(BALLOON_INFLATE); |
---|
| 27 | +} |
---|
| 28 | + |
---|
| 29 | +/** |
---|
| 30 | + * balloon_page_list_enqueue() - inserts a list of pages into the balloon page |
---|
| 31 | + * list. |
---|
| 32 | + * @b_dev_info: balloon device descriptor where we will insert a new page to |
---|
| 33 | + * @pages: pages to enqueue - allocated using balloon_page_alloc. |
---|
| 34 | + * |
---|
| 35 | + * Driver must call this function to properly enqueue balloon pages before |
---|
| 36 | + * definitively removing them from the guest system. |
---|
| 37 | + * |
---|
| 38 | + * Return: number of pages that were enqueued. |
---|
| 39 | + */ |
---|
| 40 | +size_t balloon_page_list_enqueue(struct balloon_dev_info *b_dev_info, |
---|
| 41 | + struct list_head *pages) |
---|
| 42 | +{ |
---|
| 43 | + struct page *page, *tmp; |
---|
| 44 | + unsigned long flags; |
---|
| 45 | + size_t n_pages = 0; |
---|
| 46 | + |
---|
| 47 | + spin_lock_irqsave(&b_dev_info->pages_lock, flags); |
---|
| 48 | + list_for_each_entry_safe(page, tmp, pages, lru) { |
---|
| 49 | + list_del(&page->lru); |
---|
| 50 | + balloon_page_enqueue_one(b_dev_info, page); |
---|
| 51 | + n_pages++; |
---|
| 52 | + } |
---|
| 53 | + spin_unlock_irqrestore(&b_dev_info->pages_lock, flags); |
---|
| 54 | + return n_pages; |
---|
| 55 | +} |
---|
| 56 | +EXPORT_SYMBOL_GPL(balloon_page_list_enqueue); |
---|
| 57 | + |
---|
| 58 | +/** |
---|
| 59 | + * balloon_page_list_dequeue() - removes pages from balloon's page list and |
---|
| 60 | + * returns a list of the pages. |
---|
| 61 | + * @b_dev_info: balloon device decriptor where we will grab a page from. |
---|
| 62 | + * @pages: pointer to the list of pages that would be returned to the caller. |
---|
| 63 | + * @n_req_pages: number of requested pages. |
---|
| 64 | + * |
---|
| 65 | + * Driver must call this function to properly de-allocate a previous enlisted |
---|
| 66 | + * balloon pages before definitively releasing it back to the guest system. |
---|
| 67 | + * This function tries to remove @n_req_pages from the ballooned pages and |
---|
| 68 | + * return them to the caller in the @pages list. |
---|
| 69 | + * |
---|
| 70 | + * Note that this function may fail to dequeue some pages even if the balloon |
---|
| 71 | + * isn't empty - since the page list can be temporarily empty due to compaction |
---|
| 72 | + * of isolated pages. |
---|
| 73 | + * |
---|
| 74 | + * Return: number of pages that were added to the @pages list. |
---|
| 75 | + */ |
---|
| 76 | +size_t balloon_page_list_dequeue(struct balloon_dev_info *b_dev_info, |
---|
| 77 | + struct list_head *pages, size_t n_req_pages) |
---|
| 78 | +{ |
---|
| 79 | + struct page *page, *tmp; |
---|
| 80 | + unsigned long flags; |
---|
| 81 | + size_t n_pages = 0; |
---|
| 82 | + |
---|
| 83 | + spin_lock_irqsave(&b_dev_info->pages_lock, flags); |
---|
| 84 | + list_for_each_entry_safe(page, tmp, &b_dev_info->pages, lru) { |
---|
| 85 | + if (n_pages == n_req_pages) |
---|
| 86 | + break; |
---|
| 87 | + |
---|
| 88 | + /* |
---|
| 89 | + * Block others from accessing the 'page' while we get around to |
---|
| 90 | + * establishing additional references and preparing the 'page' |
---|
| 91 | + * to be released by the balloon driver. |
---|
| 92 | + */ |
---|
| 93 | + if (!trylock_page(page)) |
---|
| 94 | + continue; |
---|
| 95 | + |
---|
| 96 | + if (IS_ENABLED(CONFIG_BALLOON_COMPACTION) && |
---|
| 97 | + PageIsolated(page)) { |
---|
| 98 | + /* raced with isolation */ |
---|
| 99 | + unlock_page(page); |
---|
| 100 | + continue; |
---|
| 101 | + } |
---|
| 102 | + balloon_page_delete(page); |
---|
| 103 | + __count_vm_event(BALLOON_DEFLATE); |
---|
| 104 | + list_add(&page->lru, pages); |
---|
| 105 | + unlock_page(page); |
---|
| 106 | + n_pages++; |
---|
| 107 | + } |
---|
| 108 | + spin_unlock_irqrestore(&b_dev_info->pages_lock, flags); |
---|
| 109 | + |
---|
| 110 | + return n_pages; |
---|
| 111 | +} |
---|
| 112 | +EXPORT_SYMBOL_GPL(balloon_page_list_dequeue); |
---|
| 113 | + |
---|
13 | 114 | /* |
---|
14 | 115 | * balloon_page_alloc - allocates a new page for insertion into the balloon |
---|
15 | | - * page list. |
---|
| 116 | + * page list. |
---|
16 | 117 | * |
---|
17 | | - * Driver must call it to properly allocate a new enlisted balloon page. |
---|
18 | | - * Driver must call balloon_page_enqueue before definitively removing it from |
---|
19 | | - * the guest system. This function returns the page address for the recently |
---|
20 | | - * allocated page or NULL in the case we fail to allocate a new page this turn. |
---|
| 118 | + * Driver must call this function to properly allocate a new balloon page. |
---|
| 119 | + * Driver must call balloon_page_enqueue before definitively removing the page |
---|
| 120 | + * from the guest system. |
---|
| 121 | + * |
---|
| 122 | + * Return: struct page for the allocated page or NULL on allocation failure. |
---|
21 | 123 | */ |
---|
22 | 124 | struct page *balloon_page_alloc(void) |
---|
23 | 125 | { |
---|
24 | 126 | struct page *page = alloc_page(balloon_mapping_gfp_mask() | |
---|
25 | | - __GFP_NOMEMALLOC | __GFP_NORETRY); |
---|
| 127 | + __GFP_NOMEMALLOC | __GFP_NORETRY | |
---|
| 128 | + __GFP_NOWARN); |
---|
26 | 129 | return page; |
---|
27 | 130 | } |
---|
28 | 131 | EXPORT_SYMBOL_GPL(balloon_page_alloc); |
---|
29 | 132 | |
---|
30 | 133 | /* |
---|
31 | | - * balloon_page_enqueue - allocates a new page and inserts it into the balloon |
---|
32 | | - * page list. |
---|
33 | | - * @b_dev_info: balloon device descriptor where we will insert a new page to |
---|
| 134 | + * balloon_page_enqueue - inserts a new page into the balloon page list. |
---|
| 135 | + * |
---|
| 136 | + * @b_dev_info: balloon device descriptor where we will insert a new page |
---|
34 | 137 | * @page: new page to enqueue - allocated using balloon_page_alloc. |
---|
35 | 138 | * |
---|
36 | | - * Driver must call it to properly enqueue a new allocated balloon page |
---|
37 | | - * before definitively removing it from the guest system. |
---|
38 | | - * This function returns the page address for the recently enqueued page or |
---|
39 | | - * NULL in the case we fail to allocate a new page this turn. |
---|
| 139 | + * Drivers must call this function to properly enqueue a new allocated balloon |
---|
| 140 | + * page before definitively removing the page from the guest system. |
---|
| 141 | + * |
---|
| 142 | + * Drivers must not call balloon_page_enqueue on pages that have been pushed to |
---|
| 143 | + * a list with balloon_page_push before removing them with balloon_page_pop. To |
---|
| 144 | + * enqueue a list of pages, use balloon_page_list_enqueue instead. |
---|
40 | 145 | */ |
---|
41 | 146 | void balloon_page_enqueue(struct balloon_dev_info *b_dev_info, |
---|
42 | 147 | struct page *page) |
---|
43 | 148 | { |
---|
44 | 149 | unsigned long flags; |
---|
45 | 150 | |
---|
46 | | - /* |
---|
47 | | - * Block others from accessing the 'page' when we get around to |
---|
48 | | - * establishing additional references. We should be the only one |
---|
49 | | - * holding a reference to the 'page' at this point. |
---|
50 | | - */ |
---|
51 | | - BUG_ON(!trylock_page(page)); |
---|
52 | 151 | spin_lock_irqsave(&b_dev_info->pages_lock, flags); |
---|
53 | | - balloon_page_insert(b_dev_info, page); |
---|
54 | | - __count_vm_event(BALLOON_INFLATE); |
---|
| 152 | + balloon_page_enqueue_one(b_dev_info, page); |
---|
55 | 153 | spin_unlock_irqrestore(&b_dev_info->pages_lock, flags); |
---|
56 | | - unlock_page(page); |
---|
57 | 154 | } |
---|
58 | 155 | EXPORT_SYMBOL_GPL(balloon_page_enqueue); |
---|
59 | 156 | |
---|
60 | 157 | /* |
---|
61 | 158 | * balloon_page_dequeue - removes a page from balloon's page list and returns |
---|
62 | | - * the its address to allow the driver release the page. |
---|
| 159 | + * its address to allow the driver to release the page. |
---|
63 | 160 | * @b_dev_info: balloon device decriptor where we will grab a page from. |
---|
64 | 161 | * |
---|
65 | | - * Driver must call it to properly de-allocate a previous enlisted balloon page |
---|
66 | | - * before definetively releasing it back to the guest system. |
---|
67 | | - * This function returns the page address for the recently dequeued page or |
---|
68 | | - * NULL in the case we find balloon's page list temporarily empty due to |
---|
69 | | - * compaction isolated pages. |
---|
| 162 | + * Driver must call this function to properly dequeue a previously enqueued page |
---|
| 163 | + * before definitively releasing it back to the guest system. |
---|
| 164 | + * |
---|
| 165 | + * Caller must perform its own accounting to ensure that this |
---|
| 166 | + * function is called only if some pages are actually enqueued. |
---|
| 167 | + * |
---|
| 168 | + * Note that this function may fail to dequeue some pages even if there are |
---|
| 169 | + * some enqueued pages - since the page list can be temporarily empty due to |
---|
| 170 | + * the compaction of isolated pages. |
---|
| 171 | + * |
---|
| 172 | + * TODO: remove the caller accounting requirements, and allow caller to wait |
---|
| 173 | + * until all pages can be dequeued. |
---|
| 174 | + * |
---|
| 175 | + * Return: struct page for the dequeued page, or NULL if no page was dequeued. |
---|
70 | 176 | */ |
---|
71 | 177 | struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info) |
---|
72 | 178 | { |
---|
73 | | - struct page *page, *tmp; |
---|
74 | 179 | unsigned long flags; |
---|
75 | | - bool dequeued_page; |
---|
| 180 | + LIST_HEAD(pages); |
---|
| 181 | + int n_pages; |
---|
76 | 182 | |
---|
77 | | - dequeued_page = false; |
---|
78 | | - spin_lock_irqsave(&b_dev_info->pages_lock, flags); |
---|
79 | | - list_for_each_entry_safe(page, tmp, &b_dev_info->pages, lru) { |
---|
80 | | - /* |
---|
81 | | - * Block others from accessing the 'page' while we get around |
---|
82 | | - * establishing additional references and preparing the 'page' |
---|
83 | | - * to be released by the balloon driver. |
---|
84 | | - */ |
---|
85 | | - if (trylock_page(page)) { |
---|
86 | | -#ifdef CONFIG_BALLOON_COMPACTION |
---|
87 | | - if (PageIsolated(page)) { |
---|
88 | | - /* raced with isolation */ |
---|
89 | | - unlock_page(page); |
---|
90 | | - continue; |
---|
91 | | - } |
---|
92 | | -#endif |
---|
93 | | - balloon_page_delete(page); |
---|
94 | | - __count_vm_event(BALLOON_DEFLATE); |
---|
95 | | - unlock_page(page); |
---|
96 | | - dequeued_page = true; |
---|
97 | | - break; |
---|
98 | | - } |
---|
99 | | - } |
---|
100 | | - spin_unlock_irqrestore(&b_dev_info->pages_lock, flags); |
---|
| 183 | + n_pages = balloon_page_list_dequeue(b_dev_info, &pages, 1); |
---|
101 | 184 | |
---|
102 | | - if (!dequeued_page) { |
---|
| 185 | + if (n_pages != 1) { |
---|
103 | 186 | /* |
---|
104 | 187 | * If we are unable to dequeue a balloon page because the page |
---|
105 | | - * list is empty and there is no isolated pages, then something |
---|
| 188 | + * list is empty and there are no isolated pages, then something |
---|
106 | 189 | * went out of track and some balloon pages are lost. |
---|
107 | | - * BUG() here, otherwise the balloon driver may get stuck into |
---|
| 190 | + * BUG() here, otherwise the balloon driver may get stuck in |
---|
108 | 191 | * an infinite loop while attempting to release all its pages. |
---|
109 | 192 | */ |
---|
110 | 193 | spin_lock_irqsave(&b_dev_info->pages_lock, flags); |
---|
.. | .. |
---|
112 | 195 | !b_dev_info->isolated_pages)) |
---|
113 | 196 | BUG(); |
---|
114 | 197 | spin_unlock_irqrestore(&b_dev_info->pages_lock, flags); |
---|
115 | | - page = NULL; |
---|
| 198 | + return NULL; |
---|
116 | 199 | } |
---|
117 | | - return page; |
---|
| 200 | + return list_first_entry(&pages, struct page, lru); |
---|
118 | 201 | } |
---|
119 | 202 | EXPORT_SYMBOL_GPL(balloon_page_dequeue); |
---|
120 | 203 | |
---|
.. | .. |
---|
155 | 238 | |
---|
156 | 239 | /* |
---|
157 | 240 | * We can not easily support the no copy case here so ignore it as it |
---|
158 | | - * is unlikely to be use with ballon pages. See include/linux/hmm.h for |
---|
159 | | - * user of the MIGRATE_SYNC_NO_COPY mode. |
---|
| 241 | + * is unlikely to be used with balloon pages. See include/linux/hmm.h |
---|
| 242 | + * for a user of the MIGRATE_SYNC_NO_COPY mode. |
---|
160 | 243 | */ |
---|
161 | 244 | if (mode == MIGRATE_SYNC_NO_COPY) |
---|
162 | 245 | return -EINVAL; |
---|