From patchwork Thu May 31 12:50:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 137377 Delivered-To: patch@linaro.org Received: by 2002:a2e:9706:0:0:0:0:0 with SMTP id r6-v6csp6561216lji; Thu, 31 May 2018 05:52:29 -0700 (PDT) X-Google-Smtp-Source: ADUXVKIaX0tjomf++C6ScV7FlkbS/8geZZGf7BUhu0+gb8T3j68zT/7SuiTag1omwfKJQi8J86mL X-Received: by 2002:a17:902:a714:: with SMTP id w20-v6mr6705338plq.374.1527771148976; Thu, 31 May 2018 05:52:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527771148; cv=none; d=google.com; s=arc-20160816; b=cCrn7DFk3efSSppowXDkO/Mj5d9RhLZsHvSQqB47WHjVtmb2IiKZqsPXNxXJrpYDEP 08kDP8I4AUQQDa8b9NMR/UpD0yM/mImVu+xbFeMDpDAaTLzO1/sYYA9edFkaaKAhEct4 dEWYYDtqBsgpJphF411zZSfycHwTE7mJluZTzM5fncyemREKFU4pLVklcHpVI/1nkAHJ 3nDA9iqWEzC26D/n9YKfbZ8IQPuxP3RtaiJ685RTwHMmjaDGjn6QPwMQzTPFrndDTaJL GH3FPrUPPVSkJzE33xjEY8FppO+f4JGqkbwhhvSujdiVRHfndF9ZAdCcB6N0Xr8NzvfC PJmw== 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:arc-authentication-results; bh=Tb0qRMUZmwx+H0DMRsKfjFevqdsxHCsIusk8TJdfRNU=; b=rhA/GjEiTtqPTho550yLTPb7z0+OPPfrSnEDkqrIGGIfxMiqar04iDzriEN58NVSVw weJO1Alj6yb3ROvC0R7OVNue3LRi+kGNrRfUkb6YL3e3OD+Hea7g+7qgFlfHUlvgAewd 2RoOSOUsu3TengIzs9munJmRVujU2jDOAjjE1V61OKkueAYV+EVzPH09XtOQ8V54d3qk j60RgohOiqw4VU65qJj3YjgHwgEd8Gb1K25Q4ZlX7mD5shNrQdY7+3AW8kvAa4vNcGtA T2qDnAtyc71hZnYdnU/RIZMxPuejmXEgDnVAAfeeL2rDbR4kbbQDAGFR53gHb9wtI45b XhrQ== 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 w5-v6si29296979pgq.550.2018.05.31.05.52.28; Thu, 31 May 2018 05:52:28 -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 S1755134AbeEaMw0 (ORCPT + 30 others); Thu, 31 May 2018 08:52:26 -0400 Received: from szxga06-in.huawei.com ([45.249.212.32]:38674 "EHLO huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1754918AbeEaMwT (ORCPT ); Thu, 31 May 2018 08:52:19 -0400 Received: from DGGEMS406-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id A8CA4779A2093; Thu, 31 May 2018 20:52:15 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEMS406-HUB.china.huawei.com (10.3.19.206) with Microsoft SMTP Server id 14.3.382.0; Thu, 31 May 2018 20:52:10 +0800 From: John Garry To: , CC: , , , Xiaofei Tan , "John Garry" Subject: [PATCH 3/9] scsi: hisi_sas: Fix the conflict between dev gone and host reset Date: Thu, 31 May 2018 20:50:44 +0800 Message-ID: <1527771050-200916-4-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1527771050-200916-1-git-send-email-john.garry@huawei.com> References: <1527771050-200916-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Xiaofei Tan There is a possible conflict when a device is removed and host reset occurs concurrently. The reason is that then the device is notified as gone, we try to clear the ITCT, which is notified via an interrupt. The dev gone function pends on this event with a completion, which is completed when the ITCT interrupt occurs. But host reset will disable all interrupts, the wait_for_completion() may wait indefinitely. This patch adds an semaphore to synchronise this two processes. The semaphore is taken by the host reset as the basis of synchronising. Signed-off-by: Xiaofei Tan Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas.h | 1 + drivers/scsi/hisi_sas/hisi_sas_main.c | 6 ++++++ 2 files changed, 7 insertions(+) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 7052a5d..78e5a92 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -277,6 +277,7 @@ struct hisi_hba { int n_phy; spinlock_t lock; + struct semaphore sem; struct timer_list timer; struct workqueue_struct *wq; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 1c424bb..823386f 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -914,7 +914,9 @@ static void hisi_sas_dev_gone(struct domain_device *device) hisi_sas_dereg_device(hisi_hba, device); + down(&hisi_hba->sem); hisi_hba->hw->clear_itct(hisi_hba, sas_dev); + up(&hisi_hba->sem); device->lldd_dev = NULL; } @@ -1364,6 +1366,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) return -1; + down(&hisi_hba->sem); dev_info(dev, "controller resetting...\n"); old_state = hisi_hba->hw->get_phys_state(hisi_hba); @@ -1378,6 +1381,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) if (rc) { dev_warn(dev, "controller reset failed (%d)\n", rc); clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags); + up(&hisi_hba->sem); scsi_unblock_requests(shost); goto out; } @@ -1388,6 +1392,7 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) hisi_hba->hw->phys_init(hisi_hba); msleep(1000); hisi_sas_refresh_port_id(hisi_hba); + up(&hisi_hba->sem); if (hisi_hba->reject_stp_links_msk) hisi_sas_terminate_stp_reject(hisi_hba); @@ -2016,6 +2021,7 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost) struct device *dev = hisi_hba->dev; int i, s, max_command_entries = hisi_hba->hw->max_command_entries; + sema_init(&hisi_hba->sem, 1); spin_lock_init(&hisi_hba->lock); for (i = 0; i < hisi_hba->n_phy; i++) { hisi_sas_phy_init(hisi_hba, i);