From patchwork Thu Apr 25 12:42:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: tanhuazhong X-Patchwork-Id: 1090749 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=huawei.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 44qcND5CQqz9sBp for ; Thu, 25 Apr 2019 22:45:16 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731411AbfDYMoQ (ORCPT ); Thu, 25 Apr 2019 08:44:16 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:40704 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1731336AbfDYMoL (ORCPT ); Thu, 25 Apr 2019 08:44:11 -0400 Received: from DGGEMS407-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 253049DCD2CD5B4733C5; Thu, 25 Apr 2019 20:44:09 +0800 (CST) Received: from localhost.localdomain (10.67.212.132) by DGGEMS407-HUB.china.huawei.com (10.3.19.207) with Microsoft SMTP Server id 14.3.439.0; Thu, 25 Apr 2019 20:44:02 +0800 From: Huazhong Tan To: CC: , , , , , , Yunsheng Lin , Peng Li , Huazhong Tan Subject: [PATCH V3 net-next 01/11] net: hns3: fix data race between ring->next_to_clean Date: Thu, 25 Apr 2019 20:42:45 +0800 Message-ID: <1556196175-65389-2-git-send-email-tanhuazhong@huawei.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1556196175-65389-1-git-send-email-tanhuazhong@huawei.com> References: <1556196175-65389-1-git-send-email-tanhuazhong@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.132] X-CFilter-Loop: Reflected Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Yunsheng Lin 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 --- 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 176d4b9..9fdc87e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -2214,14 +2214,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 cec56a5..2b4f5ea 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h @@ -581,8 +581,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;