hrtimer: Add clock bases and hrtimer mode for softirq context
authorAnna-Maria Gleixner <anna-maria@linutronix.de>
Thu, 21 Dec 2017 10:41:55 +0000 (11:41 +0100)
committerIngo Molnar <mingo@kernel.org>
Tue, 16 Jan 2018 02:00:50 +0000 (03:00 +0100)
Currently hrtimer callback functions are always executed in hard interrupt
context. Users of hrtimers, which need their timer function to be executed
in soft interrupt context, make use of tasklets to get the proper context.

Add additional hrtimer clock bases for timers which must expire in softirq
context, so the detour via the tasklet can be avoided. This is also
required for RT, where the majority of hrtimer is moved into softirq
hrtimer context.

The selection of the expiry mode happens via a mode bit. Introduce
HRTIMER_MODE_SOFT and the matching combinations with the ABS/REL/PINNED
bits and update the decoding of hrtimer_mode in tracepoints.

Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de>
Cc: Christoph Hellwig <hch@lst.de>
Cc: John Stultz <john.stultz@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: keescook@chromium.org
Link: http://lkml.kernel.org/r/20171221104205.7269-27-anna-maria@linutronix.de
Signed-off-by: Ingo Molnar <mingo@kernel.org>
include/linux/hrtimer.h
include/trace/events/timer.h
kernel/time/hrtimer.c

index 98ed35767ac5ff366c7417f08fd5fd3da75b3e33..26ae8a868ea8fdcf87b328a05322aea927fa250d 100644 (file)
@@ -33,14 +33,24 @@ struct hrtimer_cpu_base;
  * HRTIMER_MODE_REL            - Time value is relative to now
  * HRTIMER_MODE_PINNED         - Timer is bound to CPU (is only considered
  *                               when starting the timer)
+ * HRTIMER_MODE_SOFT           - Timer callback function will be executed in
+ *                               soft irq context
  */
 enum hrtimer_mode {
        HRTIMER_MODE_ABS        = 0x00,
        HRTIMER_MODE_REL        = 0x01,
        HRTIMER_MODE_PINNED     = 0x02,
+       HRTIMER_MODE_SOFT       = 0x04,
 
        HRTIMER_MODE_ABS_PINNED = HRTIMER_MODE_ABS | HRTIMER_MODE_PINNED,
        HRTIMER_MODE_REL_PINNED = HRTIMER_MODE_REL | HRTIMER_MODE_PINNED,
+
+       HRTIMER_MODE_ABS_SOFT   = HRTIMER_MODE_ABS | HRTIMER_MODE_SOFT,
+       HRTIMER_MODE_REL_SOFT   = HRTIMER_MODE_REL | HRTIMER_MODE_SOFT,
+
+       HRTIMER_MODE_ABS_PINNED_SOFT = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_SOFT,
+       HRTIMER_MODE_REL_PINNED_SOFT = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_SOFT,
+
 };
 
 /*
@@ -151,6 +161,10 @@ enum  hrtimer_base_type {
        HRTIMER_BASE_REALTIME,
        HRTIMER_BASE_BOOTTIME,
        HRTIMER_BASE_TAI,
+       HRTIMER_BASE_MONOTONIC_SOFT,
+       HRTIMER_BASE_REALTIME_SOFT,
+       HRTIMER_BASE_BOOTTIME_SOFT,
+       HRTIMER_BASE_TAI_SOFT,
        HRTIMER_MAX_CLOCK_BASES,
 };
 
index 744b4310b24b0b8922877a926fd124cf8954efca..a57e4ee989d6229476471c5527a44b230014926c 100644 (file)
@@ -148,7 +148,11 @@ DEFINE_EVENT(timer_class, timer_cancel,
                { HRTIMER_MODE_ABS,             "ABS"           },      \
                { HRTIMER_MODE_REL,             "REL"           },      \
                { HRTIMER_MODE_ABS_PINNED,      "ABS|PINNED"    },      \
-               { HRTIMER_MODE_REL_PINNED,      "REL|PINNED"    })
+               { HRTIMER_MODE_REL_PINNED,      "REL|PINNED"    },      \
+               { HRTIMER_MODE_ABS_SOFT,        "ABS|SOFT"      },      \
+               { HRTIMER_MODE_REL_SOFT,        "REL|SOFT"      },      \
+               { HRTIMER_MODE_ABS_PINNED_SOFT, "ABS|PINNED|SOFT" },    \
+               { HRTIMER_MODE_REL_PINNED_SOFT, "REL|PINNED|SOFT" })
 
 /**
  * hrtimer_init - called when the hrtimer is initialized
index 31ccd86e63c0bb777d869f7affc7d01d3f82fd0e..e2353f5cdf518ed5086f61388ce669300be65a22 100644 (file)
@@ -92,6 +92,26 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
                        .clockid = CLOCK_TAI,
                        .get_time = &ktime_get_clocktai,
                },
+               {
+                       .index = HRTIMER_BASE_MONOTONIC_SOFT,
+                       .clockid = CLOCK_MONOTONIC,
+                       .get_time = &ktime_get,
+               },
+               {
+                       .index = HRTIMER_BASE_REALTIME_SOFT,
+                       .clockid = CLOCK_REALTIME,
+                       .get_time = &ktime_get_real,
+               },
+               {
+                       .index = HRTIMER_BASE_BOOTTIME_SOFT,
+                       .clockid = CLOCK_BOOTTIME,
+                       .get_time = &ktime_get_boottime,
+               },
+               {
+                       .index = HRTIMER_BASE_TAI_SOFT,
+                       .clockid = CLOCK_TAI,
+                       .get_time = &ktime_get_clocktai,
+               },
        }
 };