Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp3343867pxv; Sun, 4 Jul 2021 16:06:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy3tJfszwylLNUzYWy+3ic4QsORUuME7gJ05CUAGXW341SclO4YwabPjTLTkg+SFPt5hjzx X-Received: by 2002:a92:b07:: with SMTP id b7mr7998340ilf.132.1625439977093; Sun, 04 Jul 2021 16:06:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625439977; cv=none; d=google.com; s=arc-20160816; b=ech4yOtUt6Dg8eCDFqCy8Z5pgV0kjfdCT3ufKuyl6FAJsmhjUUb/fqpBsirOrpaJEy d8lq2M+01qt6PZDkv+VFciXY5LfP7gvCY42iolxe9xYxyRkpwvjm7ICTxYqp9x4mTYW+ sW4OO4uw3zKxHsnL0uPix/eV62tcDvRUl8Vmph3LrnrnUCYpECGNWL07CVEw2k6kbhm3 oaynqZ/99oy/zSNQi4IB2ZloJMWzARf1882ikmOwEP2v/Hob01FYunPnCNaagJbm9KpP WoTBGt5GWS6fpGuL+jiYi0xMQrUWC3iAgUakDIvzOHiynZ4Fzfdjl/TspYFIDhTJS/c0 Gtmg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ISxV0z+ydoNYIBcjYR/AfK7Aa6ytYiVceuKs1h2KW7c=; b=Irvigy5zV/kcY13JQMF4QMcOhr613jPdDpLmC1Kb1/8NFWMwSSOKCnM1IDRP9TrNJt BlkFPw9HmGxMgJT25nEhH8XEpUTWJmCoHXy9ElCoxCHHOAJPd7CMWdqcRkKXVWMQn1TZ 93FgNJB/RnciO9Zf3s0BKXiAmQgXEXG0vH3Mz0jkK3wcIt/9/TXNv7o15F5f8zsC+tds pSk7u0UDxUF7lNKUAK6Nq5FheIq0ThCwPYGSIN/qBGOB7cdhjrSP0MBPLyTMgpN6fxws E9kiSUo2om5CbN0cVQ9NibfgN//VF9c1pzroD6GdZypmaZeX4kYf3GxDrzDaOXavRVgm YfRQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=YxL+V5Fh; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id l19si12003667jak.112.2021.07.04.16.06.05; Sun, 04 Jul 2021 16:06:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=YxL+V5Fh; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230137AbhGDXHt (ORCPT + 99 others); Sun, 4 Jul 2021 19:07:49 -0400 Received: from mail.kernel.org ([198.145.29.99]:45838 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230173AbhGDXHb (ORCPT ); Sun, 4 Jul 2021 19:07:31 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 4FADF6135D; Sun, 4 Jul 2021 23:04:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1625439895; bh=iz1M8G4Rkg9R4yfZGQBVGAgTrAORS7PKhFf9EU4R4GU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YxL+V5Fhh6z8tdLwH6hPD7wxhJn5GuF67zxJUFb9KYnSEA1AxrO+rRHPIbmRxpj1G zYFctpO7cjubFk9KSSBvT+A3NvdNQI/URlu9w3DXpBOy4WJl2bF8f30JQm67zqtIzn jgNVlKSQSKJKVb1CSsa9RhjS04rRIDZ3uHSWviLug76REa2kQp/xlzTB36RcC/vcAt u8aHaTK3c6O0ZOFWW1Ujew6bbGyn76MNHnjqi8hcpr6b8LdxBi/oCO1vH3/nGt1iYW 1w5+xjrjC8FkdVu3LrH4vt0BGJ5SLBsPdhfl70MiRqtSqe0eQNjfbQy8Iio3siDG5n dvivAlVuCbsiA== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Valentin Schneider , Peter Zijlstra , Sasha Levin Subject: [PATCH AUTOSEL 5.13 25/85] sched: Make the idle task quack like a per-CPU kthread Date: Sun, 4 Jul 2021 19:03:20 -0400 Message-Id: <20210704230420.1488358-25-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210704230420.1488358-1-sashal@kernel.org> References: <20210704230420.1488358-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Valentin Schneider [ Upstream commit 00b89fe0197f0c55a045775c11553c0cdb7082fe ] For all intents and purposes, the idle task is a per-CPU kthread. It isn't created via the same route as other pcpu kthreads however, and as a result it is missing a few bells and whistles: it fails kthread_is_per_cpu() and it doesn't have PF_NO_SETAFFINITY set. Fix the former by giving the idle task a kthread struct along with the KTHREAD_IS_PER_CPU flag. This requires some extra iffery as init_idle() call be called more than once on the same idle task. Signed-off-by: Valentin Schneider Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20210510151024.2448573-2-valentin.schneider@arm.com Signed-off-by: Sasha Levin --- include/linux/kthread.h | 2 ++ kernel/kthread.c | 30 ++++++++++++++++++------------ kernel/sched/core.c | 21 +++++++++++++++------ 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 2484ed97e72f..d9133d6db308 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -33,6 +33,8 @@ struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data), unsigned int cpu, const char *namefmt); +void set_kthread_struct(struct task_struct *p); + void kthread_set_per_cpu(struct task_struct *k, int cpu); bool kthread_is_per_cpu(struct task_struct *k); diff --git a/kernel/kthread.c b/kernel/kthread.c index 0fccf7d0c6a1..6e02094849d3 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -68,16 +68,6 @@ enum KTHREAD_BITS { KTHREAD_SHOULD_PARK, }; -static inline void set_kthread_struct(void *kthread) -{ - /* - * We abuse ->set_child_tid to avoid the new member and because it - * can't be wrongly copied by copy_process(). We also rely on fact - * that the caller can't exec, so PF_KTHREAD can't be cleared. - */ - current->set_child_tid = (__force void __user *)kthread; -} - static inline struct kthread *to_kthread(struct task_struct *k) { WARN_ON(!(k->flags & PF_KTHREAD)); @@ -103,6 +93,22 @@ static inline struct kthread *__to_kthread(struct task_struct *p) return kthread; } +void set_kthread_struct(struct task_struct *p) +{ + struct kthread *kthread; + + if (__to_kthread(p)) + return; + + kthread = kzalloc(sizeof(*kthread), GFP_KERNEL); + /* + * We abuse ->set_child_tid to avoid the new member and because it + * can't be wrongly copied by copy_process(). We also rely on fact + * that the caller can't exec, so PF_KTHREAD can't be cleared. + */ + p->set_child_tid = (__force void __user *)kthread; +} + void free_kthread_struct(struct task_struct *k) { struct kthread *kthread; @@ -272,8 +278,8 @@ static int kthread(void *_create) struct kthread *self; int ret; - self = kzalloc(sizeof(*self), GFP_KERNEL); - set_kthread_struct(self); + set_kthread_struct(current); + self = to_kthread(current); /* If user was SIGKILLed, I release the structure. */ done = xchg(&create->done, NULL); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 0a90d4d7663b..9724dd30ad44 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -7440,12 +7440,25 @@ void __init init_idle(struct task_struct *idle, int cpu) __sched_fork(0, idle); + /* + * The idle task doesn't need the kthread struct to function, but it + * is dressed up as a per-CPU kthread and thus needs to play the part + * if we want to avoid special-casing it in code that deals with per-CPU + * kthreads. + */ + set_kthread_struct(idle); + raw_spin_lock_irqsave(&idle->pi_lock, flags); raw_spin_lock(&rq->lock); idle->state = TASK_RUNNING; idle->se.exec_start = sched_clock(); - idle->flags |= PF_IDLE; + /* + * PF_KTHREAD should already be set at this point; regardless, make it + * look like a proper per-CPU kthread. + */ + idle->flags |= PF_IDLE | PF_KTHREAD | PF_NO_SETAFFINITY; + kthread_set_per_cpu(idle, cpu); scs_task_reset(idle); kasan_unpoison_task_stack(idle); @@ -7662,12 +7675,8 @@ static void balance_push(struct rq *rq) /* * Both the cpu-hotplug and stop task are in this case and are * required to complete the hotplug process. - * - * XXX: the idle task does not match kthread_is_per_cpu() due to - * histerical raisins. */ - if (rq->idle == push_task || - kthread_is_per_cpu(push_task) || + if (kthread_is_per_cpu(push_task) || is_migration_disabled(push_task)) { /* -- 2.30.2