[patch 2/3] timers: do not raise softirq unconditionally (spinlockless version)

Marcelo Tosatti
2019-04-15T20:16:06Z

[-- Attachment #1: 02-do-not-raise-softirq-unconditionally-second-attempt --]
[-- Type: text/plain, Size: 1162 bytes --]

Check base->pending_map locklessly and skip raising timer softirq
if empty.

What allows the lockless (and potentially racy against mod_timer)
check is that mod_timer will raise another timer softirq after
modifying base->pending_map.

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

---
kernel/time/timer.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

Index: linux-rt-devel/kernel/time/timer.c
===================================================================
--- linux-rt-devel.orig/kernel/time/timer.c 2019-04-15 14:21:02.788704354 -0300
+++ linux-rt-devel/kernel/time/timer.c 2019-04-15 14:22:56.755047354 -0300
@@ -1776,6 +1776,24 @@
if (time_before(jiffies, base->clk))
return;
}
+
+#ifdef CONFIG_PREEMPT_RT_FULL
+/* On RT, irq work runs from softirq */
+ if (irq_work_needs_cpu())
+ goto raise;
+#endif
+ base = this_cpu_ptr(&timer_bases[BASE_STD]);
+ if (!housekeeping_cpu(base->cpu, HK_FLAG_TIMER)) {
+ if (!bitmap_empty(base->pending_map, WHEEL_SIZE))
+ goto raise;
+ base++;
+ if (!bitmap_empty(base->pending_map, WHEEL_SIZE))
+ goto raise;
+
+ return;
+ }
+
+raise:
raise_softirq(TIMER_SOFTIRQ);
}