All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] hrtimer: avoid retrigger_next_event IPI
@ 2021-04-07 13:53 Marcelo Tosatti
  2021-04-07 19:28   ` kernel test robot
                   ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Marcelo Tosatti @ 2021-04-07 13:53 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: linux-kernel, Frederic Weisbecker, Peter Xu, Nitesh Narayan Lal,
	Alex Belits


Setting the realtime clock triggers an IPI to all CPUs to reprogram
hrtimers.

However, only base, boottime and tai clocks have their offsets updated
(and therefore potentially require a reprogram).

If the CPU is a nohz_full one, check if it only has 
monotonic active timers, and in that case update the 
realtime base offsets, skipping the IPI.

This reduces interruptions to nohz_full CPUs.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index 743c852e10f2..b42b1a434b22 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -853,6 +853,28 @@ static void hrtimer_reprogram(struct hrtimer *timer, bool reprogram)
 	tick_program_event(expires, 1);
 }
 
+#define CLOCK_SET_BASES ((1U << HRTIMER_BASE_REALTIME)|		\
+			 (1U << HRTIMER_BASE_REALTIME_SOFT)|	\
+			 (1U << HRTIMER_BASE_BOOTTIME)|		\
+			 (1U << HRTIMER_BASE_BOOTTIME_SOFT)|	\
+			 (1U << HRTIMER_BASE_TAI)|		\
+			 (1U << HRTIMER_BASE_TAI_SOFT))
+
+static bool need_reprogram_timer(struct hrtimer_cpu_base *cpu_base)
+{
+	unsigned int active = 0;
+
+	if (!cpu_base->softirq_activated)
+		active = cpu_base->active_bases & HRTIMER_ACTIVE_SOFT;
+
+	active = active | (cpu_base->active_bases & HRTIMER_ACTIVE_HARD);
+
+	if ((active & CLOCK_SET_BASES) == 0)
+		return false;
+
+	return true;
+}
+
 /*
  * Clock realtime was set
  *
@@ -867,9 +889,41 @@ static void hrtimer_reprogram(struct hrtimer *timer, bool reprogram)
 void clock_was_set(void)
 {
 #ifdef CONFIG_HIGH_RES_TIMERS
-	/* Retrigger the CPU local events everywhere */
-	on_each_cpu(retrigger_next_event, NULL, 1);
+	cpumask_var_t mask;
+	int cpu;
+
+	if (!tick_nohz_full_enabled()) {
+		/* Retrigger the CPU local events everywhere */
+		on_each_cpu(retrigger_next_event, NULL, 1);
+		goto set_timerfd;
+	}
+
+	if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) {
+		on_each_cpu(retrigger_next_event, NULL, 1);
+		goto set_timerfd;
+	}
+
+	/* Avoid interrupting nohz_full CPUs if possible */
+	preempt_disable();
+	for_each_online_cpu(cpu) {
+		if (tick_nohz_full_cpu(cpu)) {
+			unsigned long flags;
+			struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
+
+			raw_spin_lock_irqsave(&cpu_base->lock, flags);
+			if (need_reprogram_timer(cpu_base))
+				cpumask_set_cpu(cpu, mask);
+			else
+				hrtimer_update_base(cpu_base);
+			raw_spin_unlock_irqrestore(&cpu_base->lock, flags);
+		}
+	}
+
+	smp_call_function_many(mask, retrigger_next_event, NULL, 1);
+	preempt_enable();
+	free_cpumask_var(mask);
 #endif
+set_timerfd:
 	timerfd_clock_was_set();
 }
 


^ permalink raw reply related	[flat|nested] 21+ messages in thread
* Re: [PATCH] hrtimer: avoid retrigger_next_event IPI
@ 2021-04-07 18:20 kernel test robot
  0 siblings, 0 replies; 21+ messages in thread
From: kernel test robot @ 2021-04-07 18:20 UTC (permalink / raw)
  To: kbuild

[-- Attachment #1: Type: text/plain, Size: 7284 bytes --]

CC: kbuild-all(a)lists.01.org
In-Reply-To: <20210407135301.GA16985@fuller.cnet>
References: <20210407135301.GA16985@fuller.cnet>
TO: Marcelo Tosatti <mtosatti@redhat.com>
TO: Thomas Gleixner <tglx@linutronix.de>
CC: linux-kernel(a)vger.kernel.org
CC: Frederic Weisbecker <frederic@kernel.org>
CC: Peter Xu <peterx@redhat.com>
CC: Nitesh Narayan Lal <nitesh@redhat.com>
CC: Alex Belits <abelits@marvell.com>

Hi Marcelo,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on tip/timers/core]
[also build test WARNING on linux/master linus/master v5.12-rc6 next-20210407]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Marcelo-Tosatti/hrtimer-avoid-retrigger_next_event-IPI/20210407-233005
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git d4c7c28806616809e3baa0b7cd8c665516b2726d
:::::: branch date: 3 hours ago
:::::: commit date: 3 hours ago
config: i386-randconfig-s001-20210407 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.3-279-g6d5d9b42-dirty
        # https://github.com/0day-ci/linux/commit/defd4db9d63d1f16e3e21862bd9c9105a9f6a7e9
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Marcelo-Tosatti/hrtimer-avoid-retrigger_next_event-IPI/20210407-233005
        git checkout defd4db9d63d1f16e3e21862bd9c9105a9f6a7e9
        # save the attached .config to linux build tree
        make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)
>> kernel/time/hrtimer.c:944:1: sparse: sparse: unused label 'set_timerfd'

vim +/set_timerfd +944 kernel/time/hrtimer.c

defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  895  
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  896  /*
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  897   * Clock realtime was set
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  898   *
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  899   * Change the offset of the realtime clock vs. the monotonic
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  900   * clock.
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  901   *
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  902   * We might have to reprogram the high resolution timer interrupt. On
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  903   * SMP we call the architecture specific code to retrigger _all_ high
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  904   * resolution timer interrupts. On UP we just disable interrupts and
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  905   * call the high resolution interrupt code.
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  906   */
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  907  void clock_was_set(void)
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  908  {
90ff1f30c0f401 kernel/hrtimer.c      Thomas Gleixner 2011-05-25  909  #ifdef CONFIG_HIGH_RES_TIMERS
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  910  	cpumask_var_t mask;
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  911  	int cpu;
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  912  
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  913  	if (!tick_nohz_full_enabled()) {
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  914  		/* Retrigger the CPU local events everywhere */
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  915  		on_each_cpu(retrigger_next_event, NULL, 1);
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  916  		goto set_timerfd;
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  917  	}
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  918  
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  919  	if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) {
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  920  		on_each_cpu(retrigger_next_event, NULL, 1);
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  921  		goto set_timerfd;
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  922  	}
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  923  
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  924  	/* Avoid interrupting nohz_full CPUs if possible */
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  925  	preempt_disable();
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  926  	for_each_online_cpu(cpu) {
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  927  		if (tick_nohz_full_cpu(cpu)) {
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  928  			unsigned long flags;
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  929  			struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  930  
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  931  			raw_spin_lock_irqsave(&cpu_base->lock, flags);
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  932  			if (need_reprogram_timer(cpu_base))
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  933  				cpumask_set_cpu(cpu, mask);
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  934  			else
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  935  				hrtimer_update_base(cpu_base);
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  936  			raw_spin_unlock_irqrestore(&cpu_base->lock, flags);
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  937  		}
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  938  	}
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  939  
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  940  	smp_call_function_many(mask, retrigger_next_event, NULL, 1);
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  941  	preempt_enable();
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07  942  	free_cpumask_var(mask);
9ec2690758a546 kernel/hrtimer.c      Thomas Gleixner 2011-05-20  943  #endif
defd4db9d63d1f kernel/time/hrtimer.c Marcelo Tosatti 2021-04-07 @944  set_timerfd:
9ec2690758a546 kernel/hrtimer.c      Thomas Gleixner 2011-05-20  945  	timerfd_clock_was_set();
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  946  }
b12a03ce4880bd kernel/hrtimer.c      Thomas Gleixner 2011-05-02  947  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 33876 bytes --]

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2021-04-19 20:54 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-07 13:53 [PATCH] hrtimer: avoid retrigger_next_event IPI Marcelo Tosatti
2021-04-07 19:28 ` kernel test robot
2021-04-07 19:28   ` kernel test robot
2021-04-07 22:14 ` Frederic Weisbecker
2021-04-08 12:27   ` Marcelo Tosatti
2021-04-09 14:15 ` Thomas Gleixner
2021-04-09 16:51   ` Marcelo Tosatti
2021-04-10  7:53     ` Thomas Gleixner
2021-04-13 17:04       ` [PATCH v2] " Marcelo Tosatti
2021-04-14 17:19         ` Thomas Gleixner
2021-04-15 15:39         ` [PATCH v3] " Marcelo Tosatti
2021-04-15 18:59           ` Thomas Gleixner
2021-04-15 20:40             ` [PATCH v4] " Marcelo Tosatti
2021-04-16 16:00               ` [PATCH v5] " Marcelo Tosatti
2021-04-16 17:13                 ` Peter Xu
2021-04-17 16:24                   ` Thomas Gleixner
2021-04-17 16:51                     ` Thomas Gleixner
2021-04-19 18:56                       ` Marcelo Tosatti
2021-04-19 19:39                 ` [PATCH v6] " Marcelo Tosatti
2021-04-19 20:52                   ` Thomas Gleixner
2021-04-07 18:20 [PATCH] " kernel test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.