From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0049A3ED5CC for ; Wed, 22 Apr 2026 14:26:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776868005; cv=none; b=USLkiLOTtYhMq4DPmMz2sSfDAAT/HA5KSoBENx30H9GovRMa5nCCJlJ56Zh+fDCEMNnb+7XfRnTseVoVYcvzmBhJZ05i8hMiwgX1OLmKhr8oQPT/h/nGwH7c5Q0CpeG6FOP0lTas+l7kyPVcwd9QmKfJooxNBFnNSGl36L0242c= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776868005; c=relaxed/simple; bh=m0TgYRj+A+8PdcCtg5P3EadDnf3QRg7dTI5AfdououM=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=Exw0zE2qhYvbztZywoqAgZ4il5CCLP2XbgaxnnQwEPPvodYDyyEVKVhh9qgMMiVb9IBJMjs96tCdaaOQ+dp1o/1nGSmUBe+Qbpovqt3k2HhOdv2RToxynoZ4MoJ6E/6v1m5KtCdF9SYzZ7zDKDh9aOVz1Mns9ZgBgf/Yl/ZbMWE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=bLCv23mW; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="bLCv23mW" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4E8531650; Wed, 22 Apr 2026 07:26:35 -0700 (PDT) Received: from [10.57.32.48] (unknown [10.57.32.48]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 342A23FAA1; Wed, 22 Apr 2026 07:26:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1776868000; bh=m0TgYRj+A+8PdcCtg5P3EadDnf3QRg7dTI5AfdououM=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=bLCv23mWP+GEnmBiprQj1nNT7DdEbGgdlF+w+5uyDBpLNjSrxiUd6VoG45nUnWYAV f3uOWbRkaUja+2hpMPdHtcDirLMQR6p+2pCuBTVlHVnKerTBkWqNBJYwFvO5UXBSVG 6CHjjdBJt/2p/Dt+tf6MmMGHPa+GjYYKYHTWw2OY= Message-ID: <1295a3ce-65ae-4925-a022-fbe50ad7ff92@arm.com> Date: Wed, 22 Apr 2026 15:26:27 +0100 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] sched/idle: Fix avg_idle saturation by establishing symmetric idle entry hook To: Masahito S , mingo@redhat.com, peterz@infradead.org, juri.lelli@redhat.com, vincent.guittot@linaro.org Cc: dietmar.eggemann@arm.com, rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de, vschneid@redhat.com, kprateek.nayak@amd.com, linux-kernel@vger.kernel.org References: <20260417020654.911709-1-firelzrd@gmail.com> Content-Language: en-US From: Christian Loehle In-Reply-To: <20260417020654.911709-1-firelzrd@gmail.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On 4/17/26 03:06, Masahito S wrote: > update_rq_avg_idle(), called from put_prev_task_idle(), computes > rq->avg_idle as rq_clock() - rq->idle_stamp. However, idle_stamp is > only set by sched_balance_newidle() when a CPU enters CPU_NEWLY_IDLE > through the fair class path. When the idle task is preempted without > sched_balance_newidle() having run (boot, hotplug, sched class > transitions), idle_stamp remains 0, producing a delta equal to > rq_clock() — a value in the billions of nanoseconds — which saturates > avg_idle at 2 * max_idle_balance_cost. > > This inflated avg_idle prevents sched_balance_newidle() from > early-returning (fair.c: avg_idle < max_newidle_lb_cost check), > making it overly aggressive. The resulting excess newidle migrations > override wake-time placement decisions made by select_idle_sibling(), > degrading cache locality that careful placement (recent_used_cpu, > select_idle_core, etc.) is designed to preserve. > > Fix this by: > > 1. Adding an idle_stamp validity guard to update_rq_avg_idle(), so > that a zero idle_stamp is never used as a timestamp. > > 2. Setting idle_stamp in set_next_task_idle() when it has not already > been set by sched_balance_newidle(). This e> avg_idle at 2 * max_idle_balance_cost.stablishes a symmetric > idle entry/exit contract: set_next_task_idle() marks the start of > the idle period, put_prev_task_idle() measures and records it via > update_rq_avg_idle(). > > The entry hook preserves idle_stamp if sched_balance_newidle() has > already set it, maintaining the existing semantic where balance-attempt > duration is included in the idle measurement. You're missing the sign-off tag. The actual change looks reasonable to me, albeit the impact surely limited. > --- > kernel/sched/core.c | 3 +++ > kernel/sched/idle.c | 3 +++ > 2 files changed, 6 insertions(+) > > diff --git a/kernel/sched/core.c b/kernel/sched/core.c > index 496dff740d..ec801f731c 100644 > --- a/kernel/sched/core.c > +++ b/kernel/sched/core.c > @@ -3633,6 +3633,9 @@ static inline void ttwu_do_wakeup(struct task_struct *p) > > void update_rq_avg_idle(struct rq *rq) > { > + if (!rq->idle_stamp) > + return; > + > u64 delta = rq_clock(rq) - rq->idle_stamp; > u64 max = 2*rq->max_idle_balance_cost; > > diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c > index a83be0c834..9ceb7e6224 100644 > --- a/kernel/sched/idle.c > +++ b/kernel/sched/idle.c > @@ -491,6 +491,9 @@ static void set_next_task_idle(struct rq *rq, struct task_struct *next, bool fir > schedstat_inc(rq->sched_goidle); > next->se.exec_start = rq_clock_task(rq); > > + if (!rq->idle_stamp) > + rq->idle_stamp = rq_clock(rq); > + > /* > * rq is about to be idle, check if we need to update the > * lost_idle_time of clock_pelt