Received: by 2002:a05:7412:419a:b0:f3:1519:9f41 with SMTP id i26csp1270237rdh; Fri, 24 Nov 2023 08:35:35 -0800 (PST) X-Google-Smtp-Source: AGHT+IGeUwNc0+z8WNDDYrGcNfMUeIQzjbr+h7PnrlQt9oWEaXmmSK9oQ/cKB2ImjVc606oiRHjB X-Received: by 2002:a17:902:dac8:b0:1cf:9eb0:fb72 with SMTP id q8-20020a170902dac800b001cf9eb0fb72mr5135516plx.8.1700843735200; Fri, 24 Nov 2023 08:35:35 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700843735; cv=none; d=google.com; s=arc-20160816; b=qGZ3qg6fQLrYM99+F7cgt0E4aBwuhWnu1vj1fUZgocvI3HZFV5FP2GLYbaKkRrbe8r 0lEovWuu8fgxH8bZ0AmVt20dUXTObZpqE9hllpV2+cB7naSxv2QvRjw3wHxQNRFIsrl9 obmGSh2qJ2hDEsnHOEJV0k5uDP4f9FV/ZGAzJOaNg7dM8EHm1fbXcM0Fi8eXLZ5/DjCL B3jIELXenVnQLXYBvUxbnHPCz0GBxIEU3SpBO0t4QLwnB3WJHiQhEvoq7enuOFPaNF3D yLwuHkZr8gsXdl2p6AkA+NqlqbghT1Bb4ZwG0g+99GQ5Bz1u36IODlSctOcxhmqV0EzF QpLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=eUQSivaM/C3sgIYV/55zPnV1kMbFsOGZiai+sGa+jDY=; fh=A9B0uqHrLOhV8lpdKrDO+2kao9UNQ/xn2a9tcpNN72M=; b=C8MY8TCc42GYDI62TQuJKykcxyUYp0cGgj9KUUaHVEgmdUB4bo0Gr9sdLZC5o2zLCB O+c6te4TUCHIhJHzR8TamuWbVFInz3GZnFAzmCM9C77kEe9GAQx45w6kCgRhVSxnsQBv 4UdcEosFy6dKoGOQ3G+EU5qVcgW0hBy94JteSL3U2trFYjg3gyQhkKNk7coUdHIjyM+3 MfPloTfvF1HJ2yjm4xPCZSiN0JY3Pt5RKSkRibh7XW4YvOkwCAVExiRpFGB9pnLqhs6+ tpxTv5/cthf2EkQyu2F6ER5bZiP3QTSyISdw8H4qHd0Lz+TYFwO3KSU1ceq6pcG9Tl6q OTWA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=eplHiX6Z; spf=pass (google.com: domain of linux-wireless+bounces-55-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-wireless+bounces-55-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id y6-20020a17090322c600b001bc079974dbsi3933368plg.355.2023.11.24.08.35.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 08:35:35 -0800 (PST) Received-SPF: pass (google.com: domain of linux-wireless+bounces-55-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=eplHiX6Z; spf=pass (google.com: domain of linux-wireless+bounces-55-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-wireless+bounces-55-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 3F260B2102B for ; Fri, 24 Nov 2023 16:35:27 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8A49C35F15; Fri, 24 Nov 2023 16:35:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sipsolutions.net header.i=@sipsolutions.net header.b="eplHiX6Z" X-Original-To: linux-wireless@vger.kernel.org Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:242:246e::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AEB3D19A6; Fri, 24 Nov 2023 08:35:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sipsolutions.net; s=mail; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Content-Type:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-To: Resent-Cc:Resent-Message-ID; bh=eUQSivaM/C3sgIYV/55zPnV1kMbFsOGZiai+sGa+jDY=; t=1700843718; x=1702053318; b=eplHiX6ZMYIt11LKuIlWEPvXql5NNzBtK2Qbe3nAL30vIGt FwyzxUPM43QQVDRpK5rOtubghhSH5orccxvy4bO30sNFYVr3FRo6gEh+RLgXqF+JmygXOabWp9aji GtNi+yykJNzgnhM3ysbd7YOcVdz1ANXHQNTPxQ91C5s934QrL7SKN6ezcaq+T/73gIJIiFx8dVrZQ ylpxnbTXDUpkSTYbqrkecDjd/p5AHJmS2flrv6a69kcyLKkvahc1e0p4m3l4XkNrqr/YroUpi2nil D/+u1vUE0e2O0twKy7C3KVmyXzAx3/kLvucZN02tB1jDypmrLFajK/96of2N1YZA==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.97) (envelope-from ) id 1r6Z9A-00000002fA8-0Xch; Fri, 24 Nov 2023 17:35:16 +0100 From: Johannes Berg To: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , "Rafael J. Wysocki" , Johannes Berg Subject: [PATCH v2 2/6] debugfs: annotate debugfs handlers vs. removal with lockdep Date: Fri, 24 Nov 2023 17:25:25 +0100 Message-ID: <20231124172522.0442774abc66.Ia70a49792c448867fd61b0234e1da507b0f75086@changeid> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231124162522.16344-7-johannes@sipsolutions.net> References: <20231124162522.16344-7-johannes@sipsolutions.net> Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Johannes Berg When you take a lock in a debugfs handler but also try to remove the debugfs file under that lock, things can deadlock since the removal has to wait for all users to finish. Add lockdep annotations in debugfs_file_get()/_put() to catch such issues. Signed-off-by: Johannes Berg --- fs/debugfs/file.c | 10 ++++++++++ fs/debugfs/inode.c | 12 ++++++++++++ fs/debugfs/internal.h | 6 ++++++ 3 files changed, 28 insertions(+) diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index e00189aebbf4..3eff92450fd5 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -108,6 +108,12 @@ int debugfs_file_get(struct dentry *dentry) kfree(fsd); fsd = READ_ONCE(dentry->d_fsdata); } +#ifdef CONFIG_LOCKDEP + fsd->lock_name = kasprintf(GFP_KERNEL, "debugfs:%pd", dentry); + lockdep_register_key(&fsd->key); + lockdep_init_map(&fsd->lockdep_map, fsd->lock_name ?: "debugfs", + &fsd->key, 0); +#endif } /* @@ -124,6 +130,8 @@ int debugfs_file_get(struct dentry *dentry) if (!refcount_inc_not_zero(&fsd->active_users)) return -EIO; + lock_map_acquire_read(&fsd->lockdep_map); + return 0; } EXPORT_SYMBOL_GPL(debugfs_file_get); @@ -141,6 +149,8 @@ void debugfs_file_put(struct dentry *dentry) { struct debugfs_fsdata *fsd = READ_ONCE(dentry->d_fsdata); + lock_map_release(&fsd->lockdep_map); + if (refcount_dec_and_test(&fsd->active_users)) complete(&fsd->active_users_drained); } diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index dcde4199a625..80f4f000dcc1 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -241,6 +241,14 @@ static void debugfs_release_dentry(struct dentry *dentry) if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT) return; + /* check it wasn't a dir (no fsdata) or automount (no real_fops) */ + if (fsd && fsd->real_fops) { +#ifdef CONFIG_LOCKDEP + lockdep_unregister_key(&fsd->key); + kfree(fsd->lock_name); +#endif + } + kfree(fsd); } @@ -744,6 +752,10 @@ static void __debugfs_file_removed(struct dentry *dentry) fsd = READ_ONCE(dentry->d_fsdata); if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT) return; + + lock_map_acquire(&fsd->lockdep_map); + lock_map_release(&fsd->lockdep_map); + if (!refcount_dec_and_test(&fsd->active_users)) wait_for_completion(&fsd->active_users_drained); } diff --git a/fs/debugfs/internal.h b/fs/debugfs/internal.h index f7c489b5a368..c7d61cfc97d2 100644 --- a/fs/debugfs/internal.h +++ b/fs/debugfs/internal.h @@ -7,6 +7,7 @@ #ifndef _DEBUGFS_INTERNAL_H_ #define _DEBUGFS_INTERNAL_H_ +#include struct file_operations; @@ -23,6 +24,11 @@ struct debugfs_fsdata { struct { refcount_t active_users; struct completion active_users_drained; +#ifdef CONFIG_LOCKDEP + struct lockdep_map lockdep_map; + struct lock_class_key key; + char *lock_name; +#endif }; }; }; -- 2.42.0