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 <[email protected]>

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


Reply via email to