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 46015307AF0 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=1781144099; cv=none; b=mpvCkSNwxb/eDA3IBw4q1HhnRzOuLgyWu2v+6KSlAHFbB6S7hzlobPZ3JsiFd7K1XaaDK25ZFaF7vZNYibrvbl5bz9KK1L0Ih52HuP4FQxMjf+o0NxQSiuFetnpD1ANcHKe0X6Bsv3J/qy41lDCAtSrgpg4b7CF7MoFw0iR5bJI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781144099; c=relaxed/simple; bh=3xH6FmGNUd28Nw46CZikdkIMgxBQnsFZwM2yepnZnL0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GwY0JUQ0kzxjna2VOfL5sAyUqLEw+9jmtn76OurEnJkmXkqHk/LxndO9YWc4kMF3Kr0ktcy3LkIBf87owEyBwS5OOZ88k15P5N/1p90ICfDeXE4ve/nwyxx+mxyFRsvzjtWW4GjcFIrVd9KIqsOOkbbU51FWersvTPe0sTf47mM= 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=lc1j606s; 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="lc1j606s" 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=kdqeFZDB9LWG2joPws7tbH3LSfTL/lAffgc9ljBa3AA=; b=lc1j606sBdjFLOodybiqkedLdm QDZG6zhF35yduQqhXorGg6fniRwh2zn3RYhsSD+8Zv1XWPYov2kiePcshgXuoq4Cf4nRkPU0BReDJ 9XVP+hrCoChfWiS8cpcwvT6YYDB0p5rfK0dBsOYgHe8BmjFqLnXIFpAekYIZFUZeFcGsxoxG1QJyT bkHaTVWzhcA4+S/N9CSUQmzTsWqwG9LCdx/eyxAk/zjrD72vhtKdkSkzXkPM3lzvamvk93A9nrcD9 eef+Q/EuMSJZt7M71h0rFyneIcmNIkTBrXnN5xYirOdDoyBKqgkCh1aWKIPg9A6hZcMxqHgzDez1e /96+UGkA==; 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-0SVU; 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 4/9] sched/deadline: defer WARN console output under rq->lock Date: Wed, 10 Jun 2026 22:14:11 -0400 Message-ID: <20260611021416.910555-5-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/deadline.c | 72 ++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 5ccb06effea0..089ff8e56ebf 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -217,8 +217,8 @@ void __add_running_bw(u64 dl_bw, struct dl_rq *dl_rq) lockdep_assert_rq_held(rq_of_dl_rq(dl_rq)); dl_rq->running_bw += dl_bw; - WARN_ON_ONCE(dl_rq->running_bw < old); /* overflow */ - WARN_ON_ONCE(dl_rq->running_bw > dl_rq->this_bw); + SCHED_WARN_ON_ONCE(dl_rq->running_bw < old); /* overflow */ + SCHED_WARN_ON_ONCE(dl_rq->running_bw > dl_rq->this_bw); /* kick cpufreq (see the comment in kernel/sched/sched.h). */ cpufreq_update_util(rq_of_dl_rq(dl_rq), 0); } @@ -230,7 +230,7 @@ void __sub_running_bw(u64 dl_bw, struct dl_rq *dl_rq) lockdep_assert_rq_held(rq_of_dl_rq(dl_rq)); dl_rq->running_bw -= dl_bw; - WARN_ON_ONCE(dl_rq->running_bw > old); /* underflow */ + SCHED_WARN_ON_ONCE(dl_rq->running_bw > old); /* underflow */ if (dl_rq->running_bw > old) dl_rq->running_bw = 0; /* kick cpufreq (see the comment in kernel/sched/sched.h). */ @@ -244,7 +244,7 @@ void __add_rq_bw(u64 dl_bw, struct dl_rq *dl_rq) lockdep_assert_rq_held(rq_of_dl_rq(dl_rq)); dl_rq->this_bw += dl_bw; - WARN_ON_ONCE(dl_rq->this_bw < old); /* overflow */ + SCHED_WARN_ON_ONCE(dl_rq->this_bw < old); /* overflow */ } static inline @@ -254,10 +254,10 @@ void __sub_rq_bw(u64 dl_bw, struct dl_rq *dl_rq) lockdep_assert_rq_held(rq_of_dl_rq(dl_rq)); dl_rq->this_bw -= dl_bw; - WARN_ON_ONCE(dl_rq->this_bw > old); /* underflow */ + SCHED_WARN_ON_ONCE(dl_rq->this_bw > old); /* underflow */ if (dl_rq->this_bw > old) dl_rq->this_bw = 0; - WARN_ON_ONCE(dl_rq->running_bw > dl_rq->this_bw); + SCHED_WARN_ON_ONCE(dl_rq->running_bw > dl_rq->this_bw); } static inline @@ -335,7 +335,7 @@ void cancel_inactive_timer(struct sched_dl_entity *dl_se) static void dl_change_utilization(struct task_struct *p, u64 new_bw) { - WARN_ON_ONCE(p->dl.flags & SCHED_FLAG_SUGOV); + SCHED_WARN_ON_ONCE(p->dl.flags & SCHED_FLAG_SUGOV); if (task_on_rq_queued(p)) return; @@ -416,7 +416,7 @@ static void task_non_contending(struct sched_dl_entity *dl_se, bool dl_task) if (dl_entity_is_special(dl_se)) return; - WARN_ON(dl_se->dl_non_contending); + SCHED_WARN_ON(dl_se->dl_non_contending); zerolag_time = dl_se->deadline - div64_long((dl_se->runtime * dl_se->dl_period), @@ -582,7 +582,7 @@ static void enqueue_pushable_dl_task(struct rq *rq, struct task_struct *p) { struct rb_node *leftmost; - WARN_ON_ONCE(!RB_EMPTY_NODE(&p->pushable_dl_tasks)); + SCHED_WARN_ON_ONCE(!RB_EMPTY_NODE(&p->pushable_dl_tasks)); leftmost = rb_add_cached(&p->pushable_dl_tasks, &rq->dl.pushable_dl_tasks_root, @@ -664,7 +664,7 @@ static struct rq *dl_task_offline_migration(struct rq *rq, struct task_struct *p * Failed to find any suitable CPU. * The task will never come back! */ - WARN_ON_ONCE(dl_bandwidth_enabled()); + SCHED_WARN_ON_ONCE(dl_bandwidth_enabled()); /* * If admission control is disabled we @@ -756,8 +756,8 @@ static inline void setup_new_dl_entity(struct sched_dl_entity *dl_se) struct dl_rq *dl_rq = dl_rq_of_se(dl_se); struct rq *rq = rq_of_dl_rq(dl_rq); - WARN_ON(is_dl_boosted(dl_se)); - WARN_ON(dl_time_before(rq_clock(rq), dl_se->deadline)); + SCHED_WARN_ON(is_dl_boosted(dl_se)); + SCHED_WARN_ON(dl_time_before(rq_clock(rq), dl_se->deadline)); /* * We are racing with the deadline timer. So, do nothing because @@ -801,7 +801,7 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se) struct dl_rq *dl_rq = dl_rq_of_se(dl_se); struct rq *rq = rq_of_dl_rq(dl_rq); - WARN_ON_ONCE(pi_of(dl_se)->dl_runtime <= 0); + SCHED_WARN_ON_ONCE(pi_of(dl_se)->dl_runtime <= 0); /* * This could be the case for a !-dl task that is boosted. @@ -975,7 +975,7 @@ update_dl_revised_wakeup(struct sched_dl_entity *dl_se, struct rq *rq) * * See update_dl_entity() comments for further details. */ - WARN_ON(dl_time_before(dl_se->deadline, rq_clock(rq))); + SCHED_WARN_ON(dl_time_before(dl_se->deadline, rq_clock(rq))); dl_se->runtime = (dl_se->dl_density * laxity) >> BW_SHIFT; } @@ -1080,7 +1080,7 @@ static int start_dl_timer(struct sched_dl_entity *dl_se) * (current u > U). */ if (dl_se->dl_defer_armed) { - WARN_ON_ONCE(!dl_se->dl_throttled); + SCHED_WARN_ON_ONCE(!dl_se->dl_throttled); act = ns_to_ktime(dl_se->deadline - dl_se->runtime); } else { /* act = deadline - rel-deadline + period */ @@ -1451,7 +1451,7 @@ static void update_curr_dl_se(struct rq *rq, struct sched_dl_entity *dl_se, s64 /* * Non-servers would never get time accounted while throttled. */ - WARN_ON_ONCE(!dl_server(dl_se)); + SCHED_WARN_ON_ONCE(!dl_server(dl_se)); /* * While the server is marked idle, do not push out the @@ -1492,7 +1492,7 @@ static void update_curr_dl_se(struct rq *rq, struct sched_dl_entity *dl_se, s64 * and queue right away. Otherwise nothing might queue it. That's similar * to what enqueue_dl_entity() does on start_dl_timer==0. For now, just warn. */ - WARN_ON_ONCE(!start_dl_timer(dl_se)); + SCHED_WARN_ON_ONCE(!start_dl_timer(dl_se)); return; } @@ -1806,7 +1806,7 @@ void dl_server_start(struct sched_dl_entity *dl_se) */ rq->donor->sched_class->update_curr(rq); - if (WARN_ON_ONCE(!cpu_online(cpu_of(rq)))) + if (SCHED_WARN_ON_ONCE(!cpu_online(cpu_of(rq)))) return; trace_sched_dl_server_start_tp(dl_se, cpu_of(rq), dl_get_type(dl_se, rq)); @@ -1855,7 +1855,7 @@ void sched_init_dl_servers(void) dl_se = &rq->fair_server; - WARN_ON(dl_server(dl_se)); + SCHED_WARN_ON(dl_server(dl_se)); dl_server_apply_params(dl_se, runtime, period, 1); @@ -1866,7 +1866,7 @@ void sched_init_dl_servers(void) #ifdef CONFIG_SCHED_CLASS_EXT dl_se = &rq->ext_server; - WARN_ON(dl_server(dl_se)); + SCHED_WARN_ON(dl_server(dl_se)); dl_server_apply_params(dl_se, runtime, period, 1); @@ -2098,7 +2098,7 @@ int dl_server_swap_bw(struct sched_dl_entity *detach_se, struct dl_bw *dl_b; int cpus, ret; - WARN_ON_ONCE(attach_se->rq != rq); + SCHED_WARN_ON_ONCE(attach_se->rq != rq); scoped_guard (raw_spinlock, &dl_bw_of(cpu)->lock) { dl_b = dl_bw_of(cpu); @@ -2265,7 +2265,7 @@ void inc_dl_tasks(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq) static inline void dec_dl_tasks(struct sched_dl_entity *dl_se, struct dl_rq *dl_rq) { - WARN_ON(!dl_rq->dl_nr_running); + SCHED_WARN_ON(!dl_rq->dl_nr_running); dl_rq->dl_nr_running--; if (!dl_server(dl_se)) @@ -2357,7 +2357,7 @@ static void __enqueue_dl_entity(struct sched_dl_entity *dl_se) { struct dl_rq *dl_rq = dl_rq_of_se(dl_se); - WARN_ON_ONCE(!RB_EMPTY_NODE(&dl_se->rb_node)); + SCHED_WARN_ON_ONCE(!RB_EMPTY_NODE(&dl_se->rb_node)); rb_add_cached(&dl_se->rb_node, &dl_rq->root, __dl_less); @@ -2381,7 +2381,7 @@ static void __dequeue_dl_entity(struct sched_dl_entity *dl_se) static void enqueue_dl_entity(struct sched_dl_entity *dl_se, int flags) { - WARN_ON_ONCE(on_dl_rq(dl_se)); + SCHED_WARN_ON_ONCE(on_dl_rq(dl_se)); update_stats_enqueue_dl(dl_rq_of_se(dl_se), dl_se, flags); @@ -2782,7 +2782,7 @@ static void set_next_task_dl(struct rq *rq, struct task_struct *p, bool first) /* You can't push away the running task */ dequeue_pushable_dl_task(rq, p); - WARN_ON_ONCE(dl_rq->curr); + SCHED_WARN_ON_ONCE(dl_rq->curr); dl_rq->curr = dl_se; if (!first) @@ -2822,7 +2822,7 @@ static struct task_struct *__pick_task_dl(struct rq *rq, struct rq_flags *rf) return NULL; dl_se = pick_next_dl_entity(dl_rq); - WARN_ON_ONCE(!dl_se); + SCHED_WARN_ON_ONCE(!dl_se); if (dl_server(dl_se)) { p = dl_se->server_pick_task(dl_se, rf); @@ -2855,7 +2855,7 @@ static void put_prev_task_dl(struct rq *rq, struct task_struct *p, struct task_s update_dl_rq_load_avg(rq_clock_pelt(rq), rq, 1); - WARN_ON_ONCE(dl_rq->curr != dl_se); + SCHED_WARN_ON_ONCE(dl_rq->curr != dl_se); dl_rq->curr = NULL; if (task_is_blocked(p)) @@ -3037,12 +3037,12 @@ static struct task_struct *pick_next_pushable_dl_task(struct rq *rq) if (!p) return NULL; - WARN_ON_ONCE(rq->cpu != task_cpu(p)); - WARN_ON_ONCE(task_current(rq, p)); - WARN_ON_ONCE(p->nr_cpus_allowed <= 1); + SCHED_WARN_ON_ONCE(rq->cpu != task_cpu(p)); + SCHED_WARN_ON_ONCE(task_current(rq, p)); + SCHED_WARN_ON_ONCE(p->nr_cpus_allowed <= 1); - WARN_ON_ONCE(!task_on_rq_queued(p)); - WARN_ON_ONCE(!dl_task(p)); + SCHED_WARN_ON_ONCE(!task_on_rq_queued(p)); + SCHED_WARN_ON_ONCE(!dl_task(p)); return p; } @@ -3158,7 +3158,7 @@ static int push_dl_task(struct rq *rq) if (is_migration_disabled(next_task)) return 0; - if (WARN_ON(next_task == rq->curr)) + if (SCHED_WARN_ON(next_task == rq->curr)) return 0; /* We might release rq lock */ @@ -3264,8 +3264,8 @@ static void pull_dl_task(struct rq *this_rq) */ if (p && dl_time_before(p->dl.deadline, dmin) && dl_task_is_earliest_deadline(p, this_rq)) { - WARN_ON(p == src_rq->curr); - WARN_ON(!task_on_rq_queued(p)); + SCHED_WARN_ON(p == src_rq->curr); + SCHED_WARN_ON(!task_on_rq_queued(p)); /* * Then we pull iff p has actually an earlier @@ -3324,7 +3324,7 @@ static void set_cpus_allowed_dl(struct task_struct *p, struct root_domain *src_rd; struct rq *rq; - WARN_ON_ONCE(!dl_task(p)); + SCHED_WARN_ON_ONCE(!dl_task(p)); rq = task_rq(p); src_rd = rq->rd; -- 2.53.0-Meta