From patchwork Mon Jan 6 06:39:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 11318737 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C131E921 for ; Mon, 6 Jan 2020 06:39:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A335521775 for ; Mon, 6 Jan 2020 06:39:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727458AbgAFGje (ORCPT ); Mon, 6 Jan 2020 01:39:34 -0500 Received: from mx2.suse.de ([195.135.220.15]:42582 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726338AbgAFGje (ORCPT ); Mon, 6 Jan 2020 01:39:34 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id C832AADBE; Mon, 6 Jan 2020 06:39:31 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id 7A388E048A; Mon, 6 Jan 2020 07:39:31 +0100 (CET) Message-Id: <27c09c8633c2c34a78ae528e5f4850bcd964acc7.1578292157.git.mkubecek@suse.cz> In-Reply-To: References: From: Michal Kubecek Subject: [PATCH net-next v2 1/3] wil6210: get rid of begin() and complete() ethtool_ops To: "David S. Miller" , netdev@vger.kernel.org Cc: Maya Erez , Kalle Valo , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com, Francois Romieu , linux-kernel@vger.kernel.org, Andrew Lunn , Florian Fainelli Date: Mon, 6 Jan 2020 07:39:31 +0100 (CET) Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org The wil6210 driver locks a mutex in begin() ethtool_ops callback and unlocks it in complete() so that all ethtool requests are serialized. This is not going to work correctly with netlink interface; e.g. when ioctl triggers a netlink notification, netlink code would call begin() again while the mutex taken by ioctl code is still held by the same task. Let's get rid of the begin() and complete() callbacks and move the mutex locking into the remaining ethtool_ops handlers except get_drvinfo which only copies strings that are not changing so that there is no need for serialization. Signed-off-by: Michal Kubecek Reviewed-by: Florian Fainelli --- drivers/net/wireless/ath/wil6210/ethtool.c | 43 ++++++++-------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/ethtool.c b/drivers/net/wireless/ath/wil6210/ethtool.c index 912c4eaf017b..fef10886ca4a 100644 --- a/drivers/net/wireless/ath/wil6210/ethtool.c +++ b/drivers/net/wireless/ath/wil6210/ethtool.c @@ -11,26 +11,6 @@ #include "wil6210.h" -static int wil_ethtoolops_begin(struct net_device *ndev) -{ - struct wil6210_priv *wil = ndev_to_wil(ndev); - - mutex_lock(&wil->mutex); - - wil_dbg_misc(wil, "ethtoolops_begin\n"); - - return 0; -} - -static void wil_ethtoolops_complete(struct net_device *ndev) -{ - struct wil6210_priv *wil = ndev_to_wil(ndev); - - wil_dbg_misc(wil, "ethtoolops_complete\n"); - - mutex_unlock(&wil->mutex); -} - static int wil_ethtoolops_get_coalesce(struct net_device *ndev, struct ethtool_coalesce *cp) { @@ -39,11 +19,12 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev, u32 rx_itr_en, rx_itr_val = 0; int ret; + mutex_lock(&wil->mutex); wil_dbg_misc(wil, "ethtoolops_get_coalesce\n"); ret = wil_pm_runtime_get(wil); if (ret < 0) - return ret; + goto out; tx_itr_en = wil_r(wil, RGF_DMA_ITR_TX_CNT_CTL); if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN) @@ -57,7 +38,11 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev, cp->tx_coalesce_usecs = tx_itr_val; cp->rx_coalesce_usecs = rx_itr_val; - return 0; + ret = 0; + +out: + mutex_unlock(&wil->mutex); + return ret; } static int wil_ethtoolops_set_coalesce(struct net_device *ndev, @@ -67,12 +52,14 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev, struct wireless_dev *wdev = ndev->ieee80211_ptr; int ret; + mutex_lock(&wil->mutex); wil_dbg_misc(wil, "ethtoolops_set_coalesce: rx %d usec, tx %d usec\n", cp->rx_coalesce_usecs, cp->tx_coalesce_usecs); if (wdev->iftype == NL80211_IFTYPE_MONITOR) { wil_dbg_misc(wil, "No IRQ coalescing in monitor mode\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } /* only @rx_coalesce_usecs and @tx_coalesce_usecs supported, @@ -88,24 +75,26 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev, ret = wil_pm_runtime_get(wil); if (ret < 0) - return ret; + goto out; wil->txrx_ops.configure_interrupt_moderation(wil); wil_pm_runtime_put(wil); + ret = 0; - return 0; +out: + mutex_unlock(&wil->mutex); + return ret; out_bad: wil_dbg_misc(wil, "Unsupported coalescing params. Raw command:\n"); print_hex_dump_debug("DBG[MISC] coal ", DUMP_PREFIX_OFFSET, 16, 4, cp, sizeof(*cp), false); + mutex_unlock(&wil->mutex); return -EINVAL; } static const struct ethtool_ops wil_ethtool_ops = { - .begin = wil_ethtoolops_begin, - .complete = wil_ethtoolops_complete, .get_drvinfo = cfg80211_get_drvinfo, .get_coalesce = wil_ethtoolops_get_coalesce, .set_coalesce = wil_ethtoolops_set_coalesce, From patchwork Mon Jan 6 06:39:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 11318739 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8AB641398 for ; Mon, 6 Jan 2020 06:39:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 72F9321775 for ; Mon, 6 Jan 2020 06:39:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727506AbgAFGjk (ORCPT ); Mon, 6 Jan 2020 01:39:40 -0500 Received: from mx2.suse.de ([195.135.220.15]:42598 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727496AbgAFGji (ORCPT ); Mon, 6 Jan 2020 01:39:38 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id CC754ADBE; Mon, 6 Jan 2020 06:39:36 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id 7E191E048A; Mon, 6 Jan 2020 07:39:36 +0100 (CET) Message-Id: In-Reply-To: References: From: Michal Kubecek Subject: [PATCH net-next v2 2/3] via-velocity: allow nesting of ethtool_ops begin() and complete() To: "David S. Miller" , netdev@vger.kernel.org Cc: Maya Erez , Kalle Valo , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com, Francois Romieu , linux-kernel@vger.kernel.org, Andrew Lunn , Florian Fainelli Date: Mon, 6 Jan 2020 07:39:36 +0100 (CET) Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Unlike most networking drivers using begin() and complete() ethtool_ops callbacks to resume a device which is down and suspend it again when done, via-velocity does not use standard refcounted infrastructure but sets device sleep state directly. With the introduction of netlink ethtool interface, we may have nested begin-complete blocks so that inner complete() would put the device back to sleep for the rest of the outer block. To avoid rewriting an old and not very actively developed driver, just add a nesting counter and only perform resume and suspend on the outermost level. Signed-off-by: Michal Kubecek --- drivers/net/ethernet/via/via-velocity.c | 14 ++++++++++---- drivers/net/ethernet/via/via-velocity.h | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index 346e44115c4e..4b556b74541a 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c @@ -3257,12 +3257,16 @@ static struct platform_driver velocity_platform_driver = { * @dev: network device * * Called before an ethtool operation. We need to make sure the - * chip is out of D3 state before we poke at it. + * chip is out of D3 state before we poke at it. In case of ethtool + * ops nesting, only wake the device up in the outermost block. */ static int velocity_ethtool_up(struct net_device *dev) { struct velocity_info *vptr = netdev_priv(dev); - if (!netif_running(dev)) + + if (vptr->ethtool_ops_nesting == U32_MAX) + return -EBUSY; + if (!vptr->ethtool_ops_nesting++ && !netif_running(dev)) velocity_set_power_state(vptr, PCI_D0); return 0; } @@ -3272,12 +3276,14 @@ static int velocity_ethtool_up(struct net_device *dev) * @dev: network device * * Called after an ethtool operation. Restore the chip back to D3 - * state if it isn't running. + * state if it isn't running. In case of ethtool ops nesting, only + * put the device to sleep in the outermost block. */ static void velocity_ethtool_down(struct net_device *dev) { struct velocity_info *vptr = netdev_priv(dev); - if (!netif_running(dev)) + + if (!--vptr->ethtool_ops_nesting && !netif_running(dev)) velocity_set_power_state(vptr, PCI_D3hot); } diff --git a/drivers/net/ethernet/via/via-velocity.h b/drivers/net/ethernet/via/via-velocity.h index cdfe7809e3c1..f196e71d2c04 100644 --- a/drivers/net/ethernet/via/via-velocity.h +++ b/drivers/net/ethernet/via/via-velocity.h @@ -1483,6 +1483,7 @@ struct velocity_info { struct velocity_context context; u32 ticks; + u32 ethtool_ops_nesting; u8 rev_id; From patchwork Mon Jan 6 06:39:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Kubecek X-Patchwork-Id: 11318743 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0EDE5921 for ; Mon, 6 Jan 2020 06:39:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E91AB21775 for ; Mon, 6 Jan 2020 06:39:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727532AbgAFGjo (ORCPT ); Mon, 6 Jan 2020 01:39:44 -0500 Received: from mx2.suse.de ([195.135.220.15]:42620 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727522AbgAFGjn (ORCPT ); Mon, 6 Jan 2020 01:39:43 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id D0BECADBE; Mon, 6 Jan 2020 06:39:41 +0000 (UTC) Received: by unicorn.suse.cz (Postfix, from userid 1000) id 847C5E048A; Mon, 6 Jan 2020 07:39:41 +0100 (CET) Message-Id: <4d6d90454847364e49b104caf5736493170f2bea.1578292157.git.mkubecek@suse.cz> In-Reply-To: References: From: Michal Kubecek Subject: [PATCH net-next v2 3/3] epic100: allow nesting of ethtool_ops begin() and complete() To: "David S. Miller" , netdev@vger.kernel.org Cc: Maya Erez , Kalle Valo , linux-wireless@vger.kernel.org, wil6210@qti.qualcomm.com, Francois Romieu , linux-kernel@vger.kernel.org, Andrew Lunn , Florian Fainelli Date: Mon, 6 Jan 2020 07:39:41 +0100 (CET) Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org Unlike most networking drivers using begin() and complete() ethtool_ops callbacks to resume a device which is down and suspend it again when done, epic100 does not use standard refcounted infrastructure but sets device sleep state directly. With the introduction of netlink ethtool interface, we may have nested begin-complete blocks so that inner complete() would put the device back to sleep for the rest of the outer block. To avoid rewriting an old and not very actively developed driver, just add a nesting counter and only perform resume and suspend on the outermost level. Signed-off-by: Michal Kubecek --- v2: fix inverted condition in ethtool_begin() (thanks to Andrew Lunn) --- drivers/net/ethernet/smsc/epic100.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/smsc/epic100.c b/drivers/net/ethernet/smsc/epic100.c index 912760e8514c..61ddee0c2a2e 100644 --- a/drivers/net/ethernet/smsc/epic100.c +++ b/drivers/net/ethernet/smsc/epic100.c @@ -280,6 +280,7 @@ struct epic_private { signed char phys[4]; /* MII device addresses. */ u16 advertising; /* NWay media advertisement */ int mii_phy_cnt; + u32 ethtool_ops_nesting; struct mii_if_info mii; unsigned int tx_full:1; /* The Tx queue is full. */ unsigned int default_port:4; /* Last dev->if_port value. */ @@ -1435,8 +1436,10 @@ static int ethtool_begin(struct net_device *dev) struct epic_private *ep = netdev_priv(dev); void __iomem *ioaddr = ep->ioaddr; + if (ep->ethtool_ops_nesting == U32_MAX) + return -EBUSY; /* power-up, if interface is down */ - if (!netif_running(dev)) { + if (!ep->ethtool_ops_nesting++ && !netif_running(dev)) { ew32(GENCTL, 0x0200); ew32(NVCTL, (er32(NVCTL) & ~0x003c) | 0x4800); } @@ -1449,7 +1452,7 @@ static void ethtool_complete(struct net_device *dev) void __iomem *ioaddr = ep->ioaddr; /* power-down, if interface is down */ - if (!netif_running(dev)) { + if (!--ep->ethtool_ops_nesting && !netif_running(dev)) { ew32(GENCTL, 0x0008); ew32(NVCTL, (er32(NVCTL) & ~0x483c) | 0x0000); }