From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from PH8PR06CU001.outbound.protection.outlook.com (mail-westus3azon11012070.outbound.protection.outlook.com [40.107.209.70]) (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 CCC053E5577 for ; Fri, 17 Jul 2026 11:50:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=fail smtp.client-ip=40.107.209.70 ARC-Seal:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784289022; cv=fail; b=EZ3IQRN6Da2n2XoPg8ZCLD+2jrpi8WOf/ApbSEmgi563SGOmAKaB0CK7zn71OAW+84NNxegA7FHNYe9wOlQu8/wSe5VhVGwuYMlcD0EAMFMJNRid53Bqq7k60qwsAcEHflS8IF8lvu9FnWl1ItlR0/d83jOSkCtRkysJM9UkjBk= ARC-Message-Signature:i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784289022; c=relaxed/simple; bh=sh64VUxJ6D4wsB1zvNqzd8RK/kUKOJL16LpW/GDuYWI=; h=Message-ID:Date:MIME-Version:Subject:To:CC:References:From: In-Reply-To:Content-Type; b=mI9NYjx9OqgwRQS7YIZRs3d20nAi5x/Dn/ty8KfstbRDncnvUGMUGEVanAhX1zjaonChwv2jyGoRmrRC8ib0izWiF61YmzBCgQsMvmckzz0iLMyFNcvZDHwPo+dCHPADc0mplEtodcTk6G4xfWygFy3qkhdadfUmbOtQgMNL6TM= 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=IX1la4Cm; arc=fail smtp.client-ip=40.107.209.70 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="IX1la4Cm" ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=qK3WHMRH7W5sn0w49ywzbDx9H8h/p1dOx7mAwmd+KcuN5PPv9Q10jOjf4G3e3SJmGo4RuBND8Y+pnZmFaU+hihcCyAUaEWMsQ9kdzed3OLgOJ1kHRTYI3kf7VntzRKLdTHV6WmeDkRnLIk5t9TfoF6x2lbDjQhHA3g4lNxeabkF6mxM3TXhyRV4Q0fbKPYgykEeWp/zU49JY5OhXmJWCHRpFZ/Ad4BegM1WxfUWlCnkREyaOKXJYr811+HMIz16NLFr6mHNHmcV1FpsVmJytbR0Esp5+ey531XwPn24H3VKZ4hdLtaQAfiIE/feSpoe//rBjrbOnn0icpADiwyIN2A== 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=iaL49w9uk7kDCOGJiKTRlVyYJlDX31P6rW/X0z21QZk=; b=eff7tzLvsuAtATnuFNPxj/mKdMqADPa+5MyVss3pT9F9SFUIXV7xcfqHOvaHrsjla0DyKxCB3qW2JLVTH842ma/f8SzxgwZA1U65AP6f9J9rmEZ322HpFfIiia3hR94PAKCQ4FqAdP3tGpPj4DFcfosyREH+muxHjKnuP2QuguUsXRrLMiJFY1Rfw6qL+6V/qmJCL+92bUHsqa87l4qf6QNaIOGC1Glu035Udm1WJY8levksKi9DGVtoTAT1cAXJpx1NKQGp3hsQsStQelF9LzSNgm/AgswjF9dwSV7v63TQ16rRpnny5iJpM+u/yvu8iPdJzvr1X5bz/eUzujynsg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=gmail.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=iaL49w9uk7kDCOGJiKTRlVyYJlDX31P6rW/X0z21QZk=; b=IX1la4Cm/juNsbsZdKgwAyRTV+ieqHjzZShu0IFDiofXZIY4U9ja6T01lPZwtMwK7YTF9rl6fI7NqYcm2vpB+gGP2I0TdtknA6z4HItn/OCiQ8+fWqyW9KS5gwEM/puQOjFSZ1p4wdygrNXLoPtQwrmG9V6ib3dX5pwtKSm2BHU= Received: from SJ0PR13CA0086.namprd13.prod.outlook.com (2603:10b6:a03:2c4::31) by LV8PR12MB9620.namprd12.prod.outlook.com (2603:10b6:408:2a1::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.202.18; Fri, 17 Jul 2026 11:50:13 +0000 Received: from SJ1PEPF0000231B.namprd03.prod.outlook.com (2603:10b6:a03:2c4:cafe::53) by SJ0PR13CA0086.outlook.office365.com (2603:10b6:a03:2c4::31) with Microsoft SMTP Server (version=TLS1_3, cipher=TLS_AES_256_GCM_SHA384) id 15.21.245.5 via Frontend Transport; Fri, 17 Jul 2026 11:50:12 +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 SJ1PEPF0000231B.mail.protection.outlook.com (10.167.242.232) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.21.245.5 via Frontend Transport; Fri, 17 Jul 2026 11:50:11 +0000 Received: from satlexmb08.amd.com (10.181.42.217) 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.41; Fri, 17 Jul 2026 06:50:09 -0500 Received: from [10.136.35.249] (10.180.168.240) by satlexmb08.amd.com (10.181.42.217) with Microsoft SMTP Server id 15.2.2562.41 via Frontend Transport; Fri, 17 Jul 2026 06:50:06 -0500 Message-ID: <3ab1c896-7b33-4d39-85cd-3ab78f3a5bf8@amd.com> Date: Fri, 17 Jul 2026 17:20:00 +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 v3] sched/proxy_exec: Detect cycles in proxy walks To: "zhidao su (Xiaomi)" , John Stultz CC: Peter Zijlstra , Ingo Molnar , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Valentin Schneider , References: <20260714152220.4046736-1-soolaugust@gmail.com> <20260717105259.747783-1-soolaugust@gmail.com> Content-Language: en-US From: K Prateek Nayak In-Reply-To: <20260717105259.747783-1-soolaugust@gmail.com> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ1PEPF0000231B:EE_|LV8PR12MB9620:EE_ X-MS-Office365-Filtering-Correlation-Id: 575c1a8f-c677-4756-aa38-08dee3f98f1b X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|7416014|376014|82310400026|30052699003|36860700016|23010399003|1800799024|22082099003|18002099003|10067099003|56012099006|4143699003|11063799006; X-Microsoft-Antispam-Message-Info: lYRS/41KmIWkTv64AHP/sapFw7jg8YmUMBj3DWGprksA51e0tnyL3GduQ+ggofiyRpuFHIEtv8TMrgS0QuDN/TAesgQYaM5jH6AsT6gwxsR0hnLsp4uv71I+60WfZ3wz+es2tMYYYNb8QFiJle1e8Wh7eHUcNU0QYLuLzcjB53E+Qji8G+qRSGsSI9QnPDheoh11tQswRd0xuXn1OmDpYcoqDucJZP7moWgukukIyrSWsCfe6pyj8Q1eF4EOaFvO/GHsyVFIHxIbdhzSC91hwCOJPVsovzfdCjtbs034yHQAAtP35mY/9q7l4A9XAkQz35otevtLMTqxyGASp3R8aiFU/tTX1mfDPNMP1ws+8p9b/cJ4hCuUKsraFKxMRj/t2oD2pTR4exO8LTDMsO3IcBskqk/vzv3wP6DDuaA4Am2mLzQugXES+pyQvSrSIAetXSAn/vBNAdBOEGRhT44mDTwxYiwszhmRYSZB6PUuc2rKZEvtQ2xFoNkemQ3fQdRII4ISGt5+ncWCXYQvkXyC/kc/VEUgZEJafbSBzHSZ6WrEZkp2oWQmAYTfwnBHbsB9vYn2Ovv3mFomMj5kXymhn1rC3ewARXosGMw2Hj7K8G010z00sRPuf7AYkxDGjQJg439b/Sjs7QAe9b5GDCZ86ne6XaTD9QUa2mA5/Rr0VU6DJ0CQ2M3Z613H1eur8anrRXuFr3IurhhylX8LaosUvw== 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)(7416014)(376014)(82310400026)(30052699003)(36860700016)(23010399003)(1800799024)(22082099003)(18002099003)(10067099003)(56012099006)(4143699003)(11063799006);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: bBvnZ7ZRXROI291mSUKQL3EK0wCvSJntqOCHdlHFghvvGg1Yd4KBpMdzLHf2/TSitw425rJPJFo1LAcsGohYU43csO4ocMLFpDS+/eGH8vZsxfKAJlKFETpR6sgzmtfvJIjm7mAgwJYm7V4mT43dn8CTr2xjOPdarj1gWoX1iz6xexJi4O19HDGuNq6NkCl8WDwO4NTW/QqfA2LZNN8CyXR15ya5kTVXzsr7H92lqOu6pyXJvZZ8ypeMZ0Tw69EqlfliOCQgShFQvnAg0nOQ4wAn02dYmitwXsO+FHSQsF9tvLsEmvh772pTEXyk6+M5pov05Gmd6sYg3SMJngjKEB5FtNs5EnuqD9EDZDSmNyGbRbaTJ2tQgXe+OLuTSHs8XDEVxMIXjAX1k1mSoaNmF9oX1YBxEDF3vzrQLvMiWDPMLsPKloQIJeaM9kAI1Tcn X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2026 11:50:11.9492 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 575c1a8f-c677-4756-aa38-08dee3f98f1b 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: SJ1PEPF0000231B.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV8PR12MB9620 Hello Zhidao, On 7/17/2026 4:22 PM, zhidao su (Xiaomi) wrote: > find_proxy_task() can keep walking the same blocked_on chain if the chain > contains a cycle. This happens with a simple A->B->A mutex deadlock under > proxy execution, and can leave the CPU spinning in __schedule() with the rq > lock held. > > Mark each task visited during one proxy walk with the rq's pick sequence. > If the walk sees the same task again in the same pick, break the cycle by > clearing the blocked_on state at the detection point and deactivating that > task. > > Clear the marker when proxy execution migrates a blocked task, so a later > walk on another CPU cannot match stale state. > > Tested with a PE cycle reproducer in virtme-ng: > > buggy kernel: vng timed out without returning > fixed kernel: WARN_ONCE "sched/pe: deadlock cycle detected" > > Signed-off-by: zhidao su (Xiaomi) > --- > Changes since v2: > - Drop the proxy-chain depth limit. > - Detect cycles anywhere in the proxy walk, not only cycles back to the > original donor. > - Use a separate per-pick marker instead of overloading blocked_donor. > - Clear the marker on proxy-exec blocked-task migration. > > include/linux/sched.h | 4 ++++ > kernel/fork.c | 4 ++++ > kernel/sched/core.c | 34 ++++++++++++++++++++++++++++++++-- > kernel/sched/sched.h | 1 + > 4 files changed, 41 insertions(+), 2 deletions(-) > > diff --git a/include/linux/sched.h b/include/linux/sched.h > index 968b18a7f4702..b83a4e775d736 100644 > --- a/include/linux/sched.h > +++ b/include/linux/sched.h > @@ -1256,6 +1256,10 @@ struct task_struct { > * under preempt_disable(). > */ > struct task_struct *blocked_donor; > +#ifdef CONFIG_SCHED_PROXY_EXEC > + int proxy_pick_cpu; This adds 8-bytes to task_struct for not much benefit. I think resetting proxy_pick_seq on migration / enqueue is much simpler than tracking 2 things. Not to mention you need to write to "proxy_pick_cpu" at every iteration and compare it too. > + u64 proxy_pick_seq; /* find_proxy_task() seq */ > +#endif > > #ifdef CONFIG_DETECT_HUNG_TASK_BLOCKER > /* > diff --git a/kernel/fork.c b/kernel/fork.c > index 13e38e89a1f30..2219cce602c62 100644 > --- a/kernel/fork.c > +++ b/kernel/fork.c > @@ -2242,6 +2242,10 @@ __latent_entropy struct task_struct *copy_process( > > p->blocked_on = NULL; /* not blocked yet */ > p->blocked_donor = NULL; /* nobody is boosting p yet */ > +#ifdef CONFIG_SCHED_PROXY_EXEC > + p->proxy_pick_cpu = -1; > + p->proxy_pick_seq = 0; It should be okay to inherit these values from parent. The task still needs to be placed after the fork which grabs the rq_lock and next pick would increment the seq number anyways. > +#endif > > #ifdef CONFIG_BCACHE > p->sequential_io = 0; > diff --git a/kernel/sched/core.c b/kernel/sched/core.c > index 2e7cde033a319..3db4e6c2b786a 100644 > --- a/kernel/sched/core.c > +++ b/kernel/sched/core.c > @@ -6724,6 +6724,7 @@ static bool try_to_block_task(struct rq *rq, struct task_struct *p, > } > > #ifdef CONFIG_SCHED_PROXY_EXEC > + > static inline void proxy_set_task_cpu(struct task_struct *p, int cpu) > { > unsigned int wake_cpu; > @@ -6830,6 +6831,10 @@ static void proxy_migrate_task(struct rq *rq, struct rq_flags *rf, > > deactivate_task(rq, p, DEQUEUE_NOCLOCK); > proxy_set_task_cpu(p, target_cpu); > +#ifdef CONFIG_SCHED_PROXY_EXEC > + WRITE_ONCE(p->proxy_pick_cpu, -1); > + WRITE_ONCE(p->proxy_pick_seq, 0); > +#endif > > proxy_release_rq_lock(rq, rf); > > @@ -6839,14 +6844,14 @@ static void proxy_migrate_task(struct rq *rq, struct rq_flags *rf, > } > > /* > - * Find runnable lock owner to proxy for mutex blocked donor > + * Find runnable lock owner to proxy for a blocked donor > * > * Follow the blocked-on relation: > * > * ,-> task > * | | blocked-on > * | v > - * blocked_donor | mutex > + * blocked_donor | blocking primitive > * | | owner > * | v > * `-- task > @@ -6874,6 +6879,10 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf) > struct task_struct *p; > int owner_cpu; > > + rq->proxy_pick_seq++; > + if (unlikely(!rq->proxy_pick_seq)) > + rq->proxy_pick_seq++; Can't we simply initialize "rq->proxy_pick_seq" to 1 in sched_init()? I don't think we need to worry about a u64 wraparound. > + > /* Follow blocked_on chain. */ > for (p = donor; p->is_blocked; p = owner) { > /* if its PROXY_WAKING, do return migration or run if current */ > @@ -6905,6 +6914,16 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf) > return NULL; > } > > + if (READ_ONCE(p->proxy_pick_cpu) == this_cpu && > + READ_ONCE(p->proxy_pick_seq) == rq->proxy_pick_seq) { > + WARN_ONCE(1, "sched/pe: deadlock cycle detected, pid %d\n", > + p->pid); > + __clear_task_blocked_on(p, NULL); > + goto deactivate; > + } > + WRITE_ONCE(p->proxy_pick_cpu, this_cpu); > + WRITE_ONCE(p->proxy_pick_seq, rq->proxy_pick_seq); > + Why do we need READ_ONCE() / WRITE_ONCE()? All the checks happen on the same CPU under rq_lock. There is no chance of a concurrent update here. Any time we drop the lock, we do a re-pick and that should be sufficient to prevent any collision. > if (task_current(rq, p)) > curr_in_chain = true; > > @@ -6990,6 +7009,14 @@ find_proxy_task(struct rq *rq, struct task_struct *donor, struct rq_flags *rf) > */ > return proxy_resched_idle(rq); > } > + > + if (READ_ONCE(owner->proxy_pick_cpu) == this_cpu && > + READ_ONCE(owner->proxy_pick_seq) == rq->proxy_pick_seq) { > + WARN_ONCE(1, "sched/pe: deadlock cycle detected, pid %d\n", > + p->pid); > + __clear_task_blocked_on(p, NULL); > + goto deactivate; > + } > /* > * OK, now we're absolutely sure @owner is on this > * rq, therefore holding @rq->lock is sufficient to > @@ -9057,6 +9084,9 @@ void __init sched_init(void) > raw_spin_lock_init(&rq->cpu_epoch_lock); > rq->cpu_epoch_next = jiffies; > #endif > +#ifdef CONFIG_SCHED_PROXY_EXEC > + rq->proxy_pick_seq = 0; > +#endif > > zalloc_cpumask_var_node(&rq->scratch_mask, GFP_KERNEL, cpu_to_node(i)); > } > diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h > index 26ae13c86b699..f63c024d160e8 100644 > --- a/kernel/sched/sched.h > +++ b/kernel/sched/sched.h > @@ -1154,6 +1154,7 @@ struct rq { > #ifdef CONFIG_SCHED_PROXY_EXEC > struct task_struct __rcu *donor; /* Scheduling context */ > struct task_struct __rcu *curr; /* Execution context */ > + u64 proxy_pick_seq; /* find_proxy_task() seq */ > #else > union { > struct task_struct __rcu *donor; /* Scheduler context */ > > base-commit: 04998aa54848f15332202d0bea008d2ca1ed1713 -- Thanks and Regards, Prateek