From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751994AbdHaM1C (ORCPT ); Thu, 31 Aug 2017 08:27:02 -0400 Received: from Galois.linutronix.de ([146.0.238.70]:60584 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751670AbdHaMXn (ORCPT ); Thu, 31 Aug 2017 08:23:43 -0400 Message-Id: <20170831105826.760504451@linutronix.de> User-Agent: quilt/0.63-1 Date: Thu, 31 Aug 2017 12:23:41 -0000 From: Anna-Maria Gleixner To: LKML Cc: Peter Zijlstra , Ingo Molnar , Christoph Hellwig , keescook@chromium.org, John Stultz , Thomas Gleixner Subject: [PATCH 15/25] hrtimer: Add clock bases for soft irq context References: <20170831105725.809317030@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline; filename=hrtimer_Add_clock_bases_for_soft_irq_context.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Anna-Maria Gleixner hrtimer callback functions are always executed in hard interrupt context. Users of hrtimer which need their timer function to be executed in soft interrupt context, make use of tasklets to get the proper context. Add additional 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 context. Keep the new clockids internal to hrtimer for now, so they can't be accessed from other code until the rest of the changes is in place. Signed-off-by: Anna-Maria Gleixner --- include/linux/hrtimer.h | 4 +++ kernel/time/hrtimer.c | 56 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 54 insertions(+), 6 deletions(-) --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -145,6 +145,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, }; --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -60,6 +60,18 @@ #include "tick-internal.h" /* + * Clock ids for timers which expire in softirq context. These clock ids + * are kernel internal and never exported to user space. Kept internal + * until the rest of the functionality is in place. + */ +#define HRTIMER_BASE_SOFT_MASK MAX_CLOCKS + +#define CLOCK_REALTIME_SOFT (CLOCK_REALTIME | HRTIMER_BASE_SOFT_MASK) +#define CLOCK_MONOTONIC_SOFT (CLOCK_MONOTONIC | HRTIMER_BASE_SOFT_MASK) +#define CLOCK_BOOTTIME_SOFT (CLOCK_BOOTTIME | HRTIMER_BASE_SOFT_MASK) +#define CLOCK_TAI_SOFT (CLOCK_TAI | HRTIMER_BASE_SOFT_MASK) + +/* * The timer bases: * * There are more clockids than hrtimer bases. Thus, we index @@ -92,17 +104,43 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, .clockid = CLOCK_TAI, .get_time = &ktime_get_clocktai, }, + { + .index = HRTIMER_BASE_MONOTONIC_SOFT, + .clockid = CLOCK_MONOTONIC_SOFT, + .get_time = &ktime_get, + }, + { + .index = HRTIMER_BASE_REALTIME_SOFT, + .clockid = CLOCK_REALTIME_SOFT, + .get_time = &ktime_get_real, + }, + { + .index = HRTIMER_BASE_BOOTTIME_SOFT, + .clockid = CLOCK_BOOTTIME_SOFT, + .get_time = &ktime_get_boottime, + }, + { + .index = HRTIMER_BASE_TAI_SOFT, + .clockid = CLOCK_TAI_SOFT, + .get_time = &ktime_get_clocktai, + }, } }; -static const int hrtimer_clock_to_base_table[MAX_CLOCKS] = { +#define MAX_CLOCKS_HRT (MAX_CLOCKS * 2) + +static const int hrtimer_clock_to_base_table[MAX_CLOCKS_HRT] = { /* Make sure we catch unsupported clockids */ - [0 ... MAX_CLOCKS - 1] = HRTIMER_MAX_CLOCK_BASES, + [0 ... MAX_CLOCKS_HRT - 1] = HRTIMER_MAX_CLOCK_BASES, - [CLOCK_REALTIME] = HRTIMER_BASE_REALTIME, - [CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC, - [CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME, - [CLOCK_TAI] = HRTIMER_BASE_TAI, + [CLOCK_REALTIME] = HRTIMER_BASE_REALTIME, + [CLOCK_MONOTONIC] = HRTIMER_BASE_MONOTONIC, + [CLOCK_BOOTTIME] = HRTIMER_BASE_BOOTTIME, + [CLOCK_TAI] = HRTIMER_BASE_TAI, + [CLOCK_REALTIME_SOFT] = HRTIMER_BASE_REALTIME_SOFT, + [CLOCK_MONOTONIC_SOFT] = HRTIMER_BASE_MONOTONIC_SOFT, + [CLOCK_BOOTTIME_SOFT] = HRTIMER_BASE_BOOTTIME_SOFT, + [CLOCK_TAI_SOFT] = HRTIMER_BASE_TAI_SOFT, }; /* @@ -1652,6 +1690,12 @@ int hrtimers_dead_cpu(unsigned int scpu) void __init hrtimers_init(void) { + /* + * It is necessary, that the soft base mask is a single + * bit. + */ + BUILD_BUG_ON_NOT_POWER_OF_2(HRTIMER_BASE_SOFT_MASK); + hrtimers_prepare_cpu(smp_processor_id()); }