Received: by 2002:a25:7ec1:0:0:0:0:0 with SMTP id z184csp6018591ybc; Wed, 27 Nov 2019 13:30:28 -0800 (PST) X-Google-Smtp-Source: APXvYqxsWQqg6jiauw65LEHCY+XlpGMUDoN26Uf7iYnFQkakAKZTWinTYPSkrt+GvIwcZIdioU8a X-Received: by 2002:a05:6402:1296:: with SMTP id w22mr29516165edv.65.1574890228221; Wed, 27 Nov 2019 13:30:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1574890228; cv=none; d=google.com; s=arc-20160816; b=FCNmhfqP9XKm5cs8pW/nbeI2DCQkqc5YHBFbRHlbtCV0euJ6ghPtiXeCKa6buhVh/A ORKSdwJzw046R5gPNack5KUU5+Sm39mWux+IFZaDA47VFoMSVWY2HuKfVSLKCtFkuSqr mUmXGOyguWoiKRWOGKgl9MfLxXC4B4DbZEMX9SbtokmPDRoAzxrTcqXaYKKvyCQcxgmJ G6ih5cmPMjVcSsLVC3hu77AXouA6BX8X9tigWklV0CF3vHuhJNbE26iFS5JTVX//IAvM epQ7EePOBoAFpsi1g32fkIX5fOzyjElT9MDQPNalASrpz8NDoTRNqsDvS71sKMkydduf 50RA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=1fC0ojsAUMrJG4OrN0+vBaHNQSjNkMnmXcImgcNxIlo=; b=XgKuObt5QMnj9nVw2ZmMlc3Z7/OQPBd9o3w6lyO2RYfsQms4zoVS/j/qWhw6i8EjYw 72nQgvAzsOsKglATI26OLhCafKGwbKKBYzYSyXCunXwLas3iaEuPbTEFimmg8oncVYvL /wXNVO4jcmRZfC2uVoHZ/n4vCYqOlr3Zqw+wM9kj0j9DHRgxpzr3FcaC5xRyutT+FBa1 S4drP0Np4LfVyFSALzg/BWf6OfOz10ar771ygIMGCU18jktuuEoISW7bPL4p7hHH0OxN 7cBwr8u5FbTRQzdq2Qo41mYxqqNgGh88xbdIP9IhcfcI0byKm4mMrTlFsZ9uf4hIXJrn Phmg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=kVT1bXDp; 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 c36si11956993edf.165.2019.11.27.13.30.04; Wed, 27 Nov 2019 13:30:28 -0800 (PST) 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; dkim=pass header.i=@kernel.org header.s=default header.b=kVT1bXDp; 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 S1731695AbfK0V1v (ORCPT + 99 others); Wed, 27 Nov 2019 16:27:51 -0500 Received: from mail.kernel.org ([198.145.29.99]:50540 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730248AbfK0U7G (ORCPT ); Wed, 27 Nov 2019 15:59:06 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C531020678; Wed, 27 Nov 2019 20:59:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1574888345; bh=a+0kLyKi13XHKQWKFP5sMWjOl+MRNzFHvGBwZi2Kk5I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kVT1bXDpxqEcE4BVSDYvJSlZm9qc06JkAYtx4CRUygt1rD0g6jOhwwowdIwPDgueG lkVinZzz6gxLt3NKflfExpZoCADY059pidGGJLqQ8uTeShIhs0Mc9ivic/p4Y0oqap x/v1sLIrINTLJ4dgdaSo3hr+s/MjtEyl2gBMsJe4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Xiang Chen , John Garry , "Martin K. Petersen" , Sasha Levin Subject: [PATCH 4.19 055/306] scsi: hisi_sas: Fix the race between IO completion and timeout for SMP/internal IO Date: Wed, 27 Nov 2019 21:28:25 +0100 Message-Id: <20191127203118.804894226@linuxfoundation.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191127203114.766709977@linuxfoundation.org> References: <20191127203114.766709977@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Xiang Chen [ Upstream commit 584f53fe5f529d877968c711a095923c1ed12307 ] 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 has 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 Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/hisi_sas/hisi_sas_main.c | 55 ++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index e9747379384b2..d4a2625a44232 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -955,8 +955,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); } @@ -965,13 +964,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 @@ -1022,10 +1025,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 @@ -1401,6 +1412,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; @@ -1456,12 +1478,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: @@ -1827,9 +1856,17 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, 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; -- 2.20.1