Skip to content

Commit 337c017

Browse files
Wanpeng Lirkrcmar
authored andcommitted
KVM: async_pf: make rcu irq exit if not triggered from idle task
WARNING: CPU: 5 PID: 1242 at kernel/rcu/tree_plugin.h:323 rcu_note_context_switch+0x207/0x6b0 CPU: 5 PID: 1242 Comm: unity-settings- Not tainted 4.13.0-rc2+ #1 RIP: 0010:rcu_note_context_switch+0x207/0x6b0 Call Trace: __schedule+0xda/0xba0 ? kvm_async_pf_task_wait+0x1b2/0x270 schedule+0x40/0x90 kvm_async_pf_task_wait+0x1cc/0x270 ? prepare_to_swait+0x22/0x70 do_async_page_fault+0x77/0xb0 ? do_async_page_fault+0x77/0xb0 async_page_fault+0x28/0x30 RIP: 0010:__d_lookup_rcu+0x90/0x1e0 I encounter this when trying to stress the async page fault in L1 guest w/ L2 guests running. Commit 9b132fb (Add rcu user eqs exception hooks for async page fault) adds rcu_irq_enter/exit() to kvm_async_pf_task_wait() to exit cpu idle eqs when needed, to protect the code that needs use rcu. However, we need to call the pair even if the function calls schedule(), as seen from the above backtrace. This patch fixes it by informing the RCU subsystem exit/enter the irq towards/away from idle for both n.halted and !n.halted. Cc: Paolo Bonzini <[email protected]> Cc: Radim Krčmář <[email protected]> Cc: Paul E. McKenney <[email protected]> Cc: [email protected] Signed-off-by: Wanpeng Li <[email protected]> Reviewed-by: Paolo Bonzini <[email protected]> Signed-off-by: Radim Krčmář <[email protected]>
1 parent b96fb43 commit 337c017

File tree

1 file changed

+4
-2
lines changed

1 file changed

+4
-2
lines changed

arch/x86/kernel/kvm.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ void kvm_async_pf_task_wait(u32 token)
151151
if (hlist_unhashed(&n.link))
152152
break;
153153

154+
rcu_irq_exit();
155+
154156
if (!n.halted) {
155157
local_irq_enable();
156158
schedule();
@@ -159,11 +161,11 @@ void kvm_async_pf_task_wait(u32 token)
159161
/*
160162
* We cannot reschedule. So halt.
161163
*/
162-
rcu_irq_exit();
163164
native_safe_halt();
164165
local_irq_disable();
165-
rcu_irq_enter();
166166
}
167+
168+
rcu_irq_enter();
167169
}
168170
if (!n.halted)
169171
finish_swait(&n.wq, &wait);

0 commit comments

Comments
 (0)