Skip to content

Commit 468e0ff

Browse files
anadavgregkh
authored andcommitted
vmw_balloon: Fix offline page marking with compaction
The compaction code already marks pages as offline when it enqueues pages in the ballooned page list, and removes the mapping when the pages are removed from the list. VMware balloon also updates the flags, instead of letting the balloon-compaction logic handle it, which causes the assertion VM_BUG_ON_PAGE(!PageOffline(page)) to fire, when __ClearPageOffline is called the second time. This causes the following crash. [ 487.104520] kernel BUG at include/linux/page-flags.h:749! [ 487.106364] invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC PTI [ 487.107681] CPU: 7 PID: 1106 Comm: kworker/7:3 Not tainted 5.3.0-rc5balloon #227 [ 487.109196] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 12/12/2018 [ 487.111452] Workqueue: events_freezable vmballoon_work [vmw_balloon] [ 487.112779] RIP: 0010:vmballoon_release_page_list+0xaa/0x100 [vmw_balloon] [ 487.114200] Code: fe 48 c1 e7 06 4c 01 c7 8b 47 30 41 89 c1 41 81 e1 00 01 00 f0 41 81 f9 00 00 00 f0 74 d3 48 c7 c6 08 a1 a1 c0 e8 06 0d e7 ea <0f> 0b 44 89 f6 4c 89 c7 e8 49 9c e9 ea 49 8d 75 08 49 8b 45 08 4d [ 487.118033] RSP: 0018:ffffb82f012bbc98 EFLAGS: 00010246 [ 487.119135] RAX: 0000000000000037 RBX: 0000000000000001 RCX: 0000000000000006 [ 487.120601] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff9a85b6bd7620 [ 487.122071] RBP: ffffb82f012bbcc0 R08: 0000000000000001 R09: 0000000000000000 [ 487.123536] R10: 0000000000000000 R11: 0000000000000000 R12: ffffb82f012bbd00 [ 487.125002] R13: ffffe97f4598d9c0 R14: 0000000000000000 R15: ffffb82f012bbd34 [ 487.126463] FS: 0000000000000000(0000) GS:ffff9a85b6bc0000(0000) knlGS:0000000000000000 [ 487.128110] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 487.129316] CR2: 00007ffe6e413ea0 CR3: 0000000230b18001 CR4: 00000000003606e0 [ 487.130812] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 487.132283] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 487.133749] Call Trace: [ 487.134333] vmballoon_deflate+0x22c/0x390 [vmw_balloon] [ 487.135468] vmballoon_work+0x6e7/0x913 [vmw_balloon] [ 487.136711] ? process_one_work+0x21a/0x5e0 [ 487.138581] process_one_work+0x298/0x5e0 [ 487.139926] ? vmballoon_migratepage+0x310/0x310 [vmw_balloon] [ 487.141610] ? process_one_work+0x298/0x5e0 [ 487.143053] worker_thread+0x41/0x400 [ 487.144389] kthread+0x12b/0x150 [ 487.145582] ? process_one_work+0x5e0/0x5e0 [ 487.146937] ? kthread_create_on_node+0x60/0x60 [ 487.148637] ret_from_fork+0x3a/0x50 Fix it by updating the PageOffline indication only when a 2MB page is enqueued and dequeued. The 4KB pages will be handled correctly by the balloon compaction logic. Fixes: 83a8afa ("vmw_balloon: Compaction support") Cc: David Hildenbrand <[email protected]> Reported-by: Thomas Hellstrom <[email protected]> Signed-off-by: Nadav Amit <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ba03a9b commit 468e0ff

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

drivers/misc/vmw_balloon.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,6 @@ static int vmballoon_alloc_page_list(struct vmballoon *b,
691691
}
692692

693693
if (page) {
694-
vmballoon_mark_page_offline(page, ctl->page_size);
695694
/* Success. Add the page to the list and continue. */
696695
list_add(&page->lru, &ctl->pages);
697696
continue;
@@ -930,7 +929,6 @@ static void vmballoon_release_page_list(struct list_head *page_list,
930929

931930
list_for_each_entry_safe(page, tmp, page_list, lru) {
932931
list_del(&page->lru);
933-
vmballoon_mark_page_online(page, page_size);
934932
__free_pages(page, vmballoon_page_order(page_size));
935933
}
936934

@@ -1005,6 +1003,7 @@ static void vmballoon_enqueue_page_list(struct vmballoon *b,
10051003
enum vmballoon_page_size_type page_size)
10061004
{
10071005
unsigned long flags;
1006+
struct page *page;
10081007

10091008
if (page_size == VMW_BALLOON_4K_PAGE) {
10101009
balloon_page_list_enqueue(&b->b_dev_info, pages);
@@ -1014,6 +1013,11 @@ static void vmballoon_enqueue_page_list(struct vmballoon *b,
10141013
* for the balloon compaction mechanism.
10151014
*/
10161015
spin_lock_irqsave(&b->b_dev_info.pages_lock, flags);
1016+
1017+
list_for_each_entry(page, pages, lru) {
1018+
vmballoon_mark_page_offline(page, VMW_BALLOON_2M_PAGE);
1019+
}
1020+
10171021
list_splice_init(pages, &b->huge_pages);
10181022
__count_vm_events(BALLOON_INFLATE, *n_pages *
10191023
vmballoon_page_in_frames(VMW_BALLOON_2M_PAGE));
@@ -1056,6 +1060,8 @@ static void vmballoon_dequeue_page_list(struct vmballoon *b,
10561060
/* 2MB pages */
10571061
spin_lock_irqsave(&b->b_dev_info.pages_lock, flags);
10581062
list_for_each_entry_safe(page, tmp, &b->huge_pages, lru) {
1063+
vmballoon_mark_page_online(page, VMW_BALLOON_2M_PAGE);
1064+
10591065
list_move(&page->lru, pages);
10601066
if (++i == n_req_pages)
10611067
break;

0 commit comments

Comments
 (0)