Web lists-archives.com

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




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@xxxxxxxxxx>

---
 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);
 }