|
@@ -814,6 +814,8 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
|
|
|
return HRTIMER_RESTART;
|
|
|
}
|
|
|
|
|
|
+static int sched_skew_tick;
|
|
|
+
|
|
|
/**
|
|
|
* tick_setup_sched_timer - setup the tick emulation timer
|
|
|
*/
|
|
@@ -831,6 +833,14 @@ void tick_setup_sched_timer(void)
|
|
|
/* Get the next period (per cpu) */
|
|
|
hrtimer_set_expires(&ts->sched_timer, tick_init_jiffy_update());
|
|
|
|
|
|
+ /* Offset the tick to avert xtime_lock contention. */
|
|
|
+ if (sched_skew_tick) {
|
|
|
+ u64 offset = ktime_to_ns(tick_period) >> 1;
|
|
|
+ do_div(offset, num_possible_cpus());
|
|
|
+ offset *= smp_processor_id();
|
|
|
+ hrtimer_add_expires_ns(&ts->sched_timer, offset);
|
|
|
+ }
|
|
|
+
|
|
|
for (;;) {
|
|
|
hrtimer_forward(&ts->sched_timer, now, tick_period);
|
|
|
hrtimer_start_expires(&ts->sched_timer,
|
|
@@ -910,3 +920,11 @@ int tick_check_oneshot_change(int allow_nohz)
|
|
|
tick_nohz_switch_to_nohz();
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
+static int __init skew_tick(char *str)
|
|
|
+{
|
|
|
+ get_option(&str, &sched_skew_tick);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+early_param("skew_tick", skew_tick);
|