diff options
author | Wei Wang <wei.w.wang@intel.com> | 2019-07-18 05:27:20 -0400 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2019-07-22 11:19:26 -0400 |
commit | dd422906799f240bfd400a5d376aa43f7b89c38a (patch) | |
tree | 19f2696f81f32f7e46d3e477086eaaa4defd1c2a /mm/balloon_compaction.c | |
parent | 5f9e832c137075045d15cd6899ab0505cfb2ca4b (diff) |
mm/balloon_compaction: avoid duplicate page removal
A #GP is reported in the guest when requesting balloon inflation via
virtio-balloon. The reason is that the virtio-balloon driver has
removed the page from its internal page list (via balloon_page_pop),
but balloon_page_enqueue_one also calls "list_del" to do the removal.
This is necessary when it's used from balloon_page_enqueue_list, but
not from balloon_page_enqueue.
Move list_del to balloon_page_enqueue, and update comments accordingly.
Fixes: 418a3ab1e778 (mm/balloon_compaction: List interfaces)
Signed-off-by: Wei Wang <wei.w.wang@intel.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'mm/balloon_compaction.c')
-rw-r--r-- | mm/balloon_compaction.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/mm/balloon_compaction.c b/mm/balloon_compaction.c index 83a7b614061f..d25664e1857b 100644 --- a/mm/balloon_compaction.c +++ b/mm/balloon_compaction.c | |||
@@ -21,7 +21,6 @@ static void balloon_page_enqueue_one(struct balloon_dev_info *b_dev_info, | |||
21 | * memory corruption is possible and we should stop execution. | 21 | * memory corruption is possible and we should stop execution. |
22 | */ | 22 | */ |
23 | BUG_ON(!trylock_page(page)); | 23 | BUG_ON(!trylock_page(page)); |
24 | list_del(&page->lru); | ||
25 | balloon_page_insert(b_dev_info, page); | 24 | balloon_page_insert(b_dev_info, page); |
26 | unlock_page(page); | 25 | unlock_page(page); |
27 | __count_vm_event(BALLOON_INFLATE); | 26 | __count_vm_event(BALLOON_INFLATE); |
@@ -47,6 +46,7 @@ size_t balloon_page_list_enqueue(struct balloon_dev_info *b_dev_info, | |||
47 | 46 | ||
48 | spin_lock_irqsave(&b_dev_info->pages_lock, flags); | 47 | spin_lock_irqsave(&b_dev_info->pages_lock, flags); |
49 | list_for_each_entry_safe(page, tmp, pages, lru) { | 48 | list_for_each_entry_safe(page, tmp, pages, lru) { |
49 | list_del(&page->lru); | ||
50 | balloon_page_enqueue_one(b_dev_info, page); | 50 | balloon_page_enqueue_one(b_dev_info, page); |
51 | n_pages++; | 51 | n_pages++; |
52 | } | 52 | } |
@@ -128,13 +128,19 @@ struct page *balloon_page_alloc(void) | |||
128 | EXPORT_SYMBOL_GPL(balloon_page_alloc); | 128 | EXPORT_SYMBOL_GPL(balloon_page_alloc); |
129 | 129 | ||
130 | /* | 130 | /* |
131 | * balloon_page_enqueue - allocates a new page and inserts it into the balloon | 131 | * balloon_page_enqueue - inserts a new page into the balloon page list. |
132 | * page list. | 132 | * |
133 | * @b_dev_info: balloon device descriptor where we will insert a new page to | 133 | * @b_dev_info: balloon device descriptor where we will insert a new page to |
134 | * @page: new page to enqueue - allocated using balloon_page_alloc. | 134 | * @page: new page to enqueue - allocated using balloon_page_alloc. |
135 | * | 135 | * |
136 | * Driver must call it to properly enqueue a new allocated balloon page | 136 | * Driver must call it to properly enqueue a new allocated balloon page |
137 | * before definitively removing it from the guest system. | 137 | * before definitively removing it from the guest system. |
138 | * | ||
139 | * Drivers must not call balloon_page_enqueue on pages that have been | ||
140 | * pushed to a list with balloon_page_push before removing them with | ||
141 | * balloon_page_pop. To all pages on a list, use balloon_page_list_enqueue | ||
142 | * instead. | ||
143 | * | ||
138 | * This function returns the page address for the recently enqueued page or | 144 | * This function returns the page address for the recently enqueued page or |
139 | * NULL in the case we fail to allocate a new page this turn. | 145 | * NULL in the case we fail to allocate a new page this turn. |
140 | */ | 146 | */ |