From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f177.google.com (mail-pf1-f177.google.com [209.85.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B53B52EEE63 for ; Fri, 26 Jun 2026 03:25:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.177 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782444358; cv=none; b=PWRqIgjGa3kutc0s4Lz8LzP4c0TZZqgBsLrWzYHhKM0jUSkezlf03F5qOd/T0jKDqi0SRKNFIh5XEHMXTu2/2hF4NyhkebuX+1+Pt1fhsEfoCeD6cBAI49oocT1mCkiD3CAgZjpKlFstSUCPoD09Yk6tH6VfjGE8aJ1HgA27oHM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782444358; c=relaxed/simple; bh=z0YzAuG9sJxnAci3pnJ2Ldx5xw9Hlw0nYfLTYHNbL14=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=cgKlNG/ISGEIbep1Citr7sYamMn6S73o5ciBKC3HlGvNxCOt9tgE2dYkN0DZC0rQsL6a0hPidZXzrNbLPiJWPYslu3zJGZRFJGKjWkKC7emaoKnnlhjwjUqFbxcW5MhDqVF0wb939+ezTxD7qvY71+R7wCNkEfQ8abhtGfKSBEs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=fMfz2YCQ; arc=none smtp.client-ip=209.85.210.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fMfz2YCQ" Received: by mail-pf1-f177.google.com with SMTP id d2e1a72fcca58-845b6d9bf39so261873b3a.1 for ; Thu, 25 Jun 2026 20:25:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782444356; x=1783049156; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=3Tm4gZsAXl0H+ne3vFk75orXTLVFKLcc7769BzoPW80=; b=fMfz2YCQlleGMgthxbvsi5r1BGC2ZFTtEU4ssOk/mlceYYLlkj+H+U8b0Hb1fysmUv jMhwn3BNJpStgYvLl2tkSOz4kr2XVBkvzVGhBtELnSmPMlg4JGALUdoAzMhEVz3j6SD9 aRRbSrsV1OEtWLsYHAes7SNPXhQS+Kt8nwX5kzjKeWQIf5/Bb6av59bZqemw03elyNTl sW+gdH/FZhs2xpqPe1PP5hpq30C/B9MoYlryzZn6ZtI/1aUbagfC2kQEz4Mioef23i1b BzicKzeMQORqDYCIgWIqtRy3MPPleLuGEwB3/4BugVqRqgTQnCvDpryMhxYWDoqAolYR Hqng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782444356; x=1783049156; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=3Tm4gZsAXl0H+ne3vFk75orXTLVFKLcc7769BzoPW80=; b=XjxVI3mE+o2JeTCEw1ijYrQZfU0KmQ9Y+EedqgR8sRgZUFDHMelX2hPkidfZZx9yzX J1+JgPcI+cXQKrN6Mf0cxL+CkpqR0fcJC2MsbvRjJW4990g2leo0W3d1+10SNmPizewe JImUHBMZmjRi7sypksoIoyZt323GxmEWRp46iR1aZS0N8SUswMbHD2jO2HKSHL6J0h5E yikEX4c57tB0jLm7R4LLXehNZlYujcBofFKW47FEe6fwDg+k0lzycOyreGr3GXH2uzJu sNNxIC0zZE4lORq149O0GdRxcCezqH2Shk5oI28M9pI7oxShRqRaI/z/6BSjVD4bYaOj RAEQ== X-Forwarded-Encrypted: i=1; AHgh+RqdU9dF3uIB/jCYrb20eI/d8DNJ6BrLtrgQUfnussJUummKr4Pmp4OYzh9fw4K9aD4I0v9Ns9twNl6L0XI=@vger.kernel.org X-Gm-Message-State: AOJu0YzO7f2vN9JsAfxGouJbvOhQysMqdJWCE4rTzcqlLo2Q1oEpg+7t f//aS26QT3E55V/Vt42UjNhymLWdseebc3RS+jtvhO9RQn78kMUonQWR X-Gm-Gg: AfdE7cnRLeJ7kuTwDVCoQLaLR80o8p33eXj/R5AQVgfKqtYPgEZYMSrFVfiNkmZUTVM jc+DTveLKC6LqoS5jfuFBScFNAsYA5gM/GMEhgRfrm9reBfdGSoWdIVw3rGORBny3gvAZ4h9OhO yrFHlAs/1shetGVTEOSacFZb/qkocBiSLibxc5gHlOWJXzbevV9bzSi9OoETijL4cf4XY0cx5u+ OdKAjFrpJodnETp76XhrvsDQDFPFfI1x8cgiYngb8Tf/GEpbDJjokxpiyyHgMbgMe8uu0S38nuj 8zREcHiMCzIgx6vD8EFBlBM6JCnLFVTZyRTkTZKKS/tCYMSCtxF0uin1SmjIqqrKn8GoqAPOTtu bmFmaybtoQlTm/ix0K95UT5JkfLmfgbNyIQidyT9hW24jv01jPPDBl2jbHh/KXiMItxXBi8AAE8 HlCS/sk+gOLSrSNI57n0J/4qGINYXbo4Pxm747I0I= X-Received: by 2002:a05:6a00:b4f:b0:82c:7420:82bf with SMTP id d2e1a72fcca58-845b44f0316mr4375804b3a.19.1782444355859; Thu, 25 Jun 2026 20:25:55 -0700 (PDT) Received: from hz-pc.company.local ([210.184.73.204]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-845a3fedaefsm6612256b3a.23.2026.06.25.20.25.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 25 Jun 2026 20:25:55 -0700 (PDT) From: yangsonghua X-Google-Original-From: yangsonghua To: Ingo Molnar , Peter Zijlstra , K Prateek Nayak Cc: Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Valentin Schneider , linux-kernel@vger.kernel.org, yangsonghua Subject: [PATCH v2] sched/rt: Push RT tasks when preempted by a deadline task Date: Fri, 26 Jun 2026 11:23:26 +0800 Message-Id: <20260626032326.6581-1-yangsonghua@lixiang.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Commit 704069649b5b ("sched/core: Rework sched_class::wakeup_preempt() and rq_modified_*()") made wakeup_preempt_rt() callable for cross-class wakeups, leaving a "XXX If we're preempted by DL, queue a push?" comment with no implementation. When a SCHED_DEADLINE task preempts a running SCHED_FIFO/SCHED_RR task, the RT class's put_prev_task_rt() is the natural place to trigger a push: at that point the preempted task is (conditionally) added to pushable_tasks, and we have 'next' available to identify the reason for preemption. The earlier wakeup_preempt_rt() call site is too early: the running RT task has not yet been added to pushable_tasks, so rt_queue_push_tasks() would be a no-op for the common single-RT-task-per-CPU case. Guard the dl_task(next) check with a NULL test. put_prev_task_rt() is reachable with next == NULL when called via the bare put_prev_task() wrapper (sched.h), which always passes NULL: sched_change_begin() put_prev_task(rq, p) /* next = NULL */ put_prev_task_rt(rq, p, NULL) dl_task(NULL) -> NULL deref /* BUG in v1 */ The actual DL-preemption path goes through put_prev_set_next_task(), which supplies the real next task, so the NULL guard does not change the intended trigger condition. Regarding potentially unnecessary push/pull cycles for short-lived DL tasks: this is an inherent property of any asynchronous push mechanism. rt_queue_push_tasks() enqueues a balance callback rather than migrating synchronously, so by the time it fires the DL task may have already yielded; in that case the RT task may need to be pulled back. This trade-off is acceptable: leaving RT tasks stranded on a busy CPU while peer CPUs sit idle is worse than an occasional redundant migration. The same concern applies to the existing triggers of rt_queue_push_tasks() (e.g. after dequeue_task_rt), so this path is consistent with the established policy. Fix this by adding a dl_task(next) check in put_prev_task_rt(), guarded against NULL. This is intentionally placed outside and after the enqueue_pushable_task() condition, so that a push is triggered even when the preempted RT task is pinned (nr_cpus_allowed == 1) or blocked (proxy-exec): in those cases there may be other migratable RT tasks already sitting in pushable_tasks. The task_is_blocked() early-return is folded into the enqueue_pushable_task() condition to avoid inadvertently suppressing the new push logic. Note: this does not cover the DL-server case where a fair-class task running under DL bandwidth budget displaces an RT task; that is a separate concern. Signed-off-by: yangsonghua --- Changes in v2: - Guard dl_task(next) with a 'next != NULL' check to fix a NULL pointer dereference when put_prev_task_rt() is called from sched_change_begin() via the put_prev_task() wrapper, which always passes next = NULL. - Extend the commit message to explain the NULL call path and address the reviewer concern about unnecessary push/pull cycles for short-lived DL tasks. - Improve wakeup_preempt_rt() comment to explicitly point readers to put_prev_task_rt() where the DL push is now handled. kernel/sched/rt.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index e474c31d8fe6..ef8cdc4c25d2 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -1627,7 +1627,10 @@ static void wakeup_preempt_rt(struct rq *rq, struct task_struct *p, int flags) struct task_struct *donor = rq->donor; /* - * XXX If we're preempted by DL, queue a push? + * If the incoming task belongs to a higher-priority class (e.g. DL), + * we only handle same-class RT preemption here. The DL case is + * handled in put_prev_task_rt() once the current task has been + * added to pushable_tasks. */ if (p->sched_class != &rt_sched_class) return; @@ -1736,14 +1739,25 @@ static void put_prev_task_rt(struct rq *rq, struct task_struct *p, struct task_s update_rt_rq_load_avg(rq_clock_pelt(rq), rq, 1); - if (task_is_blocked(p)) - return; /* * The previous task needs to be made eligible for pushing - * if it is still active + * if it is still active and migratable. */ - if (on_rt_rq(&p->rt) && p->nr_cpus_allowed > 1) + if (!task_is_blocked(p) && on_rt_rq(&p->rt) && p->nr_cpus_allowed > 1) enqueue_pushable_task(rq, p); + + /* + * When a deadline task takes over this CPU, try to push any queued + * RT tasks to CPUs running lower-priority work. This is independent + * of whether p itself is pushable: even if p is pinned or blocked, + * there may be other migratable RT tasks already in pushable_tasks. + * + * next is NULL when called from put_prev_task() (e.g. sched_change_begin); + * guard accordingly. rt_queue_push_tasks() checks has_pushable_tasks() + * internally, so this is a no-op if nothing is queued. + */ + if (next && dl_task(next)) + rt_queue_push_tasks(rq); } /* Only try algorithms three times */ -- 2.34.1