10
10
#include <linux/export.h>
11
11
#include <linux/balloon_compaction.h>
12
12
13
+ static 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
+ */
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
+ 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
+ }
55
+ EXPORT_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
+ */
74
+ size_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
+ }
110
+ EXPORT_SYMBOL_GPL (balloon_page_list_dequeue );
111
+
13
112
/*
14
113
* balloon_page_alloc - allocates a new page for insertion into the balloon
15
114
* page list.
@@ -43,17 +142,9 @@ void balloon_page_enqueue(struct balloon_dev_info *b_dev_info,
43
142
{
44
143
unsigned long flags ;
45
144
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
145
spin_lock_irqsave (& b_dev_info -> pages_lock , flags );
53
- balloon_page_insert (b_dev_info , page );
54
- __count_vm_event (BALLOON_INFLATE );
146
+ balloon_page_enqueue_one (b_dev_info , page );
55
147
spin_unlock_irqrestore (& b_dev_info -> pages_lock , flags );
56
- unlock_page (page );
57
148
}
58
149
EXPORT_SYMBOL_GPL (balloon_page_enqueue );
59
150
@@ -70,36 +161,13 @@ EXPORT_SYMBOL_GPL(balloon_page_enqueue);
70
161
*/
71
162
struct page * balloon_page_dequeue (struct balloon_dev_info * b_dev_info )
72
163
{
73
- struct page * page , * tmp ;
74
164
unsigned long flags ;
75
- bool dequeued_page ;
165
+ LIST_HEAD (pages );
166
+ int n_pages ;
76
167
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 );
168
+ n_pages = balloon_page_list_dequeue (b_dev_info , & pages , 1 );
101
169
102
- if (! dequeued_page ) {
170
+ if (n_pages != 1 ) {
103
171
/*
104
172
* If we are unable to dequeue a balloon page because the page
105
173
* list is empty and there is no isolated pages, then something
@@ -112,9 +180,9 @@ struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info)
112
180
!b_dev_info -> isolated_pages ))
113
181
BUG ();
114
182
spin_unlock_irqrestore (& b_dev_info -> pages_lock , flags );
115
- page = NULL ;
183
+ return NULL ;
116
184
}
117
- return page ;
185
+ return list_first_entry ( & pages , struct page , lru ) ;
118
186
}
119
187
EXPORT_SYMBOL_GPL (balloon_page_dequeue );
120
188
0 commit comments