From nobody Sat Jul 25 20:48:49 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 B263636215A; Mon, 13 Jul 2026 21:24:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783977884; cv=none; b=eujjKFWpVQnv8DOD3F2jxVRDpogX/JRBetxjP7NwUGuhyqRUY35hrwoVg8jtWQ1pS7cmelGhD4oX7X0dJXFYcmyVEuCsIuYmQuAEcNvplJ7YkUsXEukGGj4ZD+rlmTTSGEqzLpMLlCfzikSRcOB/sEuzav19peJRYK7gSGeTo8Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783977884; c=relaxed/simple; bh=MpgI8lelCOyelLCNRAKd3h8WUx9TpChi+m7rMo3Wb9g=; h=Date:From:To:Subject:Cc:In-Reply-To:References:MIME-Version: Message-ID:Content-Type; b=d4UNJUCtx2jV8slSOHnyHU9SIaMzpI+z4BYNrDfSa6cxuAqYuCbtjZn5y3WT/af0qkMkltjIMqNy3MgychEL/RXFzOnJqfIKD9ReBBb1O2lVXZsF0Dk7qPcF6D1tp64crEZdxhb7k5qRF8ifUIupyvd3ry1qzUFygZMRQi8+2kY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=gQ3wdK6E; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=bOpVxAfh; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="gQ3wdK6E"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="bOpVxAfh" Date: Mon, 13 Jul 2026 21:24:39 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1783977881; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lMmkX/sCNdqZnHnnBoB3Ah+OHNfoD3Y22mZ0dq8wn88=; b=gQ3wdK6EbijbYWOE9SS1QP9N7CaZVVZH/UwA7oX7Q76D1MgupSTnMSyogAozPn/WDL4/Di nqWGfm++mU2tvHCZkbX2Iet/x99cvQX+vqeSr5Zn1PNEMWdVyvIggknmcQJ2TvaGsmh/Ky fQ5yxBv7cQQzzom6N9umGgMR+4ts9oDweApcOpIxkttyjkP1KoYqfLriG8aroxUZphpKLm jISLAX5CAEmi6+3VC7xrmXKem5yLR/ip6BTDp7UqRCdps+khxJJffkM6aksB0MGLLOSV0P XD/Vo1kvFWX/j8mYIwFE1mJXABbIS+0IeKgucjqyU68UASHYqjRfpbuA7KOUqQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1783977881; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lMmkX/sCNdqZnHnnBoB3Ah+OHNfoD3Y22mZ0dq8wn88=; b=bOpVxAfhJspcmPNrKk2q01I3zLxQCG4Hrfyh6i8fosVaglgML84uWu3PlLTBEKPzliR2W8 Emf75YKcA0miIKDA== From: "tip-bot2 for Reinette Chatre" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/cache] fs/resctrl: Fix deadlock on errors during mount Cc: Sashiko , Tony Luck , Reinette Chatre , "Borislav Petkov (AMD)" , Ben Horgan , Chen Yu , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: =?utf-8?q?=3Cfe701825d7f538a6bbac6732230004050300c93e=2E1783963?= =?utf-8?q?505=2Egit=2Ereinette=2Echatre=40intel=2Ecom=3E?= References: =?utf-8?q?=3Cfe701825d7f538a6bbac6732230004050300c93e=2E17839635?= =?utf-8?q?05=2Egit=2Ereinette=2Echatre=40intel=2Ecom=3E?= Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <178397787968.1844600.13541038655768790592.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the x86/cache branch of tip: Commit-ID: 4f6db8caa19d77252bad5a9784bc5c1057ef673f Gitweb: https://git.kernel.org/tip/4f6db8caa19d77252bad5a9784bc5c105= 7ef673f Author: Reinette Chatre AuthorDate: Mon, 13 Jul 2026 10:39:39 -07:00 Committer: Borislav Petkov (AMD) CommitterDate: Mon, 13 Jul 2026 12:39:20 -07:00 fs/resctrl: Fix deadlock on errors during mount rdt_get_tree() acquires rdtgroup_mutex before calling kernfs_get_tree(). If superblock setup fails inside kernfs_get_tree(), the VFS calls .kill_sb() (rdt_kill_sb()) on the same thread before kernfs_get_tree() returns. rdt_kill_sb() unconditionally attempts to acquire rdtgroup_mutex and deadlock occurs. Since mount failure resulting from kernfs_get_tree() already calls the resctrl fs unmount handler (rdt_kill_sb()) let both call the same helper to make it clear both paths perform the same cleanup. Call kernfs_get_tree() outside of locks. If kernfs_get_tree() fails and ctx->kfc.new_sb_created is set, then rdt_kill_sb() has already been called and no further cleanup is needed. kernfs_get_tree() may set ctx->kfc.new_sb_created and then fail to obtain an inode for the new kn, causing the rdt_kill_sb() path to run with one few= er reference than required for the root to remain accessible in kernfs_kill_sb= (). Add an extra hold on rdtgroup_default.kn to defend against this scenario and ensure the root can be dereferenced safely from kernfs_kill_sb(). Dropping locks before kernfs_get_tree() creates a window where CPU hotplug callbacks can race with the mount operation. Specifically, an online event observing resctrl_mounted =3D=3D true could concurrently append directories= to the unactivated kernfs tree, allocate mon_data structures, and arm backgrou= nd workers. This concurrency is safe because the mount has not yet returned to the VFS, meaning userspace cannot interact with these transient files. If kernfs_get_tree() subsequently fails, the standard resctrl_unmount() teardo= wn safely manages the concurrent modifications: any dynamically generated kern= fs nodes are removed, and the associated memory is freed. Any background workers spawned by the hotplug event will naturally exit without re-arming when they acquire rdtgroup_mutex and observe resctrl_mounted =3D=3D false. Fixes: 5ff193fbde20 ("x86/intel_rdt: Add basic resctrl filesystem support") Closes: https://sashiko.dev/#/patchset/20260429184858.36423-1-tony.luck%40i= ntel.com [1] Reported-by: Sashiko Co-developed-by: Tony Luck Signed-off-by: Tony Luck Signed-off-by: Reinette Chatre Signed-off-by: Borislav Petkov (AMD) Reviewed-by: Ben Horgan Reviewed-by: Chen Yu Link: https://patch.msgid.link/fe701825d7f538a6bbac6732230004050300c93e.178= 3963505.git.reinette.chatre@intel.com --- fs/resctrl/rdtgroup.c | 83 ++++++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 27 deletions(-) diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c index 9804e40..ce96472 100644 --- a/fs/resctrl/rdtgroup.c +++ b/fs/resctrl/rdtgroup.c @@ -2989,10 +2989,34 @@ static void resctrl_fs_teardown(void) rdtgroup_destroy_root(); } =20 +static void resctrl_unmount(void) +{ + struct rdt_resource *r; + + cpus_read_lock(); + mutex_lock(&rdtgroup_mutex); + + rdt_disable_ctx(); + + /* Put everything back to default values. */ + for_each_alloc_capable_rdt_resource(r) + resctrl_arch_reset_all_ctrls(r); + + resctrl_fs_teardown(); + if (resctrl_arch_alloc_capable()) + resctrl_arch_disable_alloc(); + if (resctrl_arch_mon_capable()) + resctrl_arch_disable_mon(); + resctrl_mounted =3D false; + mutex_unlock(&rdtgroup_mutex); + cpus_read_unlock(); +} + static int rdt_get_tree(struct fs_context *fc) { struct rdt_fs_context *ctx =3D rdt_fc2context(fc); unsigned long flags =3D RFTYPE_CTRL_BASE; + struct kernfs_node *rdt_root_kn; struct rdt_l3_mon_domain *dom; struct rdt_resource *r; int ret; @@ -3068,10 +3092,6 @@ static int rdt_get_tree(struct fs_context *fc) if (ret) goto out_mondata; =20 - ret =3D kernfs_get_tree(fc); - if (ret < 0) - goto out_psl; - if (resctrl_arch_alloc_capable()) resctrl_arch_enable_alloc(); if (resctrl_arch_mon_capable()) @@ -3087,10 +3107,38 @@ static int rdt_get_tree(struct fs_context *fc) RESCTRL_PICK_ANY_CPU); } =20 - goto out; + /* + * Ensure root remains accessible after mutex is unlocked so that + * kernfs_kill_sb() can run safely if called by kernfs_get_tree()'s + * failure path after creating a superblock but before taking reference + * on root kn (for example, if unable to get inode for root kn). + */ + kernfs_get(rdtgroup_default.kn); + + /* + * Make backup of the current root kn being created to be used in + * kernfs_put(). The additional reference taken above will prevent the + * kn from being freed before kernfs_kill_sb() can run but + * rdtgroup_default.kn may be set to NULL via rdtgroup_destroy_root() + * and its backing root (rdt_root) could be overwritten before + * kernfs_put() can run. + */ + rdt_root_kn =3D rdtgroup_default.kn; + + rdt_last_cmd_clear(); + mutex_unlock(&rdtgroup_mutex); + cpus_read_unlock(); + + ret =3D kernfs_get_tree(fc); + /* + * resctrl can only be mounted once, new superblock only expected + * to be created once. + */ + if (!ctx->kfc.new_sb_created) + resctrl_unmount(); + kernfs_put(rdt_root_kn); + return ret; =20 -out_psl: - rdt_pseudo_lock_release(); out_mondata: if (resctrl_arch_mon_capable()) kernfs_remove(kn_mondata); @@ -3110,7 +3158,6 @@ out_schemata_free: out_root: rdtgroup_destroy_root(); out: - rdt_last_cmd_clear(); mutex_unlock(&rdtgroup_mutex); cpus_read_unlock(); return ret; @@ -3197,26 +3244,8 @@ static int rdt_init_fs_context(struct fs_context *fc) =20 static void rdt_kill_sb(struct super_block *sb) { - struct rdt_resource *r; - - cpus_read_lock(); - mutex_lock(&rdtgroup_mutex); - - rdt_disable_ctx(); - - /* Put everything back to default values. */ - for_each_alloc_capable_rdt_resource(r) - resctrl_arch_reset_all_ctrls(r); - - resctrl_fs_teardown(); - if (resctrl_arch_alloc_capable()) - resctrl_arch_disable_alloc(); - if (resctrl_arch_mon_capable()) - resctrl_arch_disable_mon(); - resctrl_mounted =3D false; + resctrl_unmount(); kernfs_kill_sb(sb); - mutex_unlock(&rdtgroup_mutex); - cpus_read_unlock(); } =20 static struct file_system_type rdt_fs_type =3D {