History

tick/nohz: Only check for RCU deferred wakeup on user/guest entry when needed

Checking for and processing RCU-nocb deferred wakeup upon user/guest entry is only relevant when nohz_full runs on the local CPU, otherwise the periodic tick should take care of it. Make sure we don't needlessly pollute these fast-paths as a -3% performance regression on a will-it-scale.per_process_ops has been reported so far.

Frederic Weisbecker committed 5 years ago

Commit f268c371 parent 02da26a4 files · +13 −3Browse files

Unified · Split

4 files
  1. include/linux/entry-kvm.h +2 −1
  2. include/linux/tick.h +7 −0
  3. kernel/entry/common.c +3 −2
  4. kernel/time/tick-sched.c +1 −0
include/linux/entry-kvm.h+2−1
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 #define __LINUX_ENTRYKVM_H
44
55 #include <linux/entry-common.h>
6+#include <linux/tick.h>
67
78 /* Transfer to guest mode work */
89 #ifdef CONFIG_KVM_XFER_TO_GUEST_WORK
@@ -57,7 +58,7 @@ int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu); · 48 unmodified lines
5758 static inline void xfer_to_guest_mode_prepare(void)
5859 {
5960 lockdep_assert_irqs_disabled();
60− rcu_nocb_flush_deferred_wakeup();
61+ tick_nohz_user_enter_prepare();
6162 }
6263
6364 /**
include/linux/tick.h+7−0
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 #include <linux/context_tracking_state.h>
1212 #include <linux/cpumask.h>
1313 #include <linux/sched.h>
14+#include <linux/rcupdate.h>
1415
1516 #ifdef CONFIG_GENERIC_CLOCKEVENTS
1617 extern void __init tick_init(void);
@@ -300,4 +301,10 @@ static inline void tick_nohz_task_switch(void) · 283 unmodified lines
300301 __tick_nohz_task_switch();
301302 }
302303
304+static inline void tick_nohz_user_enter_prepare(void)
305+{
306+ if (tick_nohz_full_cpu(smp_processor_id()))
307+ rcu_nocb_flush_deferred_wakeup();
308+}
309+
303310 #endif
kernel/entry/common.c+3−2
@@ -5,6 +5,7 @@ · 4 unmodified lines
55 #include <linux/highmem.h>
66 #include <linux/livepatch.h>
77 #include <linux/audit.h>
8+#include <linux/tick.h>
89
910 #include "common.h"
1011
@@ -186,7 +187,7 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs, · 175 unmodified lines
186187 local_irq_disable_exit_to_user();
187188
188189 /* Check if any of the above work has queued a deferred wakeup */
189− rcu_nocb_flush_deferred_wakeup();
190+ tick_nohz_user_enter_prepare();
190191
191192 ti_work = READ_ONCE(current_thread_info()->flags);
192193 }
@@ -202,7 +203,7 @@ static void exit_to_user_mode_prepare(struct pt_regs *regs) · 9 unmodified lines
202203 lockdep_assert_irqs_disabled();
203204
204205 /* Flush pending rcuog wakeup before the last need_resched() check */
205− rcu_nocb_flush_deferred_wakeup();
206+ tick_nohz_user_enter_prepare();
206207
207208 if (unlikely(ti_work & EXIT_TO_USER_MODE_WORK))
208209 ti_work = exit_to_user_mode_loop(regs, ti_work);
kernel/time/tick-sched.c+1−0
@@ -230,6 +230,7 @@ static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs) · 229 unmodified lines
230230
231231 #ifdef CONFIG_NO_HZ_FULL
232232 cpumask_var_t tick_nohz_full_mask;
233+EXPORT_SYMBOL_GPL(tick_nohz_full_mask);
233234 bool tick_nohz_full_running;
234235 EXPORT_SYMBOL_GPL(tick_nohz_full_running);
235236 static atomic_t tick_dep_mask;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t