Received: by 2002:a05:6a10:1d13:0:0:0:0 with SMTP id pp19csp2895141pxb; Tue, 24 Aug 2021 10:04:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJy5KP8dti6JzbdUn/++XBNI3+xi+x0cWFxcrK8y8sTtlR+YnaW69ISGkdbeUwT/VLQ4yd+i X-Received: by 2002:a17:906:7ad7:: with SMTP id k23mr29779107ejo.405.1629824645942; Tue, 24 Aug 2021 10:04:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1629824645; cv=none; d=google.com; s=arc-20160816; b=DlKE6k3BHLX8sgqlEWMflfyb5C+wk2o2H14CVVn+QkVdEsf6FxmHsjxpB9n40soR4K m55DuHymB46aKqriuwVnfNR3JIxumwE0Q38EDD095Y+6fUdGgEhYWzgmchiIobgWlhYP 7MRis9psx3zKz9pVGz6akxCgT4B+DGimTnv+R5KUqVNG6R/Ldj4RkD1SM2ncHJn8ZYkt B6ojxsCoQbi/ox1gmxipAGQuNmoviWR1/lkNYDldWd/P2czPtNWzhiYQgFzn042edU4x D/gRVIJNrcFg88IT42tBzLGVLbhfSTgUrJtHBLF05xz0DeOk8d75gQLOoZkA53yzVmpV 8X8Q== 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=ZocpSrQ2qxBEQ/gbS9LuWBw7lLD81R/n6VvMptJpDKo=; b=cdF8Tq5uSaT1814jwqcsSn/Owuk5CgMCdlFkCA1xFeCqhXHNKJhF8B4BHKC8TnQhhT kmeXEOJXZe1ad1NbXx637v500OuxUyJp0THbYYcQ7C8A0O8VOdLY0k9ZpKhlMxL6g/48 lPg/X/rPCQIGNtXfw/qJhxO+E3hszVSa9gQy9s0EUzUvNNxZsUVzXJAVgxvsSJ/0ViCO FnvC15xB1U3B0C5R3PzptDKMQlNVCu9/1DrydOcTQlFpYW8bqWWPGR4icBwBMITSDWwd j2x5Uv2gkDZu0P3iZiZ7MO+JwgNpCLRxUPs28ATOFehpqYps7PRe6oqF3yPUTStIOzzy bNWQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="e/qKY/ap"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id da27si3287490edb.317.2021.08.24.10.03.09; Tue, 24 Aug 2021 10:04:05 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="e/qKY/ap"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233606AbhHXRAF (ORCPT + 99 others); Tue, 24 Aug 2021 13:00:05 -0400 Received: from mail.kernel.org ([198.145.29.99]:39458 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230087AbhHXQ5z (ORCPT ); Tue, 24 Aug 2021 12:57:55 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id D8B1061373; Tue, 24 Aug 2021 16:56:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1629824218; bh=jJbJhh5A1KzclL7VUWa5dcUIHZoPOJLaByE9B3ygb9E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e/qKY/apSoLl9pdvjng88suKOYXJq7jp2nabWgQrTCgF/Jtjfuvji9ThgXZoikmfn AQ9MPDSVubrD2OOCf/Ek5qpZXoHVxGflBFFFYQAySPwcrxxBUdg8RLpKJGjaVc6QBq rBNI+ysIpxkUC1J1BUNJfXP5LO/acPyqjJpse2TIeGNRdtS5zjz5Ne2QevyOsFU3KH uR/eDvPJc90oVa3Hacczv6IoX//Lstb/SsPYGCWfeSvwzKDETRIX7E8yi5SMIi8Aif 3apjJg+JQ/mehy/HdFOKiPHsMNTNJaUkTAIUSNYqt78U9NXA9fTADAwfHB8kxherRq revnUeydzwUUw== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Jakub Kicinski , Michael Chan , Edwin Peer , Sasha Levin Subject: [PATCH 5.13 051/127] bnxt: don't lock the tx queue from napi poll Date: Tue, 24 Aug 2021 12:54:51 -0400 Message-Id: <20210824165607.709387-52-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210824165607.709387-1-sashal@kernel.org> References: <20210824165607.709387-1-sashal@kernel.org> MIME-Version: 1.0 X-KernelTest-Patch: http://kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.13.13-rc1.gz X-KernelTest-Tree: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git X-KernelTest-Branch: linux-5.13.y X-KernelTest-Patches: git://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git X-KernelTest-Version: 5.13.13-rc1 X-KernelTest-Deadline: 2021-08-26T16:55+00:00 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jakub Kicinski [ Upstream commit 3c603136c9f82833813af77185618de5af67676c ] We can't take the tx lock from the napi poll routine, because netpoll can poll napi at any moment, including with the tx lock already held. The tx lock is protecting against two paths - the disable path, and (as Michael points out) the NETDEV_TX_BUSY case which may occur if NAPI completions race with start_xmit and both decide to re-enable the queue. For the disable/ifdown path use synchronize_net() to make sure closing the device does not race we restarting the queues. Annotate accesses to dev_state against data races. For the NAPI cleanup vs start_xmit path - appropriate barriers are already in place in the main spot where Tx queue is stopped but we need to do the same careful dance in the TX_BUSY case. Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.") Reviewed-by: Michael Chan Reviewed-by: Edwin Peer Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 54 ++++++++++++++--------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 3c3aa9467310..d0b3be7b1c1a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -362,6 +362,26 @@ static u16 bnxt_xmit_get_cfa_action(struct sk_buff *skb) return md_dst->u.port_info.port_id; } +static bool bnxt_txr_netif_try_stop_queue(struct bnxt *bp, + struct bnxt_tx_ring_info *txr, + struct netdev_queue *txq) +{ + netif_tx_stop_queue(txq); + + /* netif_tx_stop_queue() must be done before checking + * tx index in bnxt_tx_avail() below, because in + * bnxt_tx_int(), we update tx index before checking for + * netif_tx_queue_stopped(). + */ + smp_mb(); + if (bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh) { + netif_tx_wake_queue(txq); + return false; + } + + return true; +} + static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct bnxt *bp = netdev_priv(dev); @@ -390,8 +410,8 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) free_size = bnxt_tx_avail(bp, txr); if (unlikely(free_size < skb_shinfo(skb)->nr_frags + 2)) { - netif_tx_stop_queue(txq); - return NETDEV_TX_BUSY; + if (bnxt_txr_netif_try_stop_queue(bp, txr, txq)) + return NETDEV_TX_BUSY; } length = skb->len; @@ -605,16 +625,7 @@ tx_done: if (netdev_xmit_more() && !tx_buf->is_push) bnxt_db_write(bp, &txr->tx_db, prod); - netif_tx_stop_queue(txq); - - /* netif_tx_stop_queue() must be done before checking - * tx index in bnxt_tx_avail() below, because in - * bnxt_tx_int(), we update tx index before checking for - * netif_tx_queue_stopped(). - */ - smp_mb(); - if (bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh) - netif_tx_wake_queue(txq); + bnxt_txr_netif_try_stop_queue(bp, txr, txq); } return NETDEV_TX_OK; @@ -698,14 +709,9 @@ next_tx_int: smp_mb(); if (unlikely(netif_tx_queue_stopped(txq)) && - (bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh)) { - __netif_tx_lock(txq, smp_processor_id()); - if (netif_tx_queue_stopped(txq) && - bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh && - txr->dev_state != BNXT_DEV_STATE_CLOSING) - netif_tx_wake_queue(txq); - __netif_tx_unlock(txq); - } + bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh && + READ_ONCE(txr->dev_state) != BNXT_DEV_STATE_CLOSING) + netif_tx_wake_queue(txq); } static struct page *__bnxt_alloc_rx_page(struct bnxt *bp, dma_addr_t *mapping, @@ -9055,9 +9061,11 @@ void bnxt_tx_disable(struct bnxt *bp) if (bp->tx_ring) { for (i = 0; i < bp->tx_nr_rings; i++) { txr = &bp->tx_ring[i]; - txr->dev_state = BNXT_DEV_STATE_CLOSING; + WRITE_ONCE(txr->dev_state, BNXT_DEV_STATE_CLOSING); } } + /* Make sure napi polls see @dev_state change */ + synchronize_net(); /* Drop carrier first to prevent TX timeout */ netif_carrier_off(bp->dev); /* Stop all TX queues */ @@ -9071,8 +9079,10 @@ void bnxt_tx_enable(struct bnxt *bp) for (i = 0; i < bp->tx_nr_rings; i++) { txr = &bp->tx_ring[i]; - txr->dev_state = 0; + WRITE_ONCE(txr->dev_state, 0); } + /* Make sure napi polls see @dev_state change */ + synchronize_net(); netif_tx_wake_all_queues(bp->dev); if (bp->link_info.link_up) netif_carrier_on(bp->dev); -- 2.30.2