]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - mm/balloon_compaction.c
mm/balloon_compaction: List interfaces
[mirror_ubuntu-focal-kernel.git] / mm / balloon_compaction.c
CommitLineData
18468d93
RA
1/*
2 * mm/balloon_compaction.c
3 *
4 * Common interface for making balloon pages movable by compaction.
5 *
6 * Copyright (C) 2012, Red Hat, Inc. Rafael Aquini <aquini@redhat.com>
7 */
8#include <linux/mm.h>
9#include <linux/slab.h>
10#include <linux/export.h>
11#include <linux/balloon_compaction.h>
12
418a3ab1
NA
13static void balloon_page_enqueue_one(struct balloon_dev_info *b_dev_info,
14 struct page *page)
15{
16 /*
17 * Block others from accessing the 'page' when we get around to
18 * establishing additional references. We should be the only one
19 * holding a reference to the 'page' at this point. If we are not, then
20 * memory corruption is possible and we should stop execution.
21 */
22 BUG_ON(!trylock_page(page));
23 list_del(&page->lru);
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 it to properly enqueue a balloon pages before definitively
36 * removing it from the guest system.
37 *
38 * Return: number of pages that were enqueued.
39 */
40size_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 balloon_page_enqueue_one(b_dev_info, page);
50 n_pages++;
51 }
52 spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
53 return n_pages;
54}
55EXPORT_SYMBOL_GPL(balloon_page_list_enqueue);
56
57/**
58 * balloon_page_list_dequeue() - removes pages from balloon's page list and
59 * returns a list of the pages.
60 * @b_dev_info: balloon device decriptor where we will grab a page from.
61 * @pages: pointer to the list of pages that would be returned to the caller.
62 * @n_req_pages: number of requested pages.
63 *
64 * Driver must call this function to properly de-allocate a previous enlisted
65 * balloon pages before definetively releasing it back to the guest system.
66 * This function tries to remove @n_req_pages from the ballooned pages and
67 * return them to the caller in the @pages list.
68 *
69 * Note that this function may fail to dequeue some pages temporarily empty due
70 * to compaction isolated pages.
71 *
72 * Return: number of pages that were added to the @pages list.
73 */
74size_t balloon_page_list_dequeue(struct balloon_dev_info *b_dev_info,
75 struct list_head *pages, size_t n_req_pages)
76{
77 struct page *page, *tmp;
78 unsigned long flags;
79 size_t n_pages = 0;
80
81 spin_lock_irqsave(&b_dev_info->pages_lock, flags);
82 list_for_each_entry_safe(page, tmp, &b_dev_info->pages, lru) {
83 if (n_pages == n_req_pages)
84 break;
85
86 /*
87 * Block others from accessing the 'page' while we get around to
88 * establishing additional references and preparing the 'page'
89 * to be released by the balloon driver.
90 */
91 if (!trylock_page(page))
92 continue;
93
94 if (IS_ENABLED(CONFIG_BALLOON_COMPACTION) &&
95 PageIsolated(page)) {
96 /* raced with isolation */
97 unlock_page(page);
98 continue;
99 }
100 balloon_page_delete(page);
101 __count_vm_event(BALLOON_DEFLATE);
102 list_add(&page->lru, pages);
103 unlock_page(page);
104 n_pages++;
105 }
106 spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
107
108 return n_pages;
109}
110EXPORT_SYMBOL_GPL(balloon_page_list_dequeue);
111
c7cdff0e
MT
112/*
113 * balloon_page_alloc - allocates a new page for insertion into the balloon
114 * page list.
115 *
116 * Driver must call it to properly allocate a new enlisted balloon page.
117 * Driver must call balloon_page_enqueue before definitively removing it from
118 * the guest system. This function returns the page address for the recently
119 * allocated page or NULL in the case we fail to allocate a new page this turn.
120 */
121struct page *balloon_page_alloc(void)
122{
123 struct page *page = alloc_page(balloon_mapping_gfp_mask() |
124 __GFP_NOMEMALLOC | __GFP_NORETRY);
125 return page;
126}
127EXPORT_SYMBOL_GPL(balloon_page_alloc);
128
18468d93
RA
129/*
130 * balloon_page_enqueue - allocates a new page and inserts it into the balloon
131 * page list.
bdb428c8 132 * @b_dev_info: balloon device descriptor where we will insert a new page to
c7cdff0e 133 * @page: new page to enqueue - allocated using balloon_page_alloc.
18468d93 134 *
c7cdff0e 135 * Driver must call it to properly enqueue a new allocated balloon page
bdb428c8 136 * before definitively removing it from the guest system.
18468d93
RA
137 * This function returns the page address for the recently enqueued page or
138 * NULL in the case we fail to allocate a new page this turn.
139 */
c7cdff0e
MT
140void balloon_page_enqueue(struct balloon_dev_info *b_dev_info,
141 struct page *page)
18468d93
RA
142{
143 unsigned long flags;
18468d93 144
18468d93 145 spin_lock_irqsave(&b_dev_info->pages_lock, flags);
418a3ab1 146 balloon_page_enqueue_one(b_dev_info, page);
18468d93 147 spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
18468d93
RA
148}
149EXPORT_SYMBOL_GPL(balloon_page_enqueue);
150
151/*
152 * balloon_page_dequeue - removes a page from balloon's page list and returns
153 * the its address to allow the driver release the page.
154 * @b_dev_info: balloon device decriptor where we will grab a page from.
155 *
156 * Driver must call it to properly de-allocate a previous enlisted balloon page
157 * before definetively releasing it back to the guest system.
158 * This function returns the page address for the recently dequeued page or
159 * NULL in the case we find balloon's page list temporarily empty due to
160 * compaction isolated pages.
161 */
162struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info)
163{
18468d93 164 unsigned long flags;
418a3ab1
NA
165 LIST_HEAD(pages);
166 int n_pages;
18468d93 167
418a3ab1 168 n_pages = balloon_page_list_dequeue(b_dev_info, &pages, 1);
18468d93 169
418a3ab1 170 if (n_pages != 1) {
18468d93
RA
171 /*
172 * If we are unable to dequeue a balloon page because the page
173 * list is empty and there is no isolated pages, then something
174 * went out of track and some balloon pages are lost.
175 * BUG() here, otherwise the balloon driver may get stuck into
176 * an infinite loop while attempting to release all its pages.
177 */
178 spin_lock_irqsave(&b_dev_info->pages_lock, flags);
179 if (unlikely(list_empty(&b_dev_info->pages) &&
180 !b_dev_info->isolated_pages))
181 BUG();
182 spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
418a3ab1 183 return NULL;
18468d93 184 }
418a3ab1 185 return list_first_entry(&pages, struct page, lru);
18468d93
RA
186}
187EXPORT_SYMBOL_GPL(balloon_page_dequeue);
188
189#ifdef CONFIG_BALLOON_COMPACTION
18468d93 190
b1123ea6
MK
191bool balloon_page_isolate(struct page *page, isolate_mode_t mode)
192
18468d93 193{
9d1ba805 194 struct balloon_dev_info *b_dev_info = balloon_page_device(page);
18468d93 195 unsigned long flags;
d6d86c0a 196
18468d93
RA
197 spin_lock_irqsave(&b_dev_info->pages_lock, flags);
198 list_del(&page->lru);
199 b_dev_info->isolated_pages++;
200 spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
b1123ea6
MK
201
202 return true;
18468d93
RA
203}
204
b1123ea6 205void balloon_page_putback(struct page *page)
18468d93 206{
9d1ba805 207 struct balloon_dev_info *b_dev_info = balloon_page_device(page);
18468d93 208 unsigned long flags;
d6d86c0a 209
18468d93
RA
210 spin_lock_irqsave(&b_dev_info->pages_lock, flags);
211 list_add(&page->lru, &b_dev_info->pages);
212 b_dev_info->isolated_pages--;
213 spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
214}
215
18468d93
RA
216
217/* move_to_new_page() counterpart for a ballooned page */
b1123ea6
MK
218int balloon_page_migrate(struct address_space *mapping,
219 struct page *newpage, struct page *page,
220 enum migrate_mode mode)
18468d93 221{
9d1ba805 222 struct balloon_dev_info *balloon = balloon_page_device(page);
18468d93 223
2916ecc0
JG
224 /*
225 * We can not easily support the no copy case here so ignore it as it
226 * is unlikely to be use with ballon pages. See include/linux/hmm.h for
227 * user of the MIGRATE_SYNC_NO_COPY mode.
228 */
229 if (mode == MIGRATE_SYNC_NO_COPY)
230 return -EINVAL;
231
7db7671f
HD
232 VM_BUG_ON_PAGE(!PageLocked(page), page);
233 VM_BUG_ON_PAGE(!PageLocked(newpage), newpage);
18468d93 234
b1123ea6
MK
235 return balloon->migratepage(balloon, newpage, page, mode);
236}
18468d93 237
b1123ea6
MK
238const struct address_space_operations balloon_aops = {
239 .migratepage = balloon_page_migrate,
240 .isolate_page = balloon_page_isolate,
241 .putback_page = balloon_page_putback,
242};
243EXPORT_SYMBOL_GPL(balloon_aops);
18468d93 244
18468d93 245#endif /* CONFIG_BALLOON_COMPACTION */