drm/amd/display: Refactor clk_mgr functions
[linux-2.6-microblaze.git] / mm / balloon_compaction.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * mm/balloon_compaction.c
4  *
5  * Common interface for making balloon pages movable by compaction.
6  *
7  * Copyright (C) 2012, Red Hat, Inc.  Rafael Aquini <aquini@redhat.com>
8  */
9 #include <linux/mm.h>
10 #include <linux/slab.h>
11 #include <linux/export.h>
12 #include <linux/balloon_compaction.h>
13
14 /*
15  * balloon_page_alloc - allocates a new page for insertion into the balloon
16  *                        page list.
17  *
18  * Driver must call it to properly allocate a new enlisted balloon page.
19  * Driver must call balloon_page_enqueue before definitively removing it from
20  * the guest system.  This function returns the page address for the recently
21  * allocated page or NULL in the case we fail to allocate a new page this turn.
22  */
23 struct page *balloon_page_alloc(void)
24 {
25         struct page *page = alloc_page(balloon_mapping_gfp_mask() |
26                                        __GFP_NOMEMALLOC | __GFP_NORETRY);
27         return page;
28 }
29 EXPORT_SYMBOL_GPL(balloon_page_alloc);
30
31 /*
32  * balloon_page_enqueue - allocates a new page and inserts it into the balloon
33  *                        page list.
34  * @b_dev_info: balloon device descriptor where we will insert a new page to
35  * @page: new page to enqueue - allocated using balloon_page_alloc.
36  *
37  * Driver must call it to properly enqueue a new allocated balloon page
38  * before definitively removing it from the guest system.
39  * This function returns the page address for the recently enqueued page or
40  * NULL in the case we fail to allocate a new page this turn.
41  */
42 void balloon_page_enqueue(struct balloon_dev_info *b_dev_info,
43                           struct page *page)
44 {
45         unsigned long flags;
46
47         /*
48          * Block others from accessing the 'page' when we get around to
49          * establishing additional references. We should be the only one
50          * holding a reference to the 'page' at this point.
51          */
52         BUG_ON(!trylock_page(page));
53         spin_lock_irqsave(&b_dev_info->pages_lock, flags);
54         balloon_page_insert(b_dev_info, page);
55         __count_vm_event(BALLOON_INFLATE);
56         spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
57         unlock_page(page);
58 }
59 EXPORT_SYMBOL_GPL(balloon_page_enqueue);
60
61 /*
62  * balloon_page_dequeue - removes a page from balloon's page list and returns
63  *                        the its address to allow the driver release the page.
64  * @b_dev_info: balloon device decriptor where we will grab a page from.
65  *
66  * Driver must call it to properly de-allocate a previous enlisted balloon page
67  * before definetively releasing it back to the guest system.
68  * This function returns the page address for the recently dequeued page or
69  * NULL in the case we find balloon's page list temporarily empty due to
70  * compaction isolated pages.
71  */
72 struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info)
73 {
74         struct page *page, *tmp;
75         unsigned long flags;
76         bool dequeued_page;
77
78         dequeued_page = false;
79         spin_lock_irqsave(&b_dev_info->pages_lock, flags);
80         list_for_each_entry_safe(page, tmp, &b_dev_info->pages, lru) {
81                 /*
82                  * Block others from accessing the 'page' while we get around
83                  * establishing additional references and preparing the 'page'
84                  * to be released by the balloon driver.
85                  */
86                 if (trylock_page(page)) {
87 #ifdef CONFIG_BALLOON_COMPACTION
88                         if (PageIsolated(page)) {
89                                 /* raced with isolation */
90                                 unlock_page(page);
91                                 continue;
92                         }
93 #endif
94                         balloon_page_delete(page);
95                         __count_vm_event(BALLOON_DEFLATE);
96                         unlock_page(page);
97                         dequeued_page = true;
98                         break;
99                 }
100         }
101         spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
102
103         if (!dequeued_page) {
104                 /*
105                  * If we are unable to dequeue a balloon page because the page
106                  * list is empty and there is no isolated pages, then something
107                  * went out of track and some balloon pages are lost.
108                  * BUG() here, otherwise the balloon driver may get stuck into
109                  * an infinite loop while attempting to release all its pages.
110                  */
111                 spin_lock_irqsave(&b_dev_info->pages_lock, flags);
112                 if (unlikely(list_empty(&b_dev_info->pages) &&
113                              !b_dev_info->isolated_pages))
114                         BUG();
115                 spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
116                 page = NULL;
117         }
118         return page;
119 }
120 EXPORT_SYMBOL_GPL(balloon_page_dequeue);
121
122 #ifdef CONFIG_BALLOON_COMPACTION
123
124 bool balloon_page_isolate(struct page *page, isolate_mode_t mode)
125
126 {
127         struct balloon_dev_info *b_dev_info = balloon_page_device(page);
128         unsigned long flags;
129
130         spin_lock_irqsave(&b_dev_info->pages_lock, flags);
131         list_del(&page->lru);
132         b_dev_info->isolated_pages++;
133         spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
134
135         return true;
136 }
137
138 void balloon_page_putback(struct page *page)
139 {
140         struct balloon_dev_info *b_dev_info = balloon_page_device(page);
141         unsigned long flags;
142
143         spin_lock_irqsave(&b_dev_info->pages_lock, flags);
144         list_add(&page->lru, &b_dev_info->pages);
145         b_dev_info->isolated_pages--;
146         spin_unlock_irqrestore(&b_dev_info->pages_lock, flags);
147 }
148
149
150 /* move_to_new_page() counterpart for a ballooned page */
151 int balloon_page_migrate(struct address_space *mapping,
152                 struct page *newpage, struct page *page,
153                 enum migrate_mode mode)
154 {
155         struct balloon_dev_info *balloon = balloon_page_device(page);
156
157         /*
158          * We can not easily support the no copy case here so ignore it as it
159          * is unlikely to be use with ballon pages. See include/linux/hmm.h for
160          * user of the MIGRATE_SYNC_NO_COPY mode.
161          */
162         if (mode == MIGRATE_SYNC_NO_COPY)
163                 return -EINVAL;
164
165         VM_BUG_ON_PAGE(!PageLocked(page), page);
166         VM_BUG_ON_PAGE(!PageLocked(newpage), newpage);
167
168         return balloon->migratepage(balloon, newpage, page, mode);
169 }
170
171 const struct address_space_operations balloon_aops = {
172         .migratepage = balloon_page_migrate,
173         .isolate_page = balloon_page_isolate,
174         .putback_page = balloon_page_putback,
175 };
176 EXPORT_SYMBOL_GPL(balloon_aops);
177
178 #endif /* CONFIG_BALLOON_COMPACTION */