From patchwork Mon Sep 24 15:06:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 147363 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp836480lji; Mon, 24 Sep 2018 08:09:48 -0700 (PDT) X-Google-Smtp-Source: ACcGV61OiJJuuTSQAX6P51Kh9m0dyfN8wo+RUBANiOZ01YsG4e2HQ6I4TrrptjEpQgPyZzNcZlMX X-Received: by 2002:a65:5286:: with SMTP id y6-v6mr9732071pgp.65.1537801788599; Mon, 24 Sep 2018 08:09:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1537801788; cv=none; d=google.com; s=arc-20160816; b=QZnkU7CCKDaiJL2AbEh5KiYpWDcon/IWKah78ZcH5/HGyi3SkVGeFduZltNsjWVjFg MhqA/glLy2aKijs/tRXgWcqXCZqKiWzJz9J9ZVAmFFP3qhb6L+SDlwlWHzhLEk0JKnPp XT3R4pO56akBcedUE4gSagEwciqcUM0cP+a9G3xwf8LCWFOXfNssmH+YCHwEOdiBtKG8 AFd0o26B1NdaiSBdt8upJv6sF14YCJCZehvi7XdBD7x1AS7pP5T/S11V+UaRG+6QECOz yG4jLUdXx+slo+iiQweo4H7piIE++YuLpMXS6/R0snoYqUALu5/PFzNBYoKzUopl7QGW 7Nsg== 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=epDZfF+3KKsNbrGsYTYY4mpF73PYsSyGNmZOAmN034w=; b=ZIexBlNglEXatxM5Ywx0ooz04+UvhKEZb+Y+l9fHUC06kHOZrPjoQ/EiYNbse6j59w PHAgNGxgoW97G6deuUae0aakeBDtvmddzTT1MLbL6O7/ov8ohufbJir8UnkmdCCPidti GLUDnT7+itIfvDAqN/5hQur0l9HPrIzhcX3Fv8KdC7AlRv9lvG6lRtlrkOhVn4WjYhI6 Ni1/dtiiQsghDi2K9T/BA5sDLZxr2uaNvM/7kJ7wacVW0N83IgIZci1ebiaMBIqAZrIF rteW1FFnQA8DBO9oaOz1qy35N2FeJN6ZwuLw48oXZSJESXkT4T8wqP9ZggR40bvfnCaa PTBQ== 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 b3-v6si2062831plx.106.2018.09.24.08.09.48; Mon, 24 Sep 2018 08:09:48 -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 S1733277AbeIXVMX (ORCPT + 32 others); Mon, 24 Sep 2018 17:12:23 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:12681 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1728512AbeIXVMV (ORCPT ); Mon, 24 Sep 2018 17:12:21 -0400 Received: from DGGEMS402-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 0711468DEFC99; Mon, 24 Sep 2018 23:09:39 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEMS402-HUB.china.huawei.com (10.3.19.202) with Microsoft SMTP Server id 14.3.399.0; Mon, 24 Sep 2018 23:09:31 +0800 From: John Garry To: , CC: , , , Xiang Chen , "John Garry" Subject: [PATCH 3/7] scsi: hisi_sas: Fix the race between IO completion and timeout for SMP/internal IO Date: Mon, 24 Sep 2018 23:06:30 +0800 Message-ID: <1537801594-207139-4-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1537801594-207139-1-git-send-email-john.garry@huawei.com> References: <1537801594-207139-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: Xiang Chen If SMP/internal IO times out, we will possibly free the task immediately. However if the IO actually completes at the same time, the IO completion may refer to task which have been freed. So to solve the issue, flush the tasklet to finish IO completion before free'ing slot/task. Signed-off-by: Xiang Chen Signed-off-by: John Garry --- drivers/scsi/hisi_sas/hisi_sas_main.c | 55 +++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 9 deletions(-) -- 1.9.1 diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 3b95a7a..416f2c0 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -956,8 +956,7 @@ static int hisi_sas_control_phy(struct asd_sas_phy *sas_phy, enum phy_func func, static void hisi_sas_task_done(struct sas_task *task) { - if (!del_timer(&task->slow_task->timer)) - return; + del_timer(&task->slow_task->timer); complete(&task->slow_task->completion); } @@ -966,13 +965,17 @@ static void hisi_sas_tmf_timedout(struct timer_list *t) struct sas_task_slow *slow = from_timer(slow, t, timer); struct sas_task *task = slow->task; unsigned long flags; + bool is_completed = true; spin_lock_irqsave(&task->task_state_lock, flags); - if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { task->task_state_flags |= SAS_TASK_STATE_ABORTED; + is_completed = false; + } spin_unlock_irqrestore(&task->task_state_lock, flags); - complete(&task->slow_task->completion); + if (!is_completed) + complete(&task->slow_task->completion); } #define TASK_TIMEOUT 20 @@ -1023,10 +1026,18 @@ static int hisi_sas_exec_internal_tmf_task(struct domain_device *device, if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { struct hisi_sas_slot *slot = task->lldd_task; + struct hisi_sas_cq *cq = + &hisi_hba->cq[slot->dlvry_queue]; dev_err(dev, "abort tmf: TMF task timeout and not done\n"); - if (slot) + if (slot) { + /* + * flush tasklet to avoid free'ing task + * before using task in IO completion + */ + tasklet_kill(&cq->tasklet); slot->task = NULL; + } goto ex_err; } else @@ -1402,6 +1413,17 @@ static int hisi_sas_abort_task(struct sas_task *task) spin_lock_irqsave(&task->task_state_lock, flags); if (task->task_state_flags & SAS_TASK_STATE_DONE) { + struct hisi_sas_slot *slot = task->lldd_task; + struct hisi_sas_cq *cq; + + if (slot) { + /* + * flush tasklet to avoid free'ing task + * before using task in IO completion + */ + cq = &hisi_hba->cq[slot->dlvry_queue]; + tasklet_kill(&cq->tasklet); + } spin_unlock_irqrestore(&task->task_state_lock, flags); rc = TMF_RESP_FUNC_COMPLETE; goto out; @@ -1457,12 +1479,19 @@ static int hisi_sas_abort_task(struct sas_task *task) /* SMP */ struct hisi_sas_slot *slot = task->lldd_task; u32 tag = slot->idx; + struct hisi_sas_cq *cq = &hisi_hba->cq[slot->dlvry_queue]; rc = hisi_sas_internal_task_abort(hisi_hba, device, HISI_SAS_INT_ABT_CMD, tag); if (((rc < 0) || (rc == TMF_RESP_FUNC_FAILED)) && - task->lldd_task) - hisi_sas_do_release_task(hisi_hba, task, slot); + task->lldd_task) { + /* + * flush tasklet to avoid free'ing task + * before using task in IO completion + */ + tasklet_kill(&cq->tasklet); + slot->task = NULL; + } } out: @@ -1828,9 +1857,17 @@ static int hisi_sas_query_task(struct sas_task *task) if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { struct hisi_sas_slot *slot = task->lldd_task; - - if (slot) + struct hisi_sas_cq *cq = + &hisi_hba->cq[slot->dlvry_queue]; + + if (slot) { + /* + * flush tasklet to avoid free'ing task + * before using task in IO completion + */ + tasklet_kill(&cq->tasklet); slot->task = NULL; + } dev_err(dev, "internal task abort: timeout and not done.\n"); res = -EIO; goto exit;