Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp2097540yba; Sun, 21 Apr 2019 23:47:17 -0700 (PDT) X-Google-Smtp-Source: APXvYqzjrqzJAjDswE9O7il3tb946Xo9rvDlGY20n9NumgOMYMi2Rfu0Kth93GEspXLq8Rq4OnQt X-Received: by 2002:a63:f315:: with SMTP id l21mr4707283pgh.417.1555915637005; Sun, 21 Apr 2019 23:47:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1555915636; cv=none; d=google.com; s=arc-20160816; b=DAq+E5kHpzk8LenG4rzUkT1IRscVVDvej5hPRPfPlaNIgbUtWSHNWyLba9a4ghQ2Wt lkQ/U/NHZS4HR4AxJTkonlyJHPUlXLH9VLzII4xekz7YDj1MtTjJKlEpE00S0zo51pXO sJt1KK2YxuC1Os9z3Gm7zov109dthT0BnDoK/RlxjOfJToPKq3kGjbNJtNue+zIDrO1P iGVSV0H/+6iqrURRYiG8xQn//zECbMSEQ8WRl4qpW1Nhut/2mLDGiJrSzVCheEb6t3x4 NpucW9l36wQhf6gfyhMEfunsMNOYd3G/O+VPK0y2Cyg+D0RSkv8li7CJlcw8RQUVbfse 7+1A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=Eb/1ko9WNVIFMbIK+st9R/i3T2cm5njaOwilXWSIyrM=; b=YbiSo5+YZkm/mrttxSSvRpgL9RatXa8fHxcngCoIfsqxQmkXIjQU3QZ79jWDTUM+7S 9l+Gm6vHwsog2MrZK9mHparYbYLb+3gnqoZTols8O9YKecen0y0UWYav9rPvi6kniAAs SYyOFuStS9bpwxI31pT89pftYmR5TK01HmRRH0lPmTfPTSUbBtqeurb9LLH/DcyOJ9Ps plGZZsSqVh9mxT82nE1SOr1btyZxzhyj5sVhh1sAPtIqjEwvbr4XVQmvqdLhd0k2pH4X xhP5V9VPlk5SeakOWiwFKfbqQblMQw0v38M7ZFD2++nO7taf7a7a0i9J7c6YuRyZSqU8 t0HA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l86si13051782pfb.182.2019.04.21.23.47.01; Sun, 21 Apr 2019 23:47:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726934AbfDVGoZ (ORCPT + 99 others); Mon, 22 Apr 2019 02:44:25 -0400 Received: from esa2.microchip.iphmx.com ([68.232.149.84]:3655 "EHLO esa2.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726190AbfDVGoZ (ORCPT ); Mon, 22 Apr 2019 02:44:25 -0400 X-IronPort-AV: E=Sophos;i="5.60,380,1549954800"; d="scan'208";a="30574995" Received: from unknown (HELO smtp.microsemi.com) ([208.19.99.222]) by esa2.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 21 Apr 2019 23:44:12 -0700 Received: from AUSMBX1.microsemi.net (10.201.34.31) by AUSMBX2.microsemi.net (10.201.34.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Mon, 22 Apr 2019 01:44:11 -0500 Received: from AUSMBX3.microsemi.net (10.201.34.33) by AUSMBX1.microsemi.net (10.201.34.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Mon, 22 Apr 2019 01:44:10 -0500 Received: from server1.microsemi.net (10.188.116.203) by ausmbx3.microsemi.net (10.201.34.33) with Microsoft SMTP Server id 15.1.1713.5 via Frontend Transport; Mon, 22 Apr 2019 01:44:07 -0500 From: Wesley Sheng To: , , , , , , , CC: , , Subject: [PATCH 3/3] ntb_hw_switchtec: Fix setup MW with failure bug Date: Mon, 22 Apr 2019 22:42:58 +0800 Message-ID: <1555944178-1957-4-git-send-email-wesley.sheng@microchip.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1555944178-1957-1-git-send-email-wesley.sheng@microchip.com> References: <1555944178-1957-1-git-send-email-wesley.sheng@microchip.com> MIME-Version: 1.0 Content-Type: text/plain Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Joey Zhang Switchtec does not support setting multiple MWs simultaneously. The driver takes a hardware lock to ensure that two peers are not doing this simultaneously and it fails if someone else takes the lock. In most cases, this is fine as clients only setup the MWs once on one side of the link. However, there's a race condition when a re-initialization is caused by a link event. The driver will re-setup the shared memory window asynchronously and this races with the client setting up it's memory windows on the link up event. To fix this we ensure do the entire initialization in a work queue and signal the client once it's done. Signed-off-by: Joey Zhang Signed-off-by: Wesley Sheng Reviewed-by: Logan Gunthorpe --- drivers/ntb/hw/mscc/ntb_hw_switchtec.c | 66 ++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c index 6cf15c18..fffff9a 100644 --- a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c +++ b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c @@ -95,7 +95,8 @@ struct switchtec_ntb { bool link_is_up; enum ntb_speed link_speed; enum ntb_width link_width; - struct work_struct link_reinit_work; + struct work_struct check_link_status_work; + bool link_force_down; }; static struct switchtec_ntb *ntb_sndev(struct ntb_dev *ntb) @@ -494,33 +495,11 @@ enum switchtec_msg { static int switchtec_ntb_reinit_peer(struct switchtec_ntb *sndev); -static void link_reinit_work(struct work_struct *work) -{ - struct switchtec_ntb *sndev; - - sndev = container_of(work, struct switchtec_ntb, link_reinit_work); - - switchtec_ntb_reinit_peer(sndev); -} - -static void switchtec_ntb_check_link(struct switchtec_ntb *sndev, - enum switchtec_msg msg) +static void switchtec_ntb_link_status_update(struct switchtec_ntb *sndev) { int link_sta; int old = sndev->link_is_up; - if (msg == MSG_LINK_FORCE_DOWN) { - schedule_work(&sndev->link_reinit_work); - - if (sndev->link_is_up) { - sndev->link_is_up = 0; - ntb_link_event(&sndev->ntb); - dev_info(&sndev->stdev->dev, "ntb link forced down\n"); - } - - return; - } - link_sta = sndev->self_shared->link_sta; if (link_sta) { u64 peer = ioread64(&sndev->peer_shared->magic); @@ -545,6 +524,38 @@ static void switchtec_ntb_check_link(struct switchtec_ntb *sndev, } } +static void check_link_status_work(struct work_struct *work) +{ + struct switchtec_ntb *sndev; + + sndev = container_of(work, struct switchtec_ntb, + check_link_status_work); + + if (sndev->link_force_down) { + sndev->link_force_down = false; + switchtec_ntb_reinit_peer(sndev); + + if (sndev->link_is_up) { + sndev->link_is_up = 0; + ntb_link_event(&sndev->ntb); + dev_info(&sndev->stdev->dev, "ntb link forced down\n"); + } + + return; + } + + switchtec_ntb_link_status_update(sndev); +} + +static void switchtec_ntb_check_link(struct switchtec_ntb *sndev, + enum switchtec_msg msg) +{ + if (msg == MSG_LINK_FORCE_DOWN) + sndev->link_force_down = true; + + schedule_work(&sndev->check_link_status_work); +} + static void switchtec_ntb_link_notification(struct switchtec_dev *stdev) { struct switchtec_ntb *sndev = stdev->sndev; @@ -577,7 +588,7 @@ static int switchtec_ntb_link_enable(struct ntb_dev *ntb, sndev->self_shared->link_sta = 1; switchtec_ntb_send_msg(sndev, LINK_MESSAGE, MSG_LINK_UP); - switchtec_ntb_check_link(sndev, MSG_CHECK_LINK); + switchtec_ntb_link_status_update(sndev); return 0; } @@ -591,7 +602,7 @@ static int switchtec_ntb_link_disable(struct ntb_dev *ntb) sndev->self_shared->link_sta = 0; switchtec_ntb_send_msg(sndev, LINK_MESSAGE, MSG_LINK_DOWN); - switchtec_ntb_check_link(sndev, MSG_CHECK_LINK); + switchtec_ntb_link_status_update(sndev); return 0; } @@ -844,7 +855,8 @@ static int switchtec_ntb_init_sndev(struct switchtec_ntb *sndev) sndev->ntb.topo = NTB_TOPO_SWITCH; sndev->ntb.ops = &switchtec_ntb_ops; - INIT_WORK(&sndev->link_reinit_work, link_reinit_work); + INIT_WORK(&sndev->check_link_status_work, check_link_status_work); + sndev->link_force_down = false; sndev->self_partition = sndev->stdev->partition; -- 2.7.4