Received: by 2002:a05:7412:419a:b0:f3:1519:9f41 with SMTP id i26csp1270410rdh; Fri, 24 Nov 2023 08:35:48 -0800 (PST) X-Google-Smtp-Source: AGHT+IFUCf1ZawZR2uI6s470hyI07LA+rAJWdS3Be3U1ObwUQYbf5kOifZU0BkvaQqxU1rpZ44Bo X-Received: by 2002:a17:902:f544:b0:1cc:29ef:df7d with SMTP id h4-20020a170902f54400b001cc29efdf7dmr4712206plf.65.1700843747751; Fri, 24 Nov 2023 08:35:47 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700843747; cv=none; d=google.com; s=arc-20160816; b=yPnt1QMQTk9gHn0Oq53wOcnTqXAwcWIAtGbOy4IIBjRlcR1f51aWZyWoQoaDP7GWMl CNdlw9Zor5fQWQxEGyC35ki8Z59wC9zF7KsA7gqpUfTJDTIsHhue0TNqtiKJjPOzP1q6 jxAd2cr1PjajmpgdyYrDRjtoqkWw+ZJKfybSSUfEUYEUPuitLXYECMUSHb390p2PMSPl eKFfTC9s08ZAeVfxt6AGL3j96af+d0+z+OHKE5zcKoy/Pl6L7i4TxwIWSLSS6zNQ/meI GBCqWntZeHXp5k/qaa5demKm/9E3W926zkIGH5wbx6EBR2D/Xqorr1ZzfWJyct+ew5O9 1YyQ== 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=MUXidifnbmrT+lPICjftrAHoNPFMVQW1b1Sa6v/Ia/k=; fh=A9B0uqHrLOhV8lpdKrDO+2kao9UNQ/xn2a9tcpNN72M=; b=X6qzuMK8UoEiAa2MgtAPOx6zhAEo2Mi/aOFD5OqPJJIQIjRbQ5cca03X8oe8Ev0Mql w3dyX6YCk8x/prD6IzFGhGSVQnetkAWzkSpr6hPyxUEoM5pjfhgpyPE/B8IlAJFWbuz6 mg95p0YSp227ezXAhun7cE3IbLOPnYWJOxZAeFprwCXg321OpXBQI7U1wqG43e9P/Zk9 RIdOXvMVsgOb33mrTlHg3MKQ9vsvqEpp7uYqmAvqi93r9ghDsEvDqHRt5RUd2NsRXa1f FeIb8Mqnq3h32dpny3YdFZhoRhP3b7+aT5z6ZA8fsa8Eht5xdWUlfR4+wQThtcBGUYxM a9eQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=rVyZeHaC; spf=pass (google.com: domain of linux-wireless+bounces-59-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-wireless+bounces-59-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id k7-20020a170902c40700b001cf57827c7asi4021757plk.147.2023.11.24.08.35.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 08:35:47 -0800 (PST) Received-SPF: pass (google.com: domain of linux-wireless+bounces-59-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=rVyZeHaC; spf=pass (google.com: domain of linux-wireless+bounces-59-linux.lists.archive=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-wireless+bounces-59-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 sv.mirrors.kernel.org (Postfix) with ESMTPS id 3A0FE2813F3 for ; Fri, 24 Nov 2023 16:35:47 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DFF12381AE; Fri, 24 Nov 2023 16:35:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=sipsolutions.net header.i=@sipsolutions.net header.b="rVyZeHaC" 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 4255C19A9; Fri, 24 Nov 2023 08:35: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=MUXidifnbmrT+lPICjftrAHoNPFMVQW1b1Sa6v/Ia/k=; t=1700843722; x=1702053322; b=rVyZeHaCbEZbZ/qU3M0JI/yJBcit7AjwfmuBpVQ/QywYqBU 7pdJrYkha5hv1CKNwS35NhFbYRdXInHXjyT5jF/hbcpyrm8LsWSXWArZc87cMW/BuKUcDRZX0GJoz jU1BymzxgmpUjJDLjKSfSoRCE4xlG7hVRrhXWDbUGiR5N+rf/YLvnSvEhyD02Tb0eW1w5OS5d3qf3 VBEo5vicYBFgAPZGkS9BRWP5AGToNPotZZPLnNV5rJPOCfpGwa+ECmJUgppDTqLXXuZ6VGUw9G8q6 ycvXPpCN8jPrYTtM52HXY+9stPrpWBiVxFojmTuRQZha78XJzzGRNu3Fl4k2d6Yw==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.97) (envelope-from ) id 1r6Z9D-00000002fA8-3DhM; Fri, 24 Nov 2023 17:35:20 +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 6/6] wifi: mac80211: use wiphy locked debugfs for sdata/link Date: Fri, 24 Nov 2023 17:25:29 +0100 Message-ID: <20231124172522.98baff0ebc5e.I99a21601e124f5ac4e161ad32b19949e7896e390@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 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); \ } -- 2.42.0