From patchwork Mon Aug 19 22:11:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: dann frazier X-Patchwork-Id: 1149644 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46C7VP503yz9sN6; Tue, 20 Aug 2019 08:13:33 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1hzpu5-0003u6-TG; Mon, 19 Aug 2019 22:13:29 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1hzpu2-0003t6-2a for kernel-team@lists.ubuntu.com; Mon, 19 Aug 2019 22:13:26 +0000 Received: from mail-io1-f70.google.com ([209.85.166.70]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1hzpu1-0008Ac-LY for kernel-team@lists.ubuntu.com; Mon, 19 Aug 2019 22:13:25 +0000 Received: by mail-io1-f70.google.com with SMTP id e17so5590598ioh.13 for ; Mon, 19 Aug 2019 15:13:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fe2X4DaZncxw0pODkKlJSOU5aCP5Tg1rfRd2jeTxK4I=; b=NxXUppcXCXaM59ijPpYsN4KtvqsXVHqISRzUJTAfds9A5wniSW6sW7zTPYGEJffl8c E7wou5geRjVWF6ziIlQOf0l2/zsIJdiLzaxbTdQLup9GRkpQqEmaD2MAOu5+LY+cDKno yH/V+AIwYkeLV7fkSjE+yWXEE5Ecuk7VVIfSpIsxN8scrXXn41HCwOk6+lvXmCIPjz07 TB7dltWHCM79f0hYkHPYqO+/6Ao9T238nXVxAx+IA+QX3qP94PQki5iAk5ykzznEuPvr gnpr9DiasEcRG8kOGJBi/Ou8fVtFh0NOojKqjbIpNWZvGKADxNFDGAHvdJfGILFvHRgG mlyw== X-Gm-Message-State: APjAAAVGDMq/lWWYIlwz5D7dfFejnr00ucoG9cr3i2/oC5oCcPv1KZzk qFvykrGqMQHwRPJwIQuwXabUIODwgfO/wG0R1hmCXiv5n1CMS2Ff07gy6axx1y3/CSFZqCeuku7 5oG20QY7/VdPwQ4gcfZ+uqfGcWmqeiR6lwHMVqole6g== X-Received: by 2002:a6b:b4c5:: with SMTP id d188mr26577326iof.96.1566252804464; Mon, 19 Aug 2019 15:13:24 -0700 (PDT) X-Google-Smtp-Source: APXvYqzc7MCxXNYrz5rJXwkZgW/6i+15Mo0dOPThqedotpUEy058wOwKMqW3ja47iZx3rkm3isORCw== X-Received: by 2002:a6b:b4c5:: with SMTP id d188mr26577303iof.96.1566252804164; Mon, 19 Aug 2019 15:13:24 -0700 (PDT) Received: from xps13.canonical.com (c-71-56-235-36.hsd1.co.comcast.net. [71.56.235.36]) by smtp.gmail.com with ESMTPSA id y5sm16125334ioc.86.2019.08.19.15.13.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Aug 2019 15:13:23 -0700 (PDT) From: dann frazier To: kernel-team@lists.ubuntu.com Subject: [PATCH 2/3][SRU Bionic] net: hns3: fix data race between ring->next_to_clean Date: Mon, 19 Aug 2019 16:11:10 -0600 Message-Id: <20190819221111.18733-3-dann.frazier@canonical.com> X-Mailer: git-send-email 2.23.0.rc1 In-Reply-To: <20190819221111.18733-1-dann.frazier@canonical.com> References: <20190819221111.18733-1-dann.frazier@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Yunsheng Lin BugLink: https://bugs.launchpad.net/bugs/1840717 hns3_clean_tx_ring calls hns3_nic_reclaim_one_desc to clean buffers and set ring->next_to_clean, then hns3_nic_net_xmit reuses the cleaned buffers. But there are no memory barriers when buffers gets recycled, so the recycled buffers can be corrupted. This patch uses smp_store_release to update ring->next_to_clean and smp_load_acquire to read ring->next_to_clean to properly hand off buffers from hns3_clean_tx_ring to hns3_nic_net_xmit. Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC") Signed-off-by: Yunsheng Lin Signed-off-by: Peng Li Signed-off-by: Huazhong Tan Signed-off-by: David S. Miller (cherry picked from commit 26cda2f1613878d9bde11325559f4fca92fff395) Signed-off-by: dann frazier --- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 14 +++++++++++--- drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 7 +++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c index 08718f9093dc5..99815c45c9a8f 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -2112,14 +2112,22 @@ static void hns3_reuse_buffer(struct hns3_enet_ring *ring, int i) static void hns3_nic_reclaim_one_desc(struct hns3_enet_ring *ring, int *bytes, int *pkts) { - struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_clean]; + int ntc = ring->next_to_clean; + struct hns3_desc_cb *desc_cb; + desc_cb = &ring->desc_cb[ntc]; (*pkts) += (desc_cb->type == DESC_TYPE_SKB); (*bytes) += desc_cb->length; /* desc_cb will be cleaned, after hnae3_free_buffer_detach*/ - hns3_free_buffer_detach(ring, ring->next_to_clean); + hns3_free_buffer_detach(ring, ntc); - ring_ptr_move_fw(ring, next_to_clean); + if (++ntc == ring->desc_num) + ntc = 0; + + /* This smp_store_release() pairs with smp_load_acquire() in + * ring_space called by hns3_nic_net_xmit. + */ + smp_store_release(&ring->next_to_clean, ntc); } static int is_valid_clean_head(struct hns3_enet_ring *ring, int h) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h index 77f6e6cf3fead..0553022ad6db4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -572,8 +572,11 @@ union l4_hdr_info { static inline int ring_space(struct hns3_enet_ring *ring) { - int begin = ring->next_to_clean; - int end = ring->next_to_use; + /* This smp_load_acquire() pairs with smp_store_release() in + * hns3_nic_reclaim_one_desc called by hns3_clean_tx_ring. + */ + int begin = smp_load_acquire(&ring->next_to_clean); + int end = READ_ONCE(ring->next_to_use); return ((end >= begin) ? (ring->desc_num - end + begin) : (begin - end)) - 1;