From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from shelob.surriel.com (shelob.surriel.com [96.67.55.147]) (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 4497F30674B for ; Thu, 11 Jun 2026 02:14:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=96.67.55.147 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781144100; cv=none; b=exD933luK1+V6STsMwv7n7JRN5qPipm6U9m/+bToFxTKM4/XJ4cUwajgVIBY4diH1zYZf53/REFxW7YnCefUq9bGEPRCTdPetbAmeMUd/DsEvTPdbYaQNoaiLGB77QpisfR5xcPiGAB3k+mkxfnZ5mtS4lElB4ylVO3hfVnBMUA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781144100; c=relaxed/simple; bh=XmgzoyNJjZAO63TvV7Db/rKpmNCeSceyMksjQhi3ESk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AGV/sB8930t6wXTd8HHie73MVzdg4EkratuTBkl4EY7KIgggQBJEl2awj6Xt4yejZy3NGqSEqDFTndIeL0OQB3XlqdFvYKBeIknAel/ATpfe5a9IrLEBiK9AT1xR2QUOgEPrX/dVLOV2T1ZWH0Nup6udBHGq78vM71ZBATeJpSY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=surriel.com; spf=pass smtp.mailfrom=surriel.com; dkim=pass (2048-bit key) header.d=surriel.com header.i=@surriel.com header.b=HuAbt2HK; arc=none smtp.client-ip=96.67.55.147 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=surriel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=surriel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=surriel.com header.i=@surriel.com header.b="HuAbt2HK" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=surriel.com ; s=mail; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=TtLNF8u0/tIKutS9wCpH0eFPCcM5h3Ipmh/wAl+48z4=; b=HuAbt2HK2JaqpmsiRwS8sgP7Lz o+3m7ehsKpFbkiEuIfiYS/vocRT4RlYHosWruMGCXivD9xXKguoHi8lUbzrOMp9tC3rGGSbWtHSQF E5nK/G/WZMRNWndHgeaEzdbzr1ht/75n1GJsrTVAPEFUKr7U97oQj0xEp/eMpt7Fnn3ZT/Zb6W1bG 6jlmGt6CF4my+2pwAkc2WehmpBTlXPaSm8bjJne2C/0slkH9/2SCGfU5uPyIhKkdFgZ0sV9l+q7zV /gARmv+SNXJrth5wBs+G2jT0+IoRhpsH7tn4X0Z0FyJc8s6I9iVSXOAGgrRdoy5YNc0ndWBoSXn7x XEWIgWpA==; Received: from fangorn.home.surriel.com ([10.0.13.7]) by shelob.surriel.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.97.1) (envelope-from ) id 1wXUwJ-000000003Zo-0MWK; Wed, 10 Jun 2026 22:14:39 -0400 From: Rik van Riel To: linux-kernel@vger.kernel.org Cc: kernel-team@meta.com, mingo@redhat.com, peterz@infradead.org, juri.lelli@redhat.com, vincent.guittot@linaro.org, dietmar.eggemann@arm.com, vschneid@redhat.com, Rik van Riel Subject: [PATCH 3/9] sched/fair: defer WARN console output under rq->lock Date: Wed, 10 Jun 2026 22:14:10 -0400 Message-ID: <20260611021416.910555-4-riel@surriel.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260611021416.910555-1-riel@surriel.com> References: <20260611021416.910555-1-riel@surriel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Convert the WARN*() calls that run under rq->lock or ->pi_lock to the SCHED_WARN*() variants, so their console output is deferred to irq_work instead of being emitted synchronously (which can deadlock via console_unlock() -> up(&console_sem) -> try_to_wake_up() while the lock is held). This should prevent a deadlock if these warnings fire with a legacy or boot console configured. Signed-off-by: Rik van Riel Assisted-by: Claude:claude-opus-4-8 --- kernel/sched/fair.c | 66 ++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 49b48c5f5746..0cddbbe2e6a5 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -404,7 +404,7 @@ static inline void list_del_leaf_cfs_rq(struct cfs_rq *cfs_rq) static inline void assert_list_leaf_cfs_rq(struct rq *rq) { - WARN_ON_ONCE(rq->tmp_alone_branch != &rq->leaf_cfs_rq_list); + SCHED_WARN_ON_ONCE(rq->tmp_alone_branch != &rq->leaf_cfs_rq_list); } /* Iterate through all leaf cfs_rq's on a runqueue */ @@ -689,7 +689,7 @@ __sum_w_vruntime_add(struct cfs_rq *cfs_rq, struct sched_entity *se) s64 w_vruntime, key = entity_key(cfs_rq, se); w_vruntime = key * weight; - WARN_ON_ONCE((w_vruntime >> 63) != (w_vruntime >> 62)); + SCHED_WARN_ON_ONCE((w_vruntime >> 63) != (w_vruntime >> 62)); cfs_rq->sum_w_vruntime += w_vruntime; cfs_rq->sum_weight += weight; @@ -861,7 +861,7 @@ bool update_entity_lag(struct cfs_rq *cfs_rq, struct sched_entity *se) u64 avruntime = avg_vruntime(cfs_rq); s64 vlag = entity_lag(cfs_rq, se, avruntime); - WARN_ON_ONCE(!se->on_rq); + SCHED_WARN_ON_ONCE(!se->on_rq); if (se->sched_delayed) { /* previous vlag < 0 otherwise se would not be delayed */ @@ -1153,7 +1153,7 @@ static struct sched_entity *pick_eevdf(struct cfs_rq *cfs_rq, bool protect) if (sched_feat(PICK_BUDDY) && protect && cfs_rq->next && entity_eligible(cfs_rq, cfs_rq->next)) { /* ->next will never be delayed */ - WARN_ON_ONCE(cfs_rq->next->sched_delayed); + SCHED_WARN_ON_ONCE(cfs_rq->next->sched_delayed); return cfs_rq->next; } @@ -4918,7 +4918,7 @@ static inline bool load_avg_is_decayed(struct sched_avg *sa) * Make sure that rounding and/or propagation of PELT values never * break this. */ - WARN_ON_ONCE(sa->load_avg || + SCHED_WARN_ON_ONCE(sa->load_avg || sa->util_avg || sa->runnable_avg); @@ -6065,7 +6065,7 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) weight = avg_vruntime_weight(cfs_rq, se->load.weight); lag *= load + weight; - if (WARN_ON_ONCE(!load)) + if (SCHED_WARN_ON_ONCE(!load)) load = 1; lag = div64_long(lag, load); @@ -6258,7 +6258,7 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) clear_buddies(cfs_rq, se); if (flags & DEQUEUE_DELAYED) { - WARN_ON_ONCE(!se->sched_delayed); + SCHED_WARN_ON_ONCE(!se->sched_delayed); } else { bool delay = sleep; /* @@ -6268,7 +6268,7 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) if (flags & (DEQUEUE_SPECIAL | DEQUEUE_THROTTLE)) delay = false; - WARN_ON_ONCE(delay && se->sched_delayed); + SCHED_WARN_ON_ONCE(delay && se->sched_delayed); if (sched_feat(DELAY_DEQUEUE) && delay && !entity_eligible(cfs_rq, se)) { @@ -6360,7 +6360,7 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, bool first) } update_stats_curr_start(cfs_rq, se); - WARN_ON_ONCE(cfs_rq->curr); + SCHED_WARN_ON_ONCE(cfs_rq->curr); cfs_rq->curr = se; /* @@ -6422,7 +6422,7 @@ static void put_prev_entity(struct cfs_rq *cfs_rq, struct sched_entity *prev) /* in !on_rq case, update occurred at dequeue */ update_load_avg(cfs_rq, prev, 0); } - WARN_ON_ONCE(cfs_rq->curr != prev); + SCHED_WARN_ON_ONCE(cfs_rq->curr != prev); cfs_rq->curr = NULL; } @@ -6768,7 +6768,7 @@ static int tg_unthrottle_up(struct task_group *tg, void *data) cfs_rq->throttled_clock_self = 0; - if (WARN_ON_ONCE((s64)delta < 0)) + if (SCHED_WARN_ON_ONCE((s64)delta < 0)) delta = 0; cfs_rq->throttled_clock_self_time += delta; @@ -6855,8 +6855,8 @@ static int tg_throttle_down(struct task_group *tg, void *data) cfs_rq->pelt_clock_throttled = 1; } - WARN_ON_ONCE(cfs_rq->throttled_clock_self); - WARN_ON_ONCE(!list_empty(&cfs_rq->throttled_limbo_list)); + SCHED_WARN_ON_ONCE(cfs_rq->throttled_clock_self); + SCHED_WARN_ON_ONCE(!list_empty(&cfs_rq->throttled_limbo_list)); return 0; } @@ -6910,7 +6910,7 @@ static bool throttle_cfs_rq(struct cfs_rq *cfs_rq) * throttled-list. rq->lock protects completion. */ cfs_rq->throttled = 1; - WARN_ON_ONCE(cfs_rq->throttled_clock); + SCHED_WARN_ON_ONCE(cfs_rq->throttled_clock); /* * If current hierarchy was throttled, add throttle work to the @@ -7029,7 +7029,7 @@ static inline void __unthrottle_cfs_rq_async(struct cfs_rq *cfs_rq) } /* Already enqueued */ - if (WARN_ON_ONCE(!list_empty(&cfs_rq->throttled_csd_list))) + if (SCHED_WARN_ON_ONCE(!list_empty(&cfs_rq->throttled_csd_list))) return; first = list_empty(&rq->cfsb_csd_list); @@ -7042,7 +7042,7 @@ static void unthrottle_cfs_rq_async(struct cfs_rq *cfs_rq) { lockdep_assert_rq_held(rq_of(cfs_rq)); - if (WARN_ON_ONCE(!cfs_rq_throttled(cfs_rq) || + if (SCHED_WARN_ON_ONCE(!cfs_rq_throttled(cfs_rq) || cfs_rq->runtime_remaining <= 0)) return; @@ -7083,7 +7083,7 @@ static bool distribute_cfs_runtime(struct cfs_bandwidth *cfs_b) } /* By the above checks, this should never be true */ - WARN_ON_ONCE(cfs_rq->runtime_remaining > 0); + SCHED_WARN_ON_ONCE(cfs_rq->runtime_remaining > 0); scoped_guard(raw_spinlock, &cfs_b->lock) { runtime = -cfs_rq->runtime_remaining + 1; @@ -7671,7 +7671,7 @@ static void hrtick_start_fair(struct rq *rq, struct task_struct *p) u64 vdelta; u64 delta; - WARN_ON_ONCE(task_rq(p) != rq); + SCHED_WARN_ON_ONCE(task_rq(p) != rq); if (rq->cfs.h_nr_queued <= 1) return; @@ -7794,8 +7794,8 @@ requeue_delayed_entity(struct sched_entity *se) * Because a delayed entity is one that is still on * the runqueue competing until elegibility. */ - WARN_ON_ONCE(!se->sched_delayed); - WARN_ON_ONCE(!se->on_rq); + SCHED_WARN_ON_ONCE(!se->sched_delayed); + SCHED_WARN_ON_ONCE(!se->on_rq); if (update_entity_lag(cfs_rq, se)) { cfs_rq->nr_queued--; @@ -8032,8 +8032,8 @@ static int dequeue_entities(struct rq *rq, struct sched_entity *se, int flags) rq->next_balance = jiffies; if (p && task_delayed) { - WARN_ON_ONCE(!task_sleep); - WARN_ON_ONCE(p->on_rq != 1); + SCHED_WARN_ON_ONCE(!task_sleep); + SCHED_WARN_ON_ONCE(p->on_rq != 1); /* * Fix-up what block_task() skipped. @@ -9709,7 +9709,7 @@ static void set_cpus_allowed_fair(struct task_struct *p, struct affinity_context static void set_next_buddy(struct sched_entity *se) { for_each_sched_entity(se) { - if (WARN_ON_ONCE(!se->on_rq)) + if (SCHED_WARN_ON_ONCE(!se->on_rq)) return; if (se_is_idle(se)) return; @@ -9756,7 +9756,7 @@ preempt_sync(struct rq *rq, int wake_flags, * WF_SYNC without WF_TTWU is not expected so warn if it happens even * though it is likely harmless. */ - WARN_ON_ONCE(!(wake_flags & WF_TTWU)); + SCHED_WARN_ON_ONCE(!(wake_flags & WF_TTWU)); threshold = sysctl_sched_migration_cost; delta = rq_clock_task(rq) - se->exec_start; @@ -9828,7 +9828,7 @@ static void wakeup_preempt_fair(struct rq *rq, struct task_struct *p, int wake_f return; find_matching_se(&se, &pse); - WARN_ON_ONCE(!pse); + SCHED_WARN_ON_ONCE(!pse); cse_is_idle = se_is_idle(se); pse_is_idle = se_is_idle(pse); @@ -10861,8 +10861,8 @@ static void detach_task(struct task_struct *p, struct lb_env *env) schedstat_inc(p->stats.nr_forced_migrations); } - WARN_ON(task_current(env->src_rq, p)); - WARN_ON(task_current_donor(env->src_rq, p)); + SCHED_WARN_ON(task_current(env->src_rq, p)); + SCHED_WARN_ON(task_current_donor(env->src_rq, p)); deactivate_task(env->src_rq, p, DEQUEUE_NOCLOCK); set_task_cpu(p, env->dst_cpu); @@ -13334,7 +13334,7 @@ static int sched_balance_rq(int this_cpu, struct rq *this_rq, goto out_balanced; } - WARN_ON_ONCE(busiest == env.dst_rq); + SCHED_WARN_ON_ONCE(busiest == env.dst_rq); update_lb_imbalance_stat(&env, sd, idle); @@ -13651,7 +13651,7 @@ static int active_load_balance_cpu_stop(void *data) * we need to fix it. Originally reported by * Bjorn Helgaas on a 128-CPU setup. */ - WARN_ON_ONCE(busiest_rq == target_rq); + SCHED_WARN_ON_ONCE(busiest_rq == target_rq); /* Search for an sd spanning us and the target CPU. */ rcu_read_lock(); @@ -14802,7 +14802,7 @@ bool cfs_prio_less(const struct task_struct *a, const struct task_struct *b, struct cfs_rq *cfs_rqb; s64 delta; - WARN_ON_ONCE(task_rq(b)->core != rq->core); + SCHED_WARN_ON_ONCE(task_rq(b)->core != rq->core); #ifdef CONFIG_FAIR_GROUP_SCHED /* @@ -15020,7 +15020,7 @@ static void switched_from_fair(struct rq *rq, struct task_struct *p) static void switched_to_fair(struct rq *rq, struct task_struct *p) { - WARN_ON_ONCE(p->se.sched_delayed); + SCHED_WARN_ON_ONCE(p->se.sched_delayed); attach_task_cfs_rq(p); @@ -15077,7 +15077,7 @@ static void set_next_task_fair(struct rq *rq, struct task_struct *p, bool first) if (!first) return; - WARN_ON_ONCE(se->sched_delayed); + SCHED_WARN_ON_ONCE(se->sched_delayed); if (hrtick_enabled_fair(rq)) hrtick_start_fair(rq, p); @@ -15311,7 +15311,7 @@ int sched_group_set_idle(struct task_group *tg, long idle) rq_lock_irqsave(rq, &rf); grp_cfs_rq->idle = idle; - if (WARN_ON_ONCE(was_idle == cfs_rq_is_idle(grp_cfs_rq))) + if (SCHED_WARN_ON_ONCE(was_idle == cfs_rq_is_idle(grp_cfs_rq))) goto next_cpu; idle_task_delta = grp_cfs_rq->h_nr_queued - -- 2.53.0-Meta