From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from PH8PR06CU001.outbound.protection.outlook.com (mail-westus3azon11012057.outbound.protection.outlook.com [40.107.209.57]) (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 941D040DFBD for ; Mon, 20 Apr 2026 05:49:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.209.57 ARC-Seal:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776664183; cv=fail; b=CUewcg4gXV4rYyp786JpTBGWJ3a0ztjPnITh980QMX7eP/fZgV8aVQw47UityRQoZ3g8d9wfiNlt+Sv51GGvSKg9AjlFRN0nyuFrcLj1gHbXCg4YR0hGkhYLmyDbtCuve3KhpQY+JhM3MQEhzEv0XBhfr853ae/tsjcvfbcscrI= ARC-Message-Signature:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776664183; c=relaxed/simple; bh=OGNYxox8FDLkyolxxmxRxGgxzT5znMnyqAVlI8NWKjM=; h=Message-ID:Date:MIME-Version:Subject:To:CC:References:From: In-Reply-To:Content-Type; b=cgvxxGstcEmQJNvs2eJBujfrzGhxUkFSywoZ++rUhNtnrxbQRex5NCNRv7Ydd6oRvFuqNUlIgsYBzsewDEAVJ/Ws3F4AeNg5rxswmMEC9ANCd/Emn+NHBMmSBp7tC65IEak+DmEkSLLcGVxym9yIjWuTghc60e9dhOJ6bM8W6kc= ARC-Authentication-Results:i=2; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com; spf=fail smtp.mailfrom=amd.com; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b=Cbn8mX7f; arc=fail smtp.client-ip=40.107.209.57 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=amd.com Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=amd.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amd.com header.i=@amd.com header.b="Cbn8mX7f" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=cf8uMP/9PlY1M0TB4abvgrV/Jfx9ehbD1IeswIZLqNOTTSf/RPMJhS6edh9EfftrjXteOH4HD6YiddTnTQJ4ecCU6IZ4NyROsv0L8PTCDCah058nwfNPu/VG1fvb5b6QA99PaBM6tNhjWSrHYUvHNA/rK1TTSGk8Ddv3EhSXQ9CEK06sReSHskAWKjQlNmfapCwYfP+q2gKseja7e9nqedGDBZW9vypBlvyR+QaQ4aEdAxpghkZjYWYwLl/ZPtWlhj/oVkksmDa1eZ8qDzKqP7aGoeiRXOlxyP39xWyEaRZ/2/hm1Uf6/Zkpm16kcwxdOkElp0zMtUB/EViVyK8XaQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=XhfguzYSfxlQa7gohrEeCXZHTp+D2mnb/FPygfB8HNk=; b=UtdDIw8kIMfOE+ztjJAI7J+VQF9u2M6A724UbUJDvQJS8BLKDeYzf7GAYeZ+15CUXYXyW9P9HIIb1NGxw6xzoQi5TwF1Zwv1GdqNnwTeRU7Q1nlVVk3DeLB7/5W2mOsTAaJ64E0Ww4Qr+Xb0t3ctCGb8v8bCQmEHIjbiJgPDeQJvQoKqUhQMUkctSKyNHzyD+P0DKSh9jCamwivmqqFcoeektJ3wAkVSsBU0oYfDKN9W8FWw9dljCb3HNEjNkoYBb0X9SfsPT1idtq0bgRaKFOYq0v1xeAiZA00tpHow62zBpeXiTYjYBeneatQ0op54V1PJnz6W/OqC1EiwlDntnw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=nvidia.com smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=XhfguzYSfxlQa7gohrEeCXZHTp+D2mnb/FPygfB8HNk=; b=Cbn8mX7fIOKAK70dAmqgHl74DLXNmJ7TqspDK0m48rJWFUITH3hRdR/hI8EPYWSrAXaas3TqB0ghCGueWaDkgjWctCx3W7YwJ8hntvckA/TD86jZq98sx+TvcLDb0ZHtikVXnPrkjKzuYw560XKRRmuQp1gKrQsTqPRKlIPu1eQ= Received: from SJ0P220CA0001.NAMP220.PROD.OUTLOOK.COM (2603:10b6:a03:41b::7) by DM6PR12MB4089.namprd12.prod.outlook.com (2603:10b6:5:213::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9846.8; Mon, 20 Apr 2026 05:49:35 +0000 Received: from BY1PEPF0001AE1B.namprd04.prod.outlook.com (2603:10b6:a03:41b:cafe::a3) by SJ0P220CA0001.outlook.office365.com (2603:10b6:a03:41b::7) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.20.9791.48 via Frontend Transport; Mon, 20 Apr 2026 05:49:35 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=satlexmb08.amd.com; pr=C Received: from satlexmb08.amd.com (165.204.84.17) by BY1PEPF0001AE1B.mail.protection.outlook.com (10.167.242.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9791.48 via Frontend Transport; Mon, 20 Apr 2026 05:49:34 +0000 Received: from Satlexmb09.amd.com (10.181.42.218) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Mon, 20 Apr 2026 00:49:32 -0500 Received: from satlexmb08.amd.com (10.181.42.217) by satlexmb09.amd.com (10.181.42.218) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.17; Sun, 19 Apr 2026 22:49:32 -0700 Received: from [10.136.34.119] (10.180.168.240) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server id 15.2.2562.17 via Frontend Transport; Mon, 20 Apr 2026 00:49:28 -0500 Message-ID: <7313ba07-7b87-447c-9c48-2f6b2b53ac94@amd.com> Date: Mon, 20 Apr 2026 11:19:27 +0530 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH 1/2] sched/fair: Prefer fully-idle SMT cores in asym-capacity idle selection To: Andrea Righi , Dietmar Eggemann CC: Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Steven Rostedt , "Ben Segall" , Mel Gorman , Valentin Schneider , Christian Loehle , Koba Ko , Felix Abecassis , Balbir Singh , Shrikanth Hegde , References: <20260403053654.1559142-1-arighi@nvidia.com> <20260403053654.1559142-2-arighi@nvidia.com> <64fe32e0-d428-42bb-beb4-2656d8781b0f@arm.com> Content-Language: en-US From: K Prateek Nayak In-Reply-To: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BY1PEPF0001AE1B:EE_|DM6PR12MB4089:EE_ X-MS-Office365-Filtering-Correlation-Id: cec1f8d3-fef3-4f57-3830-08de9ea09a14 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|7416014|1800799024|82310400026|36860700016|18002099003|22082099003|56012099003; X-Microsoft-Antispam-Message-Info: YEbdolL/Eg36bn3y/zp0Ruw7HLgErMQuCdTjci/RkFfDlp3RJToiPdkCdx6Rl4DDlZJz+SCOE0+NTDPl1rpm2e8RRPqdtpGoJ6neC2Kmv0HMuR1OJ/gUqVmQ0rgbx2m1Q+6vpHB8ILFxVTOavJ6StuKe9hS+V1WDYU8glTHiHSkr1ZHswIJwTSJFrh5LSv/5sOQYt+TE/aHBzXwRK3wrGbceoN4VBcE2eprpozk/yt/ZISSxMu5MGjXBVR6ALDCMeg4mDmh/+RiVjfd7LzeIk+VQUe9ruLuM5vSl7mh9eXkQruPxh6RYhCVuGMRO8lgCkO2YVJRV/xzW14jWVpOpQUdklDhNPDu/raDxuRKFXn1R2TrgaMhare6FFPfBgTWDSCKoCyV29wW9H4h8Dnj1bmKj8+fTLHGaE74egH4wASU5vnqTt1LqbRLmHIrZUFgWcnhMsUwh/CuSmaaX3YbkvwqsV7Xpn5kXXE5mqOqqwo3TlvA+wa9d7zxjaDwRZqLDQuvCmvEU9XIR6Vj/pg3mvwoTC9hocYE6v7tP3De8CHO+3DvEIKZ0jKhF/16wHI3zUAEht4JdZR5A485IdeIBqWwlAhOj1nj0T97bNBSyifrbQZqP7MtbWc1lBhy762Y7ZMs/UsnX4mQEi3UTabg6mwBClS/8alAnRqN0fnCMO9dHfkfCSjiTYI7rmNVFzjqw0IzsvZvYav3zLyqy+/58UxamQdCKwIe7gQ1D0AzTyShfjarvn9deUnoFqTXBzp9Flhb1LjLAlDy76+ZtyrmABw== X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:satlexmb08.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230040)(376014)(7416014)(1800799024)(82310400026)(36860700016)(18002099003)(22082099003)(56012099003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: uEYVj+Y/e+K9IYMEX2t987D4RtGpZYiZzlyKU32W//eyDP7lhHFnqzL3eCkaHB7v3XnFYydc5pA5wpVEBEhevNNhdmbg22uYeaYb88cxn6PMaNbSn3/9gZDFu8F8olnoo4JrZl51pcxoejA9zppYB/NQjhtH7Hx22o0QHRbHnYNkqflkI20lRn9gZBYLFVB9g7NHJIvHt8E65erW5F2gxFUiA37UfPHAtpxdMnUWYvFuRSbVp4Wwg1PWgrvnI5i1SmS3eGZbptuv9832SFCvikhmZxbBohmsAp5jpKxYilMvyswTk9xaww11d0piLVAow4iPRLMO2J7OmL+XsgfmE+fsbp9lQxfUfh4qB2sjpMZ19Fsqlr6U67ucBPf+BI2E9MwCM49yEsyFSoYdwudE5TKMiv2eU+Uhm0MkxGnDE7CL6kmIidtOWHYX3O1edgmC X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Apr 2026 05:49:34.8826 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: cec1f8d3-fef3-4f57-3830-08de9ea09a14 X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[satlexmb08.amd.com] X-MS-Exchange-CrossTenant-AuthSource: BY1PEPF0001AE1B.namprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4089 Hello Andrea, On 4/18/2026 1:54 PM, Andrea Righi wrote: >>> @@ -7774,6 +7774,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool >>> static int >>> select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target) >>> { >>> + bool prefers_idle_core = sched_smt_active() && test_idle_cores(target); >> >> Somehow I miss a: >> >> if (prefers_idle_core) >> set_idle_cores(target, false) >> >> The one in select_idle_sibling() -> select_idle_cpu() isn't executed >> anymore in with ASYM_CPUCAPACITY. >> > > Right, we need to add this as also pointed by Vincent. > >> >> Another thing is that sic() iterates over CPUs sd_asym_cpucapacity >> whereas the idle core thing lives in sd_llc/sd_llc_shared. Both sd's are >> probably th same on your system. > > Hm... they're the same on my machine, but if they're different, clearing > has_idle_cores here is not right and it might lead to false positives. We should > only clear it only when both domains span the same CPUs (or just check if > sd_asym_cpucapacity and sd_llc are the same). > > However, if they're not the same, I'm not sure exactly what we should do... > maybe ignore has_idle_cores and always do the scan for now? With your changes, only two places actually care about test_idle_cores(): - select_idle_capacity() - select_idle_cpu() If we go into select_idle_capacity(), we don't do select_idle_cpu() so the two paths are mutually exclusive. In nohz_balancer_kick(), if we find, sd_asym_cpucapacity, we simply don't care about the sd_llc_shared->nr_busy_cpus during balancing so that begs the question if we can simply track idle_cores at sd_asym_cpucapacity for these systems? Following is only build tested for now but I'll try to spoof asym cpucapacity on my system and check if it holds up or not: (On top of tip:sched/core at sched-core-2026-04-13 + this series) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 78f2d2c4e24f..509146c486ac 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7913,7 +7913,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_rq_mask); int i, cpu, idle_cpu = -1, nr = INT_MAX; - if (sched_feat(SIS_UTIL)) { + if (sched_feat(SIS_UTIL) && sd->shared) { /* * Increment because !--nr is the condition to stop scan. * @@ -12856,7 +12856,8 @@ static void set_cpu_sd_state_busy(int cpu) goto unlock; sd->nohz_idle = 0; - atomic_inc(&sd->shared->nr_busy_cpus); + if (sd->shared) + atomic_inc(&sd->shared->nr_busy_cpus); unlock: rcu_read_unlock(); } @@ -12885,7 +12886,8 @@ static void set_cpu_sd_state_idle(int cpu) goto unlock; sd->nohz_idle = 1; - atomic_dec(&sd->shared->nr_busy_cpus); + if (sd->shared) + atomic_dec(&sd->shared->nr_busy_cpus); unlock: rcu_read_unlock(); } diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c index 5847b83d9d55..45b919b39c7d 100644 --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c @@ -680,19 +680,38 @@ static void update_top_cache_domain(int cpu) int id = cpu; int size = 1; + sd = lowest_flag_domain(cpu, SD_ASYM_CPUCAPACITY_FULL); + if (sd) { + /* + * If sd_asym_cpucapacity exists, + * the shared object should exist too. + */ + WARN_ON_ONCE(!sd->shared); + sds = sd->shared; + } + + rcu_assign_pointer(per_cpu(sd_asym_cpucapacity, cpu), sd); + sd = highest_flag_domain(cpu, SD_SHARE_LLC); if (sd) { id = cpumask_first(sched_domain_span(sd)); size = cpumask_weight(sched_domain_span(sd)); - /* If sd_llc exists, sd_llc_shared should exist too. */ - WARN_ON_ONCE(!sd->shared); - sds = sd->shared; + /* + * If sd_asym_cpucapacity doesn't exist, + * sd_llc_shared must have a sd->shared linked. + */ + if (!sds) { + WARN_ON_ONCE(!sd->shared); + sds = sd->shared; + } } rcu_assign_pointer(per_cpu(sd_llc, cpu), sd); per_cpu(sd_llc_size, cpu) = size; per_cpu(sd_llc_id, cpu) = id; + + /* TODO: Rename sd_llc_shared to fit the new role. */ rcu_assign_pointer(per_cpu(sd_llc_shared, cpu), sds); sd = lowest_flag_domain(cpu, SD_CLUSTER); @@ -711,9 +730,6 @@ static void update_top_cache_domain(int cpu) sd = highest_flag_domain(cpu, SD_ASYM_PACKING); rcu_assign_pointer(per_cpu(sd_asym_packing, cpu), sd); - - sd = lowest_flag_domain(cpu, SD_ASYM_CPUCAPACITY_FULL); - rcu_assign_pointer(per_cpu(sd_asym_cpucapacity, cpu), sd); } /* @@ -2650,6 +2666,15 @@ static void adjust_numa_imbalance(struct sched_domain *sd_llc) } } +static void init_sched_domain_shared(struct s_data *d, struct sched_domain *sd) +{ + int sd_id = cpumask_first(sched_domain_span(sd)); + + sd->shared = *per_cpu_ptr(d->sds, sd_id); + atomic_set(&sd->shared->nr_busy_cpus, sd->span_weight); + atomic_inc(&sd->shared->ref); +} + /* * Build sched domains for a given set of CPUs and attach the sched domains * to the individual CPUs @@ -2712,16 +2737,33 @@ build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *att if (!sd) continue; + /* + * In case of ASYM_CPUCAPACITY, attach sd->shared to + * sd_asym_cpucapacity for wakeup stat tracking. + * + * XXX: This assumes SD_ASYM_CPUCAPACITY_FULL domain + * always has more than one group else it is prone to + * degeneration. + */ + if (has_asym) { + while (sd && !(sd->flags & SD_ASYM_CPUCAPACITY_FULL)) + sd = sd->parent; + + init_sched_domain_shared(&d, sd); + } + /* First, find the topmost SD_SHARE_LLC domain */ + sd = *per_cpu_ptr(d.sd, i); while (sd->parent && (sd->parent->flags & SD_SHARE_LLC)) sd = sd->parent; if (sd->flags & SD_SHARE_LLC) { - int sd_id = cpumask_first(sched_domain_span(sd)); - - sd->shared = *per_cpu_ptr(d.sds, sd_id); - atomic_set(&sd->shared->nr_busy_cpus, sd->span_weight); - atomic_inc(&sd->shared->ref); + /* + * Initialize the sd->shared for SD_SHARE_LLC if + * SD_ASYM_CPUCAPACITY_FULL hasn't claimed it already. + */ + if (!has_asym) + init_sched_domain_shared(&d, sd); /* * In presence of higher domains, adjust the --- I still have one question: Can first SD_ASYM_CPUCAPACITY_FULL be set at a SD_NUMA? We'll need to deal with overlapping domains then but seems like it could be possible with weird cpusets :-( But in that case, do we even want to search CPUs outside the NUMA in select_idle_capacity()? I don't think anything stops this currently but I might be wrong. -- Thanks and Regards, Prateek