From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linutronix.de (146.0.238.70:993) by crypto-ml.lab.linutronix.de with IMAP4-SSL for ; 21 Jan 2019 19:54:56 -0000 Received: from mga11.intel.com ([192.55.52.93]) by Galois.linutronix.de with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1gkeqX-0003NL-9S for speck@linutronix.de; Sat, 19 Jan 2019 01:50:49 +0100 From: Andi Kleen Subject: [MODERATED] [PATCH v5 17/27] MDSv5 9 Date: Fri, 18 Jan 2019 16:50:32 -0800 Message-Id: <5455fae5a329c4b163b372d7b4955aeb35e26bfc.1547858934.git.ak@linux.intel.com> In-Reply-To: References: In-Reply-To: References: To: speck@linutronix.de Cc: Andi Kleen List-ID: From: Andi Kleen Subject: mds: Clear cpu on all timers, unless the timer opts-out By default we assume timers might touch user data and schedule a cpu clear on next kernel exit. Support opt-outs where timer and hrtimer handlers can opt-in they they don't touch any user data. Note this takes one bit from the timer wheel index field away, but it seems there are less wheels available anyways, so that should be ok. Signed-off-by: Andi Kleen --- include/linux/hrtimer.h | 4 ++++ include/linux/timer.h | 9 ++++++--- kernel/time/hrtimer.c | 5 +++++ kernel/time/timer.c | 8 ++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 2e8957eac4d4..b32c76919f78 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -32,6 +32,7 @@ struct hrtimer_cpu_base; * when starting the timer) * HRTIMER_MODE_SOFT - Timer callback function will be executed in * soft irq context + * HRTIMER_MODE_NO_USER - Handler does not touch user data. */ enum hrtimer_mode { HRTIMER_MODE_ABS = 0x00, @@ -48,6 +49,7 @@ enum hrtimer_mode { HRTIMER_MODE_ABS_PINNED_SOFT = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_SOFT, HRTIMER_MODE_REL_PINNED_SOFT = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_SOFT, + HRTIMER_MODE_NO_USER = 0x08, }; /* @@ -101,6 +103,7 @@ enum hrtimer_restart { * @state: state information (See bit values above) * @is_rel: Set if the timer was armed relative * @is_soft: Set if hrtimer will be expired in soft interrupt context. + * @no_user: function does not touch user data. * * The hrtimer structure must be initialized by hrtimer_init() */ @@ -112,6 +115,7 @@ struct hrtimer { u8 state; u8 is_rel; u8 is_soft; + u8 no_user; }; /** diff --git a/include/linux/timer.h b/include/linux/timer.h index 7b066fd38248..222e72432be3 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -56,10 +56,13 @@ struct timer_list { #define TIMER_DEFERRABLE 0x00080000 #define TIMER_PINNED 0x00100000 #define TIMER_IRQSAFE 0x00200000 -#define TIMER_ARRAYSHIFT 22 -#define TIMER_ARRAYMASK 0xFFC00000 +#define TIMER_NO_USER 0x00400000 +#define TIMER_ARRAYSHIFT 23 +#define TIMER_ARRAYMASK 0xFF800000 -#define TIMER_TRACE_FLAGMASK (TIMER_MIGRATING | TIMER_DEFERRABLE | TIMER_PINNED | TIMER_IRQSAFE) +#define TIMER_TRACE_FLAGMASK \ + (TIMER_MIGRATING | TIMER_DEFERRABLE | TIMER_PINNED | TIMER_IRQSAFE | \ + TIMER_NO_USER) #define __TIMER_INITIALIZER(_function, _flags) { \ .entry = { .next = TIMER_ENTRY_STATIC }, \ diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index f5cfa1b73d6f..e2c8776ba2a4 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -42,6 +42,7 @@ #include #include #include +#include #include @@ -1276,6 +1277,7 @@ static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, clock_id = CLOCK_MONOTONIC; base += hrtimer_clockid_to_base(clock_id); + timer->no_user = !!(mode & HRTIMER_MODE_NO_USER); timer->is_soft = softtimer; timer->base = &cpu_base->clock_base[base]; timerqueue_init(&timer->node); @@ -1390,6 +1392,9 @@ static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, trace_hrtimer_expire_exit(timer); raw_spin_lock_irq(&cpu_base->lock); + if (!timer->no_user) + lazy_clear_cpu(); + /* * Note: We clear the running state after enqueue_hrtimer and * we do not reprogram the event hardware. Happens either in diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 444156debfa0..e6ab6986ffc8 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -1338,6 +1339,13 @@ static void call_timer_fn(struct timer_list *timer, void (*fn)(struct timer_list */ preempt_count_set(count); } + + /* + * The timer might have touched user data. Schedule + * a cpu clear on the next kernel exit. + */ + if (!(timer->flags & TIMER_NO_USER)) + lazy_clear_cpu(); } static void expire_timers(struct timer_base *base, struct hlist_head *head) -- 2.17.2