From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751728AbdHaMXo (ORCPT ); Thu, 31 Aug 2017 08:23:44 -0400 Received: from Galois.linutronix.de ([146.0.238.70]:60551 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751488AbdHaMXk (ORCPT ); Thu, 31 Aug 2017 08:23:40 -0400 Message-Id: <20170831105826.365542256@linutronix.de> User-Agent: quilt/0.63-1 Date: Thu, 31 Aug 2017 12:23:38 -0000 From: Anna-Maria Gleixner To: LKML Cc: Peter Zijlstra , Ingo Molnar , Christoph Hellwig , keescook@chromium.org, John Stultz , Thomas Gleixner Subject: [PATCH 10/25] hrtimer: Make handling of hrtimer reprogramming and enqueuing not conditional References: <20170831105725.809317030@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline; filename=hrtimer--handle-gleich.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The hrtimer_reprogramming, remote timer enqueuing and handling of the hrtimer_cpu_base struct member expires_next depend on the active high resolution timers. This makes the code harder to understand. To simplify the code, the hrtimer reprogramming is now executed independently except for the real reprogramming part. The expires_next stores now the first enqueued timer. Due to the adaption of the check_target function, remote enqueuing is now only possible when the expiry time is after the currently first expiry time independent of the active high resolution timers. Signed-off-by: Anna-Maria Gleixner --- kernel/time/hrtimer.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -154,10 +154,11 @@ struct hrtimer_clock_base *lock_hrtimer_ } /* - * With high resolution timers enabled we do not migrate the timer - * when it is expiring before the next event on the target cpu because - * we cannot reprogram the target cpu hardware and we would cause it - * to fire late. + * We do not migrate the timer when it is expiring before the next + * event on the target cpu. When high resolution is enabled, we cannot + * reprogram the target cpu hardware and we would cause it to fire + * late. To keep it simple, we handle the high resolution enabled and + * disabled case similar. * * Called with cpu_base->lock of target cpu held. */ @@ -166,9 +167,6 @@ hrtimer_check_target(struct hrtimer *tim { ktime_t expires; - if (!new_base->cpu_base->hres_active) - return 0; - expires = ktime_sub(hrtimer_get_expires(timer), new_base->offset); return expires <= new_base->cpu_base->expires_next; } @@ -689,21 +687,24 @@ static void hrtimer_reprogram(struct hrt /* Update the pointer to the next expiring timer */ hrtimer_update_next_timer(cpu_base, timer); + cpu_base->expires_next = expires; /* + * If hres is not active, hardware does not have to be + * programmed yet. + * * If a hang was detected in the last timer interrupt then we * do not schedule a timer which is earlier than the expiry * which we enforced in the hang detection. We want the system * to make progress. */ - if (cpu_base->hang_detected) + if (!__hrtimer_hres_active(cpu_base) || cpu_base->hang_detected) return; /* * Program the timer hardware. We enforce the expiry for * events which are already in the past. */ - cpu_base->expires_next = expires; tick_program_event(expires, 1); } @@ -943,16 +944,8 @@ void hrtimer_start_range_ns(struct hrtim if (!leftmost) goto unlock; - if (!hrtimer_is_hres_active(timer)) { - /* - * Kick to reschedule the next tick to handle the new timer - * on dynticks target. - */ - if (new_base->cpu_base->nohz_active) - wake_up_nohz_cpu(new_base->cpu_base->cpu); - } else { - hrtimer_reprogram(timer, new_base); - } + hrtimer_reprogram(timer, new_base); + unlock: unlock_hrtimer_base(timer, &flags); }