From patchwork Thu Nov 9 21:22:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 163611 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b129:0:b0:403:3b70:6f57 with SMTP id q9csp722759vqs; Thu, 9 Nov 2023 13:40:46 -0800 (PST) X-Google-Smtp-Source: AGHT+IF8FX7FiCN7vgfNF3LYato+6teQEqPIDJ8uA9qLPj8qh2kQBbcPmXzZofLgGmN1KUhd4F2S X-Received: by 2002:a05:6a00:b46:b0:6be:2ace:deb8 with SMTP id p6-20020a056a000b4600b006be2acedeb8mr7487351pfo.20.1699566045818; Thu, 09 Nov 2023 13:40:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699566045; cv=none; d=google.com; s=arc-20160816; b=ZRJnmz7cnpjF6Wb15hWtlABs2d6NXTm7SQxkM2BIEHqcV5AZBsI8R4VWyx6sN5yAfq XU+Sati/VfF+RFWCrn1RfPBTeUbxZzmyMn0sGUQGkI04JfHA+N7lclYHryUVqwc4adoR NdFQIz4GLEV47OxKRdZAuqqZ4K4Z55DKfZ3VwypO9vVk5dMw4aR3A/jO1D85EBRiMiOs rjvH4HyJDYvGgr/zCqCdcNXuMVpqal2pQG835SqIYWfjpiWwBw0Qf1+bFm68aWqUWTkh AdU0KUDR0PnIVKzx64+FqjcTbRHJUiVQLQ9jrwnnMgefMGQ+O0HjhdCYU6dUu3/640/t aQCw== 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=6ZT7FJvDZFk52iLWTs4ADJtCF3Ou7kQeTljiE1vVw8M=; fh=fr6hIKaSb7E+0K08IHhjy1pQvdN8X98xxmR7pnwhgag=; b=QjJ7KkfdJM+PvWZMOfIINnpRkDjT58qGNqN2QRZZj9G9f8K73hoB+rH4NUocYmeBit bFHFmr/57aPpHUuheNj2Pp7bkIGt50gdPsRlamBDHpqAD6VkZcsGMB+AMWjEwpgBNcw/ Rk3MmHawvP69w4HgtV3VmQ+dIg2ZyZSvvW/RBhV0HODDP1jQQKcvZ07kzRWJkl+MB48z hnSmhZN8C1rpLG3bQ2ljwdTxGcfISgWb3u70elWqpqRSEjnhdKwlishUt3k3dRkjY0op Zz/SbR8Xu3leq2bOCJccQ70pryic81dnTMoNdjmpAJJB+3amQo2wm2Ncb/++bu6sjeMF CTJg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=UAdlYhOA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from lipwig.vger.email (lipwig.vger.email. [23.128.96.33]) by mx.google.com with ESMTPS id ea27-20020a056a004c1b00b0068fcf6fe22esi17137532pfb.306.2023.11.09.13.40.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Nov 2023 13:40:45 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) client-ip=23.128.96.33; Authentication-Results: mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=UAdlYhOA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id E76828060CA4; Thu, 9 Nov 2023 13:38:58 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345265AbjKIViY (ORCPT + 30 others); Thu, 9 Nov 2023 16:38:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42250 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345257AbjKIViW (ORCPT ); Thu, 9 Nov 2023 16:38:22 -0500 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:242:246e::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7EBF43C39; Thu, 9 Nov 2023 13:38:20 -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=6ZT7FJvDZFk52iLWTs4ADJtCF3Ou7kQeTljiE1vVw8M=; t=1699565900; x=1700775500; b=UAdlYhOAvjrHYOPAbb2Mb8zNSg97SFKyj7Cpn+Y/RdoYZ1u +yHSpkU98GF4XU0nsiSTUsX/Hu186weqvkIKluzsGVehfN0TRaoeHwHohx0xtoFJoVpuKN3I1bYMU FsPxo/uwDa27c6G9HNR8LijMmQFG5PTf/o4FRLL6fpb2c94T4+MHvJsL4it87tZs4gmFXS2ytZ7S4 9z9IoMIgL4EtqMqirlgMgDUxxu8lsHsCgUTq+HAoolmn+CqRGxD0eDUXCvONr0GB/nxqdA/bAOwSt GDR2Iw81HONfl95SrVKojS6/cfvFUp+HSWhVMUVRn/nWFqfQsdWVFPJR3egkqstw==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.97) (envelope-from ) id 1r1CjB-00000001znF-1Xz5; Thu, 09 Nov 2023 22:38:17 +0100 From: Johannes Berg To: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, Greg Kroah-Hartman , "Rafael J. Wysocki" , Nicolai Stange , Ben Greear , Johannes Berg Subject: [RFC PATCH 1/6] debugfs: fix automount d_fsdata usage Date: Thu, 9 Nov 2023 22:22:53 +0100 Message-ID: <20231109222251.9e54cb55c700.I64fe5615568e87f9ae2d7fb2ac4e5fa96924cb50@changeid> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231109212251.213873-7-johannes@sipsolutions.net> References: <20231109212251.213873-7-johannes@sipsolutions.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (lipwig.vger.email [0.0.0.0]); Thu, 09 Nov 2023 13:38:59 -0800 (PST) X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782124166176939338 X-GMAIL-MSGID: 1782124166176939338 From: Johannes Berg debugfs_create_automount() stores a function pointer in d_fsdata, but since commit 7c8d469877b1 ("debugfs: add support for more elaborate ->d_fsdata") debugfs_release_dentry() will free it, now conditionally on DEBUGFS_FSDATA_IS_REAL_FOPS_BIT, but that's not set for the function pointer in automount. As a result, removing an automount dentry would attempt to free the function pointer. Luckily, the only user of this (tracing) never removes it. Nevertheless, it's safer if we just handle the fsdata in one way, namely either DEBUGFS_FSDATA_IS_REAL_FOPS_BIT or allocated. Thus, change the automount to allocate it, and use the real_fops in the data to indicate whether or not automount is filled, rather than adding a type tag. At least for now this isn't actually needed, but the next changes will require it. Also check in debugfs_file_get() that it gets only called on regular files, just to make things clearer. Signed-off-by: Johannes Berg --- fs/debugfs/file.c | 3 +++ fs/debugfs/inode.c | 25 ++++++++++++++++++------- fs/debugfs/internal.h | 10 ++++++++-- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 87b3753aa4b1..23bdfc126b5e 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -84,6 +84,9 @@ int debugfs_file_get(struct dentry *dentry) struct debugfs_fsdata *fsd; void *d_fsd; + if (WARN_ON(!d_is_reg(dentry))) + return -EINVAL; + d_fsd = READ_ONCE(dentry->d_fsdata); if (!((unsigned long)d_fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)) { fsd = d_fsd; diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 83e57e9f9fa0..269bad87d552 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -236,17 +236,19 @@ static const struct super_operations debugfs_super_operations = { static void debugfs_release_dentry(struct dentry *dentry) { - void *fsd = dentry->d_fsdata; + struct debugfs_fsdata *fsd = dentry->d_fsdata; - if (!((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)) - kfree(dentry->d_fsdata); + if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT) + return; + + kfree(fsd); } static struct vfsmount *debugfs_automount(struct path *path) { - debugfs_automount_t f; - f = (debugfs_automount_t)path->dentry->d_fsdata; - return f(path->dentry, d_inode(path->dentry)->i_private); + struct debugfs_fsdata *fsd = path->dentry->d_fsdata; + + return fsd->automount(path->dentry, d_inode(path->dentry)->i_private); } static const struct dentry_operations debugfs_dops = { @@ -634,11 +636,20 @@ struct dentry *debugfs_create_automount(const char *name, void *data) { struct dentry *dentry = start_creating(name, parent); + struct debugfs_fsdata *fsd; struct inode *inode; if (IS_ERR(dentry)) return dentry; + fsd = kzalloc(sizeof(*fsd), GFP_KERNEL); + if (!fsd) { + failed_creating(dentry); + return ERR_PTR(-ENOMEM); + } + + fsd->automount = f; + if (!(debugfs_allow & DEBUGFS_ALLOW_API)) { failed_creating(dentry); return ERR_PTR(-EPERM); @@ -654,7 +665,7 @@ struct dentry *debugfs_create_automount(const char *name, make_empty_dir_inode(inode); inode->i_flags |= S_AUTOMOUNT; inode->i_private = data; - dentry->d_fsdata = (void *)f; + dentry->d_fsdata = fsd; /* directory inodes start off with i_nlink == 2 (for "." entry) */ inc_nlink(inode); d_instantiate(dentry, inode); diff --git a/fs/debugfs/internal.h b/fs/debugfs/internal.h index 92af8ae31313..f7c489b5a368 100644 --- a/fs/debugfs/internal.h +++ b/fs/debugfs/internal.h @@ -17,8 +17,14 @@ extern const struct file_operations debugfs_full_proxy_file_operations; struct debugfs_fsdata { const struct file_operations *real_fops; - refcount_t active_users; - struct completion active_users_drained; + union { + /* automount_fn is used when real_fops is NULL */ + debugfs_automount_t automount; + struct { + refcount_t active_users; + struct completion active_users_drained; + }; + }; }; /* From patchwork Thu Nov 9 21:22:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 163609 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b129:0:b0:403:3b70:6f57 with SMTP id q9csp722199vqs; Thu, 9 Nov 2023 13:39:11 -0800 (PST) X-Google-Smtp-Source: AGHT+IGN/3qgsv++uJ1RCdI8GkPBaOCquQ+exNCbF/HLua+74VMXQjhQTTXHEzDuWWX3X7nSps5I X-Received: by 2002:a05:6a20:4329:b0:16b:b4a0:e06b with SMTP id h41-20020a056a20432900b0016bb4a0e06bmr7531200pzk.43.1699565950948; Thu, 09 Nov 2023 13:39:10 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699565950; cv=none; d=google.com; s=arc-20160816; b=hakXuNVE5izsJYyQduQIDRitqjm89DeJcn9WdzExkRlxslSAsSvtvHVEkv8fEPQQk+ uwSCzGOwUKEYCV9arK2kqefCxUX8fVHg1ydfhl3DJgrfwaqlZ6Wottez+0KGBKrqP34k /H/TJ7g09Y6ZLiX/KHkdkBpHiF5pSGOa/xPzhO0070X4uW7+tb36IBhzfLlz0C+d50tk mdIOTIyue4d7lnD+JreD0ucwkM8+8b3gUqF0WeUZtobacQgYX4nC1JyZGjkep4ggiMig tCaT0PAi1YB8qc/KpQOVCKIPloyzyL4lLY1OMvEWlaOPI84ub1iCnjE/RK68jlsVkJn+ gkNQ== 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=FsLOXpYyzFGJvMDs+SWO8R+4g522I7OBFFoDx/3n4iY=; fh=fr6hIKaSb7E+0K08IHhjy1pQvdN8X98xxmR7pnwhgag=; b=y3dLwj2Z/rx5+I3fyGaBSIi/SD9WWDhH6B3KGE6yGy8h+A78YqzvCuWGg38WkG92jE MLUOnfRN9YLWePz1ij2ZO2UYrkXYEAoWQ2z3GYxNwyjnKVmY/1/OV60NOT2XynL25Ic6 z2BIayGr5Xx3Z1yRcnR7siSwmI43l6er7M8J6gHX9adIsL2ZtWFpj4dVw6ddtYK7mNEq tw4x7JY0OZjMoU9PXHtVLh+OFhIrp35rlViRlbTWIYWN5hjYMfGKUY4NrT+bqX9rQ0TT 4//QlS8Vn9HR79eMv8MXS1F0blzur2ciLF4nEiZmIAvxBG6iR0tVVt/eOcMdK/iNTc3C bLAQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=vZlLtyqI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from agentk.vger.email (agentk.vger.email. [2620:137:e000::3:2]) by mx.google.com with ESMTPS id b13-20020a63d80d000000b005be2508cde6si186881pgh.593.2023.11.09.13.39.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Nov 2023 13:39:10 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) client-ip=2620:137:e000::3:2; Authentication-Results: mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=vZlLtyqI; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by agentk.vger.email (Postfix) with ESMTP id 5DF6A822F74A; Thu, 9 Nov 2023 13:38:54 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at agentk.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345280AbjKIVi0 (ORCPT + 30 others); Thu, 9 Nov 2023 16:38:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42262 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345259AbjKIViX (ORCPT ); Thu, 9 Nov 2023 16:38:23 -0500 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:242:246e::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1A2103C3D; Thu, 9 Nov 2023 13:38:21 -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=FsLOXpYyzFGJvMDs+SWO8R+4g522I7OBFFoDx/3n4iY=; t=1699565901; x=1700775501; b=vZlLtyqIDj5duKA94ALT7y+Ns0paq19XWTcyqOijEAu8W2S y+JXON4phpgqgTruwZ8whIlgRs2i4eV7DzPlG1l68I9b2OYmAvnvXCLDY/4WVP4NpPAeLr0nhNea/ WSEKR/eia4v3U83RCinmH4q+zYeS8GQ7xgWxLakuPIG1eTSTpmjl1EBLQY35Szzeqz5EtbnIpsg/1 a4w4YSJybxmFRnoExexriqXMM3YeS6snGYQpWbxwT6jqeTOB4VMb3lfWX5fYb3DufVDsLRwGLbRn5 uXRr8PpuYI9jwLa3HMT0LD5E2BwrF38reACT+DGbzv6fqtkTlpF/2KjxZTf7tWwQ==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.97) (envelope-from ) id 1r1CjC-00000001znF-0g58; Thu, 09 Nov 2023 22:38:18 +0100 From: Johannes Berg To: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, Greg Kroah-Hartman , "Rafael J. Wysocki" , Nicolai Stange , Ben Greear , Johannes Berg Subject: [RFC PATCH 2/6] debugfs: annotate debugfs handlers vs. removal with lockdep Date: Thu, 9 Nov 2023 22:22:54 +0100 Message-ID: <20231109222251.a62811ebde9b.Ia70a49792c448867fd61b0234e1da507b0f75086@changeid> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231109212251.213873-7-johannes@sipsolutions.net> References: <20231109212251.213873-7-johannes@sipsolutions.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (agentk.vger.email [0.0.0.0]); Thu, 09 Nov 2023 13:38:54 -0800 (PST) X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on agentk.vger.email X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782124066333305991 X-GMAIL-MSGID: 1782124066333305991 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 23bdfc126b5e..e499d38b1077 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -103,6 +103,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 } /* @@ -119,6 +125,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); @@ -136,6 +144,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 269bad87d552..a4c77aafb77b 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 an automount or dir */ + if (fsd && fsd->real_fops) { +#ifdef CONFIG_LOCKDEP + lockdep_unregister_key(&fsd->key); + kfree(fsd->lock_name); +#endif + } + kfree(fsd); } @@ -742,6 +750,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 }; }; }; From patchwork Thu Nov 9 21:22:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 163606 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b129:0:b0:403:3b70:6f57 with SMTP id q9csp722034vqs; Thu, 9 Nov 2023 13:38:41 -0800 (PST) X-Google-Smtp-Source: AGHT+IEWjnedNOUnNT/RNXU6w3UE0MfXNzk2nHoUCFlTI/wTExE66PlIrIuW0M48Fujli49c3Vfv X-Received: by 2002:a17:90a:4585:b0:27d:222c:f5eb with SMTP id v5-20020a17090a458500b0027d222cf5ebmr2762460pjg.11.1699565921151; Thu, 09 Nov 2023 13:38:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699565921; cv=none; d=google.com; s=arc-20160816; b=lF7q/A9F9QqKDNYQt4m2IGZDB2hcjVt/ecN4C+5fbb4eBBFaUbXy9jNtxMq+67fUl0 3x05V3TyWMT06Ghbe4I5X29MJ+T3fThHKYeH0ySh7Cvdldlj42DvQ8SetzmdYaWSVM2H sTLcTT6DFNfqLmGiIT6IegiYRymhccl/XCKyLaR0F/3LxvIfyKXg56cZXPhKAQDUyPjt /ehDD+rPIoqvoEVa1V6gWGJc9a0+7pC8DJ7UUpGYt1R5mRyOGkNseSUqLMNueiCyfKL1 ocZLN1WA2j9GLuhn4S46B7SiU4A5NDf5cAtJqX/W3jo2LEsW6iRcrFuSekfL29V+VpZj UnbA== 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=/3x7Uzb2xVsM+qPa/s6ahfiXYwxF7KgqrBu++ys4yuQ=; fh=fr6hIKaSb7E+0K08IHhjy1pQvdN8X98xxmR7pnwhgag=; b=fbzgi+ffrQ6DvPgSWj8yu8vH2p1/ByLV04ABgg8SM937V+vl46NzmhANo23HIacYmj +zU12gHnFZ9z6x/afJ/7KmPMtI4G0nrlcJxeZeTYYHZQQCpkKhbUCAGOXLNfDDGaKdm6 H0h3UuftR8gqduE6ddz6uWmZ6dbuILhlgNpQMVn6yhP13/IaHJX8SzFje03zMJcYpzN+ iAxrbixK/4e9TJ3wGZKEIjel7T7J42wCLI3CizabPF9zJ7yMpagNxe07pYRaKZU8LKRQ YmnOfBv6XbjFF15MUCwZoxOz79giQU+nR8zRmiWzbmMR/FrqiAHtJuGX0wyqu15SncrT pDYw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=KUznzj3v; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id ob3-20020a17090b390300b00280a4a15cddsi2718509pjb.94.2023.11.09.13.38.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Nov 2023 13:38:41 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=KUznzj3v; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id D523D8392E1D; Thu, 9 Nov 2023 13:38:39 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234801AbjKIVic (ORCPT + 30 others); Thu, 9 Nov 2023 16:38:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42266 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345262AbjKIViY (ORCPT ); Thu, 9 Nov 2023 16:38:24 -0500 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:242:246e::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC8103C30; Thu, 9 Nov 2023 13:38:21 -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=/3x7Uzb2xVsM+qPa/s6ahfiXYwxF7KgqrBu++ys4yuQ=; t=1699565902; x=1700775502; b=KUznzj3vFood3m4qndr+0Z80B26ACVzpDau6qD8FaPG4vyw azKhDI/pUxt5lc/NGA8irE4Cdnrw/ZAKAYuDRtt/4LNJgBMdL7oUzJR63AubskA9uGPAROo6IiMtZ 2Pn2Ojmw4PDyF3Tk4HntXkax+8MUv/rlavzyBtENs1n4AIWe8VZbXjjnRJahgDfpzayaKJDoM3paN pI6zRcnH6kpYDuQpjETJP7CHdl28yUMPzH8wuWhX/5irb0MW2ZmzYLoahgox/UARVARH8j7OEbTxq JESXEl0lQkQPNbO9TvcPAQbyoVXoKbr9ioprsH+ibNFakONbac0H8PbJtr+U5W5Q==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.97) (envelope-from ) id 1r1CjC-00000001znF-3teS; Thu, 09 Nov 2023 22:38:19 +0100 From: Johannes Berg To: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, Greg Kroah-Hartman , "Rafael J. Wysocki" , Nicolai Stange , Ben Greear , Johannes Berg Subject: [RFC PATCH 3/6] debugfs: add API to allow debugfs operations cancellation Date: Thu, 9 Nov 2023 22:22:55 +0100 Message-ID: <20231109222251.e6ade2190ef4.If54cd017d5734024e7bee5e4a237e17244050480@changeid> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231109212251.213873-7-johannes@sipsolutions.net> References: <20231109212251.213873-7-johannes@sipsolutions.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Thu, 09 Nov 2023 13:38:39 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782124035395618556 X-GMAIL-MSGID: 1782124035395618556 From: Johannes Berg In some cases there might be longer-running hardware accesses in debugfs files, or attempts to acquire locks, and we want to still be able to quickly remove the files. Introduce a cancellations API to use inside the debugfs handler functions to be able to cancel such operations on a per-file basis. Signed-off-by: Johannes Berg --- fs/debugfs/file.c | 82 +++++++++++++++++++++++++++++++++++++++++ fs/debugfs/inode.c | 23 +++++++++++- fs/debugfs/internal.h | 5 +++ include/linux/debugfs.h | 19 ++++++++++ 4 files changed, 128 insertions(+), 1 deletion(-) diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index e499d38b1077..f6993c068322 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -109,6 +109,8 @@ int debugfs_file_get(struct dentry *dentry) lockdep_init_map(&fsd->lockdep_map, fsd->lock_name ?: "debugfs", &fsd->key, 0); #endif + INIT_LIST_HEAD(&fsd->cancellations); + spin_lock_init(&fsd->cancellations_lock); } /* @@ -151,6 +153,86 @@ void debugfs_file_put(struct dentry *dentry) } EXPORT_SYMBOL_GPL(debugfs_file_put); +/** + * debugfs_enter_cancellation - enter a debugfs cancellation + * @file: the file being accessed + * @cancellation: the cancellation object, the cancel callback + * inside of it must be initialized + * + * When a debugfs file is removed it needs to wait for all active + * operations to complete. However, the operation itself may need + * to wait for hardware or completion of some asynchronous process + * or similar. As such, it may need to be cancelled to avoid long + * waits or even deadlocks. + * + * This function can be used inside a debugfs handler that may + * need to be cancelled. As soon as this function is called, the + * cancellation's 'cancel' callback may be called, at which point + * the caller should proceed to call debugfs_leave_cancellation() + * and leave the debugfs handler function as soon as possible. + * Note that the 'cancel' callback is only ever called in the + * context of some kind of debugfs_remove(). + * + * This function must be paired with debugfs_leave_cancellation(). + */ +void debugfs_enter_cancellation(struct file *file, + struct debugfs_cancellation *cancellation) +{ + struct debugfs_fsdata *fsd; + struct dentry *dentry = F_DENTRY(file); + + INIT_LIST_HEAD(&cancellation->list); + + if (WARN_ON(!d_is_reg(dentry))) + return; + + if (WARN_ON(!cancellation->cancel)) + return; + + fsd = READ_ONCE(dentry->d_fsdata); + if (WARN_ON(!fsd || + ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT))) + return; + + spin_lock(&fsd->cancellations_lock); + list_add(&cancellation->list, &fsd->cancellations); + spin_unlock(&fsd->cancellations_lock); + + /* if we're already removing wake it up to cancel */ + if (d_unlinked(dentry)) + complete(&fsd->active_users_drained); +} +EXPORT_SYMBOL_GPL(debugfs_enter_cancellation); + +/** + * debugfs_leave_cancellation - leave cancellation section + * @file: the file being accessed + * @cancellation: the cancellation previously registered with + * debugfs_enter_cancellation() + * + * See the documentation of debugfs_enter_cancellation(). + */ +void debugfs_leave_cancellation(struct file *file, + struct debugfs_cancellation *cancellation) +{ + struct debugfs_fsdata *fsd; + struct dentry *dentry = F_DENTRY(file); + + if (WARN_ON(!d_is_reg(dentry))) + return; + + fsd = READ_ONCE(dentry->d_fsdata); + if (WARN_ON(!fsd || + ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT))) + return; + + spin_lock(&fsd->cancellations_lock); + if (!list_empty(&cancellation->list)) + list_del(&cancellation->list); + spin_unlock(&fsd->cancellations_lock); +} +EXPORT_SYMBOL_GPL(debugfs_leave_cancellation); + /* * Only permit access to world-readable files when the kernel is locked down. * We also need to exclude any file that has ways to write or alter it as root diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index a4c77aafb77b..2cbcc49a8826 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -247,6 +247,7 @@ static void debugfs_release_dentry(struct dentry *dentry) lockdep_unregister_key(&fsd->key); kfree(fsd->lock_name); #endif + WARN_ON(!list_empty(&fsd->cancellations)); } kfree(fsd); @@ -754,8 +755,28 @@ static void __debugfs_file_removed(struct dentry *dentry) lock_map_acquire(&fsd->lockdep_map); lock_map_release(&fsd->lockdep_map); - if (!refcount_dec_and_test(&fsd->active_users)) + /* if we hit zero, just wait for all to finish */ + if (!refcount_dec_and_test(&fsd->active_users)) { wait_for_completion(&fsd->active_users_drained); + return; + } + + /* if we didn't hit zero, try to cancel any we can */ + while (refcount_read(&fsd->active_users)) { + struct debugfs_cancellation *c; + + spin_lock(&fsd->cancellations_lock); + while ((c = list_first_entry_or_null(&fsd->cancellations, + typeof(*c), list))) { + list_del_init(&c->list); + spin_unlock(&fsd->cancellations_lock); + c->cancel(dentry, c->cancel_data); + spin_lock(&fsd->cancellations_lock); + } + spin_unlock(&fsd->cancellations_lock); + + wait_for_completion(&fsd->active_users_drained); + } } static void remove_one(struct dentry *victim) diff --git a/fs/debugfs/internal.h b/fs/debugfs/internal.h index c7d61cfc97d2..5f279abd9351 100644 --- a/fs/debugfs/internal.h +++ b/fs/debugfs/internal.h @@ -8,6 +8,7 @@ #ifndef _DEBUGFS_INTERNAL_H_ #define _DEBUGFS_INTERNAL_H_ #include +#include struct file_operations; @@ -29,6 +30,10 @@ struct debugfs_fsdata { struct lock_class_key key; char *lock_name; #endif + + /* lock for the cancellations list */ + spinlock_t cancellations_lock; + struct list_head cancellations; }; }; }; diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index ea2d919fd9c7..c9c65b132c0f 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -171,6 +171,25 @@ ssize_t debugfs_write_file_bool(struct file *file, const char __user *user_buf, ssize_t debugfs_read_file_str(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); +/** + * struct debugfs_cancellation - cancellation data + * @list: internal, for keeping track + * @cancel: callback to call + * @cancel_data: extra data for the callback to call + */ +struct debugfs_cancellation { + struct list_head list; + void (*cancel)(struct dentry *, void *); + void *cancel_data; +}; + +void __acquires(cancellation) +debugfs_enter_cancellation(struct file *file, + struct debugfs_cancellation *cancellation); +void __releases(cancellation) +debugfs_leave_cancellation(struct file *file, + struct debugfs_cancellation *cancellation); + #else #include From patchwork Thu Nov 9 21:22:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 163610 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b129:0:b0:403:3b70:6f57 with SMTP id q9csp722639vqs; Thu, 9 Nov 2023 13:40:25 -0800 (PST) X-Google-Smtp-Source: AGHT+IEStpGIv5TpMOgS300lsOvvHAJFx/ThcDdGw9+a8cwy7Mwi6TtbDdQApYX5e/xb4YndqgzW X-Received: by 2002:a05:6e02:2142:b0:359:6dbb:3090 with SMTP id d2-20020a056e02214200b003596dbb3090mr7028689ilv.32.1699566025357; Thu, 09 Nov 2023 13:40:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699566025; cv=none; d=google.com; s=arc-20160816; b=yxjvqi0Qn461NKS9pqt8kIbQCAtLoReJb9lY+5qqs0yctGSD6atxBG/fBMOrR2anO+ TyqA+ol0yf2qPZ44ieI+DnjvVhIxuYe8DFCXFh+EvNtiEje8e1s0xQ5XNsXGxZcIE22V 4vB/jwxN0Vg3mnMLaEVRIcvcojAyOUlMfdlWF9TnDsKjrGQ762zpTHYsM+N3yTh0WiAq bIq6Bn3VHqboLS4UCajlglg59/EkN+BrCf9Cnrn7MGH+x6N4da1Yah/wr0Fhn1fs7UT7 fX0t4/8SZF4pQpCPxUcZQysDfO5g14iSr/CiDiT9volAKUMWLgz5xgzUqjb0j6MtMptA cHkQ== 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=scv5oorCJU13Z/yavLrg9Y3mxIkMMv5PMJeDsknaHgU=; fh=fr6hIKaSb7E+0K08IHhjy1pQvdN8X98xxmR7pnwhgag=; b=IgjhqDFZdDblninL+x9bTueHgbCuANUfNdwzWIuKVjpzZnFdqyOM1AO6ohBocKC25N 48M4dqriuUQ1e96ExbKzbJuk7r736JXB512RF3NhpTnp0lRZlJ3O7+1dxnPvuOaYvglr /TxfC9wcebZjo9yS6vOaH5+tAamQDuRZLeHPDHMXoEkNo0sAJT8xfjP0V0o3cCziR7Ls Z04yQU4SH8Nc21KAxdXvo846G71h3soONeXZRRp0WmZDv1Y6j2WXLNpPoPxJQDBd0JiN zqgnu7hPBegtNjXnNXP70GnyDU80/PwFvW4Gw4hiXVezkKURN4DPFd1LkHcJlLn1wwqR IjaQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=XKa2HVNX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from groat.vger.email (groat.vger.email. [23.128.96.35]) by mx.google.com with ESMTPS id o8-20020a656a48000000b005b57aa8517bsi10041404pgu.91.2023.11.09.13.40.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Nov 2023 13:40:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) client-ip=23.128.96.35; Authentication-Results: mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=XKa2HVNX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by groat.vger.email (Postfix) with ESMTP id 4F3418087FE8; Thu, 9 Nov 2023 13:40:22 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at groat.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234892AbjKIVig (ORCPT + 30 others); Thu, 9 Nov 2023 16:38:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42268 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345270AbjKIViZ (ORCPT ); Thu, 9 Nov 2023 16:38:25 -0500 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:242:246e::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AE2854204; Thu, 9 Nov 2023 13:38:22 -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=scv5oorCJU13Z/yavLrg9Y3mxIkMMv5PMJeDsknaHgU=; t=1699565902; x=1700775502; b=XKa2HVNXoLNcVy6ovLVdlyADfafidgPIBBkvJLqNzVTwVFl 8/th/JGWGudYkvn0xuM25Uj3i6tGZgpY3nHldccFvEWBSOS9hhqQ/WJ7DrkDGclCgBozijbYCN8jg /tguvSZqzAjgDEdM0hHlUVJg5UXA+S6XmERW/bN32d3NoFSvspgANVhy60FNh3N9YvWqkr/zLsCuu Lx8HINcnTq169EqJ46QlF+1XbfvMfWiP6LXPW0VL6LhDFWTS2ObiYB2g+VXYEe5OU467u+hRZGG3k di6iKEHpE5IEohgJPT8sg+VqIyacbzIjVxGuTjAN1H1RtEGdvAwwZvCvV0T2gaNg==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.97) (envelope-from ) id 1r1CjD-00000001znF-3lT7; Thu, 09 Nov 2023 22:38:20 +0100 From: Johannes Berg To: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, Greg Kroah-Hartman , "Rafael J. Wysocki" , Nicolai Stange , Ben Greear , Johannes Berg Subject: [RFC PATCH 4/6] wifi: cfg80211: add locked debugfs wrappers Date: Thu, 9 Nov 2023 22:22:56 +0100 Message-ID: <20231109222251.dc646db745f3.I52daf6c4d8f70b5c5c2de7f0918c6748f11f1e8b@changeid> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231109212251.213873-7-johannes@sipsolutions.net> References: <20231109212251.213873-7-johannes@sipsolutions.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (groat.vger.email [0.0.0.0]); Thu, 09 Nov 2023 13:40:22 -0800 (PST) X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on groat.vger.email X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782124144899328939 X-GMAIL-MSGID: 1782124144899328939 From: Johannes Berg Add wrappers for debugfs files that should be called with the wiphy mutex held, while the file is also to be removed under the wiphy mutex. This could otherwise deadlock when a file is trying to acquire the wiphy mutex while the code removing it holds the mutex but waits for the removal. This actually works by pushing the execution of the read or write handler to a wiphy work that can be cancelled using the debugfs cancellation API. Signed-off-by: Johannes Berg --- include/net/cfg80211.h | 46 ++++++++++++ net/wireless/debugfs.c | 160 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index b137a33a1b68..4ecfb06c413d 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -9299,4 +9299,50 @@ bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap, */ void cfg80211_links_removed(struct net_device *dev, u16 link_mask); +#ifdef CONFIG_CFG80211_DEBUGFS +/** + * wiphy_locked_debugfs_read - do a locked read in debugfs + * @wiphy: the wiphy to use + * @file: the file being read + * @buf: the buffer to fill and then read from + * @bufsize: size of the buffer + * @userbuf: the user buffer to copy to + * @count: read count + * @ppos: read position + * @handler: the read handler to call (under wiphy lock) + * @data: additional data to pass to the read handler + */ +ssize_t wiphy_locked_debugfs_read(struct wiphy *wiphy, struct file *file, + char *buf, size_t bufsize, + char __user *userbuf, size_t count, + loff_t *ppos, + ssize_t (*handler)(struct wiphy *wiphy, + struct file *file, + char *buf, + size_t bufsize, + void *data), + void *data); + +/** + * wiphy_locked_debugfs_write - do a locked write in debugfs + * @wiphy: the wiphy to use + * @file: the file being written to + * @buf: the buffer to copy the user data to + * @bufsize: size of the buffer + * @userbuf: the user buffer to copy from + * @count: read count + * @handler: the write handler to call (under wiphy lock) + * @data: additional data to pass to the write handler + */ +ssize_t wiphy_locked_debugfs_write(struct wiphy *wiphy, struct file *file, + char *buf, size_t bufsize, + const char __user *userbuf, size_t count, + ssize_t (*handler)(struct wiphy *wiphy, + struct file *file, + char *buf, + size_t count, + void *data), + void *data); +#endif + #endif /* __NET_CFG80211_H */ diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c index 0878b162890a..40e49074e2ee 100644 --- a/net/wireless/debugfs.c +++ b/net/wireless/debugfs.c @@ -4,6 +4,7 @@ * * Copyright 2009 Luis R. Rodriguez * Copyright 2007 Johannes Berg + * Copyright (C) 2023 Intel Corporation */ #include @@ -109,3 +110,162 @@ void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev) DEBUGFS_ADD(long_retry_limit); DEBUGFS_ADD(ht40allow_map); } + +struct debugfs_read_work { + struct wiphy_work work; + ssize_t (*handler)(struct wiphy *wiphy, + struct file *file, + char *buf, + size_t count, + void *data); + struct wiphy *wiphy; + struct file *file; + char *buf; + size_t bufsize; + void *data; + ssize_t ret; + struct completion completion; +}; + +static void wiphy_locked_debugfs_read_work(struct wiphy *wiphy, + struct wiphy_work *work) +{ + struct debugfs_read_work *w = container_of(work, typeof(*w), work); + + w->ret = w->handler(w->wiphy, w->file, w->buf, w->bufsize, w->data); + complete(&w->completion); +} + +static void wiphy_locked_debugfs_read_cancel(struct dentry *dentry, + void *data) +{ + struct debugfs_read_work *w = data; + + wiphy_work_cancel(w->wiphy, &w->work); + complete(&w->completion); +} + +ssize_t wiphy_locked_debugfs_read(struct wiphy *wiphy, struct file *file, + char *buf, size_t bufsize, + char __user *userbuf, size_t count, + loff_t *ppos, + ssize_t (*handler)(struct wiphy *wiphy, + struct file *file, + char *buf, + size_t bufsize, + void *data), + void *data) +{ + struct debugfs_read_work work = { + .handler = handler, + .wiphy = wiphy, + .file = file, + .buf = buf, + .bufsize = bufsize, + .data = data, + .ret = -ENODEV, + .completion = COMPLETION_INITIALIZER_ONSTACK(work.completion), + }; + struct debugfs_cancellation cancellation = { + .cancel = wiphy_locked_debugfs_read_cancel, + .cancel_data = &work, + }; + + /* don't leak stack data or whatever */ + memset(buf, 0, bufsize); + + wiphy_work_init(&work.work, wiphy_locked_debugfs_read_work); + wiphy_work_queue(wiphy, &work.work); + + debugfs_enter_cancellation(file, &cancellation); + wait_for_completion(&work.completion); + debugfs_leave_cancellation(file, &cancellation); + + if (work.ret < 0) + return work.ret; + + if (WARN_ON(work.ret > bufsize)) + return -EINVAL; + + return simple_read_from_buffer(userbuf, count, ppos, buf, work.ret); +} +EXPORT_SYMBOL_GPL(wiphy_locked_debugfs_read); + +struct debugfs_write_work { + struct wiphy_work work; + ssize_t (*handler)(struct wiphy *wiphy, + struct file *file, + char *buf, + size_t count, + void *data); + struct wiphy *wiphy; + struct file *file; + char *buf; + size_t count; + void *data; + ssize_t ret; + struct completion completion; +}; + +static void wiphy_locked_debugfs_write_work(struct wiphy *wiphy, + struct wiphy_work *work) +{ + struct debugfs_write_work *w = container_of(work, typeof(*w), work); + + w->ret = w->handler(w->wiphy, w->file, w->buf, w->count, w->data); + complete(&w->completion); +} + +static void wiphy_locked_debugfs_write_cancel(struct dentry *dentry, + void *data) +{ + struct debugfs_write_work *w = data; + + wiphy_work_cancel(w->wiphy, &w->work); + complete(&w->completion); +} + +ssize_t wiphy_locked_debugfs_write(struct wiphy *wiphy, + struct file *file, char *buf, size_t bufsize, + const char __user *userbuf, size_t count, + ssize_t (*handler)(struct wiphy *wiphy, + struct file *file, + char *buf, + size_t count, + void *data), + void *data) +{ + struct debugfs_write_work work = { + .handler = handler, + .wiphy = wiphy, + .file = file, + .buf = buf, + .count = count, + .data = data, + .ret = -ENODEV, + .completion = COMPLETION_INITIALIZER_ONSTACK(work.completion), + }; + struct debugfs_cancellation cancellation = { + .cancel = wiphy_locked_debugfs_write_cancel, + .cancel_data = &work, + }; + + /* mostly used for strings so enforce NUL-termination for safety */ + if (count >= bufsize) + return -EINVAL; + + memset(buf, 0, bufsize); + + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + wiphy_work_init(&work.work, wiphy_locked_debugfs_write_work); + wiphy_work_queue(wiphy, &work.work); + + debugfs_enter_cancellation(file, &cancellation); + wait_for_completion(&work.completion); + debugfs_leave_cancellation(file, &cancellation); + + return work.ret; +} +EXPORT_SYMBOL_GPL(wiphy_locked_debugfs_write); From patchwork Thu Nov 9 21:22:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 163607 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b129:0:b0:403:3b70:6f57 with SMTP id q9csp722091vqs; Thu, 9 Nov 2023 13:38:49 -0800 (PST) X-Google-Smtp-Source: AGHT+IEfHF1c9obtn84Qg55RWGmir4pT6mQDAiOwNPWr9UBNXlfg+5//SzRfuYLSRSn22Rdg2k3Y X-Received: by 2002:a17:902:e5c7:b0:1cc:4fe8:c6c6 with SMTP id u7-20020a170902e5c700b001cc4fe8c6c6mr633571plf.6.1699565928861; Thu, 09 Nov 2023 13:38:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699565928; cv=none; d=google.com; s=arc-20160816; b=kLuXT/ZG5kH6pOwMyOCI3Rg3xDK8AG6IKdH8iHBzA36SrBHLYbwBLUABueQBaLIh4X LzuPw/9WJ5fidtRGzAZcH7b1r9UCDzU9tWZmhHNYadKSv1qzjQGtnfJTODnyqQhUBq2y IRkkLvZtJKlIrOzMZMA+dUzifPrKglJsXX/iSTkYWpdcmphHZJWxNMComxyqa0RIPe+O oFSF3M5kO3FCUSDvUyduNEtil3uOrz/H6y0yGkhr3gvb6QCUVhNTvbs4hlrZ9lLJjzo9 Hj4g2886SCd56x3Cly/OyIvONjaAfjLawOeeEQnVbXsUkFK30V5s3xz6Bcpy1uqdJepl DOKw== 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=M/fWRyp8GxWkUswIUSN/tlr3Lm4Oy3tnZdgRLeTz0Zc=; fh=fr6hIKaSb7E+0K08IHhjy1pQvdN8X98xxmR7pnwhgag=; b=q5PvMcKHDJI260SsFwGSxWU6XAxMNA2H/5DOsJRjP6VFPA5Xbrb/9sa5PA0GcZ9JOT 50fKA/WOes8ueR0VrpmNA2xsi45p8EaOnm5VDGfG9FTjd8EOIeN8ok1CkZ9QDyVpuemC ruw3za9LrWtsNJ5hQCWB62FOvozeYZDvgKqvj86r9iJkyvz8mz4vDJE2k6USsDfqYJ/f +naH1DqLfS7Y2VTyOd2W1G6f8G6ceKy9GGKhQdlbAZOK4vEOqKciRGTjPTVlUyPvuk4J Rx8/JecK4MfcCzvmlc8B5JDG0KEQw5sD/HcHrbEkne02XmWeeFRHyz7tGgm35Eb77vnP XegA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=Bi3yt5dg; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id d6-20020a170902cec600b001c4401a7e18si6421968plg.382.2023.11.09.13.38.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Nov 2023 13:38:48 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=Bi3yt5dg; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 2383B8392E27; Thu, 9 Nov 2023 13:38:48 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345299AbjKIVik (ORCPT + 30 others); Thu, 9 Nov 2023 16:38:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42284 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345257AbjKIViZ (ORCPT ); Thu, 9 Nov 2023 16:38:25 -0500 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:242:246e::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84156420F; Thu, 9 Nov 2023 13:38:23 -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=M/fWRyp8GxWkUswIUSN/tlr3Lm4Oy3tnZdgRLeTz0Zc=; t=1699565903; x=1700775503; b=Bi3yt5dg4Lb471Hyb3UC9fCaGIF059ok5lmHYgDUiQCP4tS B7PqVlm7nLjPMQrRa5kX6qtLWQlu+Fiy7qv16CKFy8rSVFgk0TwQRLBdA6O8THOPCG12ylqgbyoVv yGXnmFAfWGYteseUWI5pD3LaaHv1X/OI9DfjqphV7jaQMBWPjIyIEdl6UXr/JEHyxKWgyjPvN5sVu ex69pjRF5TYLHn1aB8VgP87z68IC/WE2Q+NTFPZJ0nsZU79ZJQZQkYj8QWnWP+Jml/07EQcQqEgEK pPDwN03WyFZFOO475AUV9IWMRW8WgsdmUlZX/TeRU3x8cQfk5iwVVbMW2TJqgFJg==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.97) (envelope-from ) id 1r1CjE-00000001znF-3mWA; Thu, 09 Nov 2023 22:38:21 +0100 From: Johannes Berg To: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, Greg Kroah-Hartman , "Rafael J. Wysocki" , Nicolai Stange , Ben Greear , Johannes Berg Subject: [RFC PATCH 5/6] wifi: mac80211: use wiphy locked debugfs helpers for agg_status Date: Thu, 9 Nov 2023 22:22:57 +0100 Message-ID: <20231109222251.186dcaf8bdcc.Id4251db174cdd42519a5ef19cbb08d7ed8f65397@changeid> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231109212251.213873-7-johannes@sipsolutions.net> References: <20231109212251.213873-7-johannes@sipsolutions.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Thu, 09 Nov 2023 13:38:48 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782124043283482586 X-GMAIL-MSGID: 1782124043283482586 From: Johannes Berg The read is currently with RCU and the write can deadlock, convert both for the sake of illustration. Signed-off-by: Johannes Berg --- net/mac80211/debugfs_sta.c | 74 +++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 06e3613bf46b..5bf507ebb096 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -312,23 +312,14 @@ static ssize_t sta_aql_write(struct file *file, const char __user *userbuf, STA_OPS_RW(aql); -static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) +static ssize_t sta_agg_status_do_read(struct wiphy *wiphy, struct file *file, + char *buf, size_t bufsz, void *data) { - char *buf, *p; - ssize_t bufsz = 71 + IEEE80211_NUM_TIDS * 40; + struct sta_info *sta = data; + char *p = buf; int i; - struct sta_info *sta = file->private_data; struct tid_ampdu_rx *tid_rx; struct tid_ampdu_tx *tid_tx; - ssize_t ret; - - buf = kzalloc(bufsz, GFP_KERNEL); - if (!buf) - return -ENOMEM; - p = buf; - - rcu_read_lock(); p += scnprintf(p, bufsz + buf - p, "next dialog_token: %#02x\n", sta->ampdu_mlme.dialog_token_allocator + 1); @@ -338,8 +329,8 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, for (i = 0; i < IEEE80211_NUM_TIDS; i++) { bool tid_rx_valid; - tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[i]); - tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[i]); + tid_rx = wiphy_dereference(wiphy, sta->ampdu_mlme.tid_rx[i]); + tid_tx = wiphy_dereference(wiphy, sta->ampdu_mlme.tid_tx[i]); tid_rx_valid = test_bit(i, sta->ampdu_mlme.agg_session_valid); p += scnprintf(p, bufsz + buf - p, "%02d", i); @@ -358,31 +349,39 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, tid_tx ? skb_queue_len(&tid_tx->pending) : 0); p += scnprintf(p, bufsz + buf - p, "\n"); } - rcu_read_unlock(); - ret = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); + return p - buf; +} + +static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct sta_info *sta = file->private_data; + struct wiphy *wiphy = sta->local->hw.wiphy; + size_t bufsz = 71 + IEEE80211_NUM_TIDS * 40; + char *buf = kmalloc(bufsz, GFP_KERNEL); + ssize_t ret; + + if (!buf) + return -ENOMEM; + + ret = wiphy_locked_debugfs_read(wiphy, file, buf, bufsz, + userbuf, count, ppos, + sta_agg_status_do_read, sta); kfree(buf); + return ret; } -static ssize_t sta_agg_status_write(struct file *file, const char __user *userbuf, - size_t count, loff_t *ppos) +static ssize_t sta_agg_status_do_write(struct wiphy *wiphy, struct file *file, + char *buf, size_t count, void *data) { - char _buf[25] = {}, *buf = _buf; - struct sta_info *sta = file->private_data; + struct sta_info *sta = data; bool start, tx; unsigned long tid; - char *pos; + char *pos = buf; int ret, timeout = 5000; - if (count > sizeof(_buf)) - return -EINVAL; - - if (copy_from_user(buf, userbuf, count)) - return -EFAULT; - - buf[sizeof(_buf) - 1] = '\0'; - pos = buf; buf = strsep(&pos, " "); if (!buf) return -EINVAL; @@ -420,7 +419,6 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu if (ret || tid >= IEEE80211_NUM_TIDS) return -EINVAL; - wiphy_lock(sta->local->hw.wiphy); if (tx) { if (start) ret = ieee80211_start_tx_ba_session(&sta->sta, tid, @@ -432,10 +430,22 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu 3, true); ret = 0; } - wiphy_unlock(sta->local->hw.wiphy); return ret ?: count; } + +static ssize_t sta_agg_status_write(struct file *file, + const char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct sta_info *sta = file->private_data; + struct wiphy *wiphy = sta->local->hw.wiphy; + char _buf[26]; + + return wiphy_locked_debugfs_write(wiphy, file, _buf, sizeof(_buf), + userbuf, count, + sta_agg_status_do_write, sta); +} STA_OPS_RW(agg_status); /* link sta attributes */ From patchwork Thu Nov 9 21:22:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 163608 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b129:0:b0:403:3b70:6f57 with SMTP id q9csp722135vqs; Thu, 9 Nov 2023 13:38:57 -0800 (PST) X-Google-Smtp-Source: AGHT+IFZYwUvrQF3s9wPLu6qXii8nwD/9Z6/joX4AhyrO2CQibDVy3hKhOkqjVHxirHyX2Nsy6w+ X-Received: by 2002:a17:902:e851:b0:1c4:44a0:5c03 with SMTP id t17-20020a170902e85100b001c444a05c03mr7386426plg.9.1699565936866; Thu, 09 Nov 2023 13:38:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699565936; cv=none; d=google.com; s=arc-20160816; b=TsF50hbE3JHh+DF4wACEz2cLChqiHvinElmCm0UgXRV7A6V9XptM74yhgInA9ZF6NZ naItzq3APVJXQj5vpanHAUGIA1L8ZGvMwL1JDQFdaBK+Zpr3VFjkp/b/JT/u3LMG2dHn 3yuSnUyE+mI/gO2n4vnv+qpF/IYIfYBipiU6XPAbHAc+f6leEJk9TORztem9H//I2TWM CPq+QmZkiz5rQ762CJS/7hwLz/HQFcz0m/OC0k5t5kOjFfxHYjd5x99WeZW9j0Z+B1vJ VNKo2s1rg5yBTlTvg4TObdIyQdMNnoFJLVFjbGBYUsSN6GZO8DY7VyA9NMWp3z8ks3uv U2dg== 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=+DtEJdw1hoIddhRyJ2mVLtfdj8W1joudvJrs09mD3A4=; fh=fr6hIKaSb7E+0K08IHhjy1pQvdN8X98xxmR7pnwhgag=; b=sFjIry4Ue/I7EvggrkliYKlifoZx8hDFvC07HUGvjsaknLpKWPnQR7N7liVpSvMRuO lChaWSIpQO780r3bMHx2ajudKqzK1tatgmvAfimiUpmcj7aB/69flwtctY31uJy7AOzD NW5JOKQ+oROUCX9XhvuS/pyHDk+U4qHkHIZ3bcOdTBks/13mndoMyeJ9q6bwFBTYzwzB 1ypKiX3ZZuFKARq349OMRWDdzYeAHHrMZxW1XcZNsPMwCk+kJjFB8mspCLXuCM14zvH+ 7wP8PTvcZXxFOKcdqFJ2lhbSmw9TzHj8uFhsO3+YIcvwNmrNSMXZxEqLh/nsxiOpUJuU zWkA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=oivGQvGs; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from snail.vger.email (snail.vger.email. [23.128.96.37]) by mx.google.com with ESMTPS id kv15-20020a17090328cf00b001c9b15bf936si5312855plb.220.2023.11.09.13.38.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Nov 2023 13:38:56 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) client-ip=23.128.96.37; Authentication-Results: mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=oivGQvGs; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.37 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 854988392E25; Thu, 9 Nov 2023 13:38:55 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345308AbjKIVin (ORCPT + 30 others); Thu, 9 Nov 2023 16:38:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50714 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234678AbjKIVib (ORCPT ); Thu, 9 Nov 2023 16:38:31 -0500 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:242:246e::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D5DF22139; Thu, 9 Nov 2023 13:38:24 -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=+DtEJdw1hoIddhRyJ2mVLtfdj8W1joudvJrs09mD3A4=; t=1699565905; x=1700775505; b=oivGQvGso84+xWyeMP70VawhLwOycZqLWhdWpejaMMlG5wr t3bfh8e+lk0W+TyCRSRE0wYsVW1/2k7MdFeWmtP5sYFFujM8n78IVFZxAr3s0/UNltKEsmMRm4ajq BEV/IfGn35NAWQgCR03GbQWIQhtbk8kVYuLAV7/sWCZsoimoz53TL9ceORr5l2fIWaYZsr8VxS+zD 506/boRHbvK1j7+kdHi2628msi1LGL+iOUJdks0ini9VGoLEXpN7/a+FOzs7f3T3WkUUsT/ARRMIx exqCWN4xV8PiEQ1vVwlTGE9Ruk65YaKP5jwHA+gVzTn9bk6lMuFIDZtpWsTcPdYA==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.97) (envelope-from ) id 1r1CjF-00000001znF-4871; Thu, 09 Nov 2023 22:38:22 +0100 From: Johannes Berg To: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, Greg Kroah-Hartman , "Rafael J. Wysocki" , Nicolai Stange , Ben Greear , Johannes Berg Subject: [RFC PATCH 6/6] wifi: mac80211: use wiphy locked debugfs for sdata/link Date: Thu, 9 Nov 2023 22:22:58 +0100 Message-ID: <20231109222251.f6f6241e2541.I99a21601e124f5ac4e161ad32b19949e7896e390@changeid> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231109212251.213873-7-johannes@sipsolutions.net> References: <20231109212251.213873-7-johannes@sipsolutions.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Thu, 09 Nov 2023 13:38:55 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782124051641309923 X-GMAIL-MSGID: 1782124051641309923 From: Johannes Berg The debugfs files for netdevs (sdata) and links are removed with the wiphy mutex held, which may deadlock. Use the new wiphy locked debugfs to avoid that. Signed-off-by: Johannes Berg --- net/mac80211/debugfs_netdev.c | 150 ++++++++++++++++++++++++---------- 1 file changed, 105 insertions(+), 45 deletions(-) diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index ec91e131b29e..80aeb25f1b68 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -22,88 +22,148 @@ #include "debugfs_netdev.h" #include "driver-ops.h" +struct ieee80211_if_read_sdata_data { + ssize_t (*format)(const struct ieee80211_sub_if_data *, char *, int); + struct ieee80211_sub_if_data *sdata; +}; + +static ssize_t ieee80211_if_read_sdata_handler(struct wiphy *wiphy, + struct file *file, + char *buf, + size_t bufsize, + void *data) +{ + struct ieee80211_if_read_sdata_data *d = data; + + return d->format(d->sdata, buf, bufsize); +} + static ssize_t ieee80211_if_read_sdata( - struct ieee80211_sub_if_data *sdata, + struct file *file, char __user *userbuf, size_t count, loff_t *ppos, ssize_t (*format)(const struct ieee80211_sub_if_data *sdata, char *, int)) { + struct ieee80211_sub_if_data *sdata = file->private_data; + struct ieee80211_if_read_sdata_data data = { + .format = format, + .sdata = sdata, + }; char buf[200]; - ssize_t ret = -EINVAL; - wiphy_lock(sdata->local->hw.wiphy); - ret = (*format)(sdata, buf, sizeof(buf)); - wiphy_unlock(sdata->local->hw.wiphy); + return wiphy_locked_debugfs_read(sdata->local->hw.wiphy, + file, buf, sizeof(buf), + userbuf, count, ppos, + ieee80211_if_read_sdata_handler, + &data); +} - if (ret >= 0) - ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret); +struct ieee80211_if_write_sdata_data { + ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int); + struct ieee80211_sub_if_data *sdata; +}; - return ret; +static ssize_t ieee80211_if_write_sdata_handler(struct wiphy *wiphy, + struct file *file, + char *buf, + size_t count, + void *data) +{ + struct ieee80211_if_write_sdata_data *d = data; + + return d->write(d->sdata, buf, count); } static ssize_t ieee80211_if_write_sdata( - struct ieee80211_sub_if_data *sdata, + struct file *file, const char __user *userbuf, size_t count, loff_t *ppos, ssize_t (*write)(struct ieee80211_sub_if_data *sdata, const char *, int)) { + struct ieee80211_sub_if_data *sdata = file->private_data; + struct ieee80211_if_write_sdata_data data = { + .write = write, + .sdata = sdata, + }; char buf[64]; - ssize_t ret; - if (count >= sizeof(buf)) - return -E2BIG; + return wiphy_locked_debugfs_write(sdata->local->hw.wiphy, + file, buf, sizeof(buf), + userbuf, count, + ieee80211_if_write_sdata_handler, + &data); +} - if (copy_from_user(buf, userbuf, count)) - return -EFAULT; - buf[count] = '\0'; +struct ieee80211_if_read_link_data { + ssize_t (*format)(const struct ieee80211_link_data *, char *, int); + struct ieee80211_link_data *link; +}; - wiphy_lock(sdata->local->hw.wiphy); - ret = (*write)(sdata, buf, count); - wiphy_unlock(sdata->local->hw.wiphy); +static ssize_t ieee80211_if_read_link_handler(struct wiphy *wiphy, + struct file *file, + char *buf, + size_t bufsize, + void *data) +{ + struct ieee80211_if_read_link_data *d = data; - return ret; + return d->format(d->link, buf, bufsize); } static ssize_t ieee80211_if_read_link( - struct ieee80211_link_data *link, + struct file *file, char __user *userbuf, size_t count, loff_t *ppos, ssize_t (*format)(const struct ieee80211_link_data *link, char *, int)) { + struct ieee80211_link_data *link = file->private_data; + struct ieee80211_if_read_link_data data = { + .format = format, + .link = link, + }; char buf[200]; - ssize_t ret = -EINVAL; - wiphy_lock(link->sdata->local->hw.wiphy); - ret = (*format)(link, buf, sizeof(buf)); - wiphy_unlock(link->sdata->local->hw.wiphy); + return wiphy_locked_debugfs_read(link->sdata->local->hw.wiphy, + file, buf, sizeof(buf), + userbuf, count, ppos, + ieee80211_if_read_link_handler, + &data); +} - if (ret >= 0) - ret = simple_read_from_buffer(userbuf, count, ppos, buf, ret); +struct ieee80211_if_write_link_data { + ssize_t (*write)(struct ieee80211_link_data *, const char *, int); + struct ieee80211_link_data *link; +}; - return ret; +static ssize_t ieee80211_if_write_link_handler(struct wiphy *wiphy, + struct file *file, + char *buf, + size_t count, + void *data) +{ + struct ieee80211_if_write_sdata_data *d = data; + + return d->write(d->sdata, buf, count); } static ssize_t ieee80211_if_write_link( - struct ieee80211_link_data *link, + struct file *file, const char __user *userbuf, size_t count, loff_t *ppos, ssize_t (*write)(struct ieee80211_link_data *link, const char *, int)) { + struct ieee80211_link_data *link = file->private_data; + struct ieee80211_if_write_link_data data = { + .write = write, + .link = link, + }; char buf[64]; - ssize_t ret; - if (count >= sizeof(buf)) - return -E2BIG; - - if (copy_from_user(buf, userbuf, count)) - return -EFAULT; - buf[count] = '\0'; - - wiphy_lock(link->sdata->local->hw.wiphy); - ret = (*write)(link, buf, count); - wiphy_unlock(link->sdata->local->hw.wiphy); - - return ret; + return wiphy_locked_debugfs_write(link->sdata->local->hw.wiphy, + file, buf, sizeof(buf), + userbuf, count, + ieee80211_if_write_link_handler, + &data); } #define IEEE80211_IF_FMT(name, type, field, format_string) \ @@ -173,7 +233,7 @@ static ssize_t ieee80211_if_read_##name(struct file *file, \ char __user *userbuf, \ size_t count, loff_t *ppos) \ { \ - return ieee80211_if_read_sdata(file->private_data, \ + return ieee80211_if_read_sdata(file, \ userbuf, count, ppos, \ ieee80211_if_fmt_##name); \ } @@ -183,7 +243,7 @@ static ssize_t ieee80211_if_write_##name(struct file *file, \ const char __user *userbuf, \ size_t count, loff_t *ppos) \ { \ - return ieee80211_if_write_sdata(file->private_data, userbuf, \ + return ieee80211_if_write_sdata(file, userbuf, \ count, ppos, \ ieee80211_if_parse_##name); \ } @@ -211,7 +271,7 @@ static ssize_t ieee80211_if_read_##name(struct file *file, \ char __user *userbuf, \ size_t count, loff_t *ppos) \ { \ - return ieee80211_if_read_link(file->private_data, \ + return ieee80211_if_read_link(file, \ userbuf, count, ppos, \ ieee80211_if_fmt_##name); \ } @@ -221,7 +281,7 @@ static ssize_t ieee80211_if_write_##name(struct file *file, \ const char __user *userbuf, \ size_t count, loff_t *ppos) \ { \ - return ieee80211_if_write_link(file->private_data, userbuf, \ + return ieee80211_if_write_link(file, userbuf, \ count, ppos, \ ieee80211_if_parse_##name); \ }