From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BBEF53A7F70 for ; Tue, 24 Feb 2026 16:36:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771950973; cv=none; b=PiIJHtoldJ8gXzweAn9VzzHlr+6lK4knHzTKc05xmPdktYWB16pm/Ihz98lpR8oZuXRjvsv2ToC5NjwT72Rcohke9GVYRqx/KwR90EJHYfXzUwAy8sfVh34yHSG/3oLQYIBRwhoAbCHSo2wMWASdJDlXT5+GAGjqS4BzdDn7MoM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771950973; c=relaxed/simple; bh=nu9vMrdiR6vyLXbjcbF7j1PN1pBFhVJBtbJrOkS8Yyk=; h=Date:Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=pu91sAP8jfF9HvUPcESN6l3gN7Vk/CEsVXX/oDh+4HX4d8dMhKU699KpObgSMKxiDXQKplKaXQwtptS3X3I8PoHfBUupDggfv0+0kmhFxUFgdED2mD8EngHlldf2wSgJ9N9p+EFCZr1AWPSdPS9BzHaAwQ0uDjwWIn2MHdfR6CI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AFl0pOO1; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="AFl0pOO1" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 29D77C116D0; Tue, 24 Feb 2026 16:36:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1771950973; bh=nu9vMrdiR6vyLXbjcbF7j1PN1pBFhVJBtbJrOkS8Yyk=; h=Date:From:To:Cc:Subject:References:From; b=AFl0pOO1GEz8XtLIOcWTyY5D3OKz4BQnZxdN9pqqsSdX0dCflI5rcPQ7YVSyQx0Oh YiiNtiZaZWnn7+Zy99Mab2La5644jQYQPm90xvPLmTzzkOIukBOIgJ+PayRz4G7iRj q+Rvxe50sqf09egUVJsgbYRDXO8wQ1jvo5g3GpVk21IaFY+djnRbQrZudYtwH9IUJ7 gZIBiunYFm6sClawVrSxSFqAYEzyOnCb5fxAy+KQ6ms6H2844cNJ24lJolhV2h316l BXPxnJs/Kpv77qpNSCa2versGQMo5doHh90vwpVLD7/u1KzQIIi3ze++30DRhE0pIw k7H25yRh5DRWQ== Date: Tue, 24 Feb 2026 17:36:10 +0100 Message-ID: <20260224163429.542178086@kernel.org> User-Agent: quilt/0.68 From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , John Stultz , Stephen Boyd , Daniel Lezcano , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Valentin Schneider , x86@kernel.org, Peter Zijlstra , Frederic Weisbecker , Eric Dumazet Subject: [patch 12/48] tick/sched: Avoid hrtimer_cancel/start() sequence References: <20260224163022.795809588@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 The sequence of cancel and start is inefficient. It has to do the timer lock/unlock twice and in the worst case has to reprogram the underlying clock event device twice. The reason why it is done this way is the usage of hrtimer_forward_now(), which requires the timer to be inactive. But that can be completely avoided as the forward can be done on a variable and does not need any of the overrun accounting provided by hrtimer_forward_now(). Implement a trivial forwarding mechanism and replace the cancel/reprogram sequence with hrtimer_start(..., new_expiry). For the non high resolution case the timer is not actually armed, but used for storage so that code checking for expiry times can unconditially look it up in the timer. So it is safe for that case to set the new expiry time directly. Signed-off-by: Thomas Gleixner --- kernel/time/tick-sched.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -864,19 +864,32 @@ u64 get_cpu_iowait_time_us(int cpu, u64 } EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us); +/* Simplified variant of hrtimer_forward_now() */ +static ktime_t tick_forward_now(ktime_t expires, ktime_t now) +{ + ktime_t delta = now - expires; + + if (likely(delta < TICK_NSEC)) + return expires + TICK_NSEC; + + expires += TICK_NSEC * ktime_divns(delta, TICK_NSEC); + if (expires > now) + return expires; + return expires + TICK_NSEC; +} + static void tick_nohz_restart(struct tick_sched *ts, ktime_t now) { - hrtimer_cancel(&ts->sched_timer); - hrtimer_set_expires(&ts->sched_timer, ts->last_tick); + ktime_t expires = ts->last_tick; - /* Forward the time to expire in the future */ - hrtimer_forward(&ts->sched_timer, now, TICK_NSEC); + if (now >= expires) + expires = tick_forward_now(expires, now); if (tick_sched_flag_test(ts, TS_FLAG_HIGHRES)) { - hrtimer_start_expires(&ts->sched_timer, - HRTIMER_MODE_ABS_PINNED_HARD); + hrtimer_start(&ts->sched_timer, expires, HRTIMER_MODE_ABS_PINNED_HARD); } else { - tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1); + hrtimer_set_expires(&ts->sched_timer, expires); + tick_program_event(expires, 1); } /*