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 448AF3043C9 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=1781144097; cv=none; b=EufrXWJeppBqDhvfGeQSpQ87KhyJ0AYDY2la/X2zo2K4nFf5pjj0gOE2kc51Izo/8MH/EcSVKDp6e8YcQiP4/d+pzROlkoin3oZqSWvkNRBqG9SgT1iwD2f7AK8A/9YmPXeZcFdwsofYQZvoJsjplKbNfyPY5NHICvxdO5WHj/o= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781144097; c=relaxed/simple; bh=0pu3QmZWlYH+/rOI7LkJRQ40DRF+/WXG6ls5Liak7HM=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=SfOjmsi+Esmp4QhFFIPj9irjO3vAvv85IblFZWUwCqwX/rGov94ThIaNKF3FkgB/ZnvaDLAURIwUIEr5lifVO9j5fEiyH9rNVn5GMjpgBnXi9+TI/zpq/w8j1x8pdgDhnfaQ4H1WOz4FuBQoTelP9/mCpyMG0uPbox/i8EFigCw= 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=Vwtaqp9U; 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="Vwtaqp9U" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=surriel.com ; s=mail; h=Content-Transfer-Encoding:MIME-Version: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: In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=KObTpnRrH66IjBeBFBnB8VZAO3VcQKgh8VcVk7yYcBc=; b=Vwtaqp9UM7slXAhqbx1dpvGNg3 W/D94jpGuBnPwTh7UcNjKPvQ4g5Ng0O2I8jbHpmzv5v3wR1B1Rp2jdJYSGFc+mtNO620UHfvgwWVg WgwAmdA/rK5iWpf+bVdB+rl+7tp9p/+YhTaPMXo9auTxwxqF04xFvQfBKgugJXwCYxh0lwT2n2V/5 aCR/Ig0W4GlXaDTIrZPF8ABZjdWZGu7gBdaqg/eU1YIzpjpv8agjpcA5sMn4TeSBhyPE4qUuwlwQA wouOo4x+MYsNJWRhkWiEzdvmbnDpb5giK7D5Kkh5flLE5SS7vtg5PVKk58z8ppwTw8TVkQYHQy8IX iM+Lr8iw==; 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-01Nr; 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 0/9] sched: make WARN_ON under rq->lock deadlock-safe (SCHED_WARN_ON) Date: Wed, 10 Jun 2026 22:14:07 -0400 Message-ID: <20260611021416.910555-1-riel@surriel.com> X-Mailer: git-send-email 2.54.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit A plain WARN_ON()/WARN_ON_ONCE()/WARN()/WARN_ONCE() emits at KERN_WARNING. On a machine with a legacy or boot console registered (e.g. console=ttyS0), vprintk_emit() takes the synchronous "legacy_direct" path: console_trylock_spinning() + console_unlock() -> up(&console_sem) -> wake_up_process() -> try_to_wake_up() which grabs the woken task's ->pi_lock and its rq->lock. Almost every WARN in the scheduling-class hot paths fires while the current CPU already holds an rq->lock or a ->pi_lock, so this re-enters the scheduler and can deadlock (recursively on rq->lock, or via the pi_lock/rq->lock order). The nbcon and klogd wakeups are deferred via irq_work and are safe; only the legacy console path is synchronous. This deadlock bit us when the WARN_ON_ONCE in __sum_w_vruntime_add() fired, but many other WARN instances in the scheduler code appear to be vulnerable to the exact same deadlock. The scheduler already works around this in a handful of spots by using printk_deferred() instead of printk(), but WARN_ON() has no such variant: it emits at KERN_WARNING, not LOGLEVEL_SCHED, so it is not deferred. Patch 1 adds SCHED_WARN_ON()/SCHED_WARN_ON_ONCE() and the SCHED_WARN()/ SCHED_WARN_ONCE() message-carrying forms, which behave exactly like their WARN*() counterparts but bracket the report in a printk_deferred section so the console output is handed to irq_work instead of being emitted synchronously. The bracket is entered only on the (cold) firing path, so the hot path cost is unchanged -- just the condition test. (printk_deferred toggles a per-CPU counter that must be balanced on one CPU, which is guaranteed because rq->lock/->pi_lock are raw_spinlock_t and disable preemption; a lockdep_assert_preemption_disabled() catches misuse and compiles away without CONFIG_PROVE_LOCKING.) Patches 2-9 convert, one file at a time (for bisectability), the WARN*() calls that execute under rq->lock or ->pi_lock. WARN sites in setup/teardown/sysfs/preemptible paths are left alone (they are not in the hazard class and SCHED_WARN_ON would trip the lockdep assert there). 1 sched: add SCHED_WARN_ON()/.../SCHED_WARN_ONCE() 2 sched/core (34 sites) 3 sched/fair (33) 4 sched/deadline (36) 5 sched/rt (17) 6 sched_ext (49) 7 sched/core_sched (3) 8 sched/deadline (cpudeadline.c) (3) 9 sched/rt (cpupri.c) (1) Not converted: two sites with mixed preemptible/locked callers (nohz_balance_exit_idle() in fair.c, next_task_group() in rt.c) are left as plain WARN_ON_ONCE() pending per-site analysis -- converting them blindly would risk a false lockdep_assert_preemption_disabled() on the preemptible caller path. Built (full bzImage, x86_64) on tip sched/core. Based on sched/core plus the EEVDF reweight vlag-clamp fix; the series itself is independent of that fix. Split up into one patch per .c file in kernel/sched to make things a little less unwieldy. Rik van Riel (9): sched: add SCHED_WARN_ON()/SCHED_WARN_ON_ONCE()/SCHED_WARN()/SCHED_WARN_ONCE() sched/core: defer WARN console output under rq->lock sched/fair: defer WARN console output under rq->lock sched/deadline: defer WARN console output under rq->lock sched/rt: defer WARN console output under rq->lock sched_ext: defer WARN console output under rq->lock sched/core_sched: defer WARN console output under rq->lock sched/deadline: defer WARN console output under rq->lock sched/rt: defer WARN console output under rq->lock kernel/sched/core.c | 68 +++++++++++++------------- kernel/sched/core_sched.c | 6 +-- kernel/sched/cpudeadline.c | 6 +-- kernel/sched/cpupri.c | 2 +- kernel/sched/deadline.c | 72 ++++++++++++++-------------- kernel/sched/ext.c | 98 +++++++++++++++++++------------------- kernel/sched/fair.c | 66 ++++++++++++------------- kernel/sched/rt.c | 34 ++++++------- kernel/sched/sched.h | 52 ++++++++++++++++++++ 9 files changed, 228 insertions(+), 176 deletions(-) base-commit: eaf710f74e602ea2fd517f798066d6988072f3ae -- 2.53.0-Meta