Received: by 2002:a25:7ec1:0:0:0:0:0 with SMTP id z184csp733460ybc; Sat, 16 Nov 2019 07:45:48 -0800 (PST) X-Google-Smtp-Source: APXvYqz+0AgP0fdmgzA+TAuCe/ZAIumE+OKdyOpNcidudRGKnGs4K306X3241+ScU6c3NP12OcaY X-Received: by 2002:a17:906:74d7:: with SMTP id z23mr10999025ejl.1.1573919148552; Sat, 16 Nov 2019 07:45:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573919148; cv=none; d=google.com; s=arc-20160816; b=XO2sUhNZMow9iefjkcNYzjMBiHupISNrTzTSLgix2NfDwKfHNrGGZrokmc8THidgAW xG9wb0fEYSgIbUdgclqhU4D33Q6TInhX6p/lM/99HmVB5L45TwMiuhIxRv1sOuVgEqck rCyJvrQ8q+SN3K4G5nVwnKDFygw+Cp+vNdi+HWpmvQWH9CvOA71LIaULyFUlPuPL1l4x 9EUvmB07f62dww71/QpIjIbViNcRB5Vw9OTh+EYXP9ws5Jwl//U1p7XbeEzuZmRwbDuv jh/jUVkgXn4tzhYI80jIb3bByGnc+HdIT0+hQa7bHW7D+FL4+FBaFw+hxx/qS8DSfMvg 92/w== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=1fC0ojsAUMrJG4OrN0+vBaHNQSjNkMnmXcImgcNxIlo=; b=lh2goQeBqtSl8S19Ze3blAWYlVNghqzAqc5Ai0Y6C1w3uENAbFlGYZWAS0uey3VLpY fZ5P6rhFTX60Sj9vXJxhTYrmcaLbUBiNm/jui9Z9GvlVdLnqHW7MEB4wslF3PTmO0Ys7 1OwbtHp80wjxH7wORLd+8HzX6F6oyCuPhLn2YBZ8msDSUeLWOF67aN/G608AAmwvc19+ 2U1zOhiVGnTAJ6P9AttXCG9Un5ThajokTpPxC4gA37I2w8y9OfBWAwtpmXHsoqH6pjko 8A6oZ9nWvcY7LX/GV87yh413r6n81TwxXqQ3nzERHF4bVmO5VhqlMXvHHeB/D9LEQ4AS gSNA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=FiFMmquW; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u59si9952695edc.193.2019.11.16.07.45.23; Sat, 16 Nov 2019 07:45:48 -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=FiFMmquW; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728040AbfKPPly (ORCPT + 99 others); Sat, 16 Nov 2019 10:41:54 -0500 Received: from mail.kernel.org ([198.145.29.99]:45186 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728028AbfKPPlx (ORCPT ); Sat, 16 Nov 2019 10:41:53 -0500 Received: from sasha-vm.mshome.net (unknown [50.234.116.4]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6018720803; Sat, 16 Nov 2019 15:41:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1573918911; bh=a+0kLyKi13XHKQWKFP5sMWjOl+MRNzFHvGBwZi2Kk5I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FiFMmquWhpIGZdht5fJMMntcfD1F2y9WrpmJfOA1LIUyuxWa6TlGCX8zsCyzQ7hZ0 4G8/HgJjg7vid9uXvSYeabE6EIevVRt2T5Vdqlv/UZisMxX3jbCh0n3RJVNpSbR3qX mEqthgxKmdavxcL64vcliMcABjLIxAXcHbaLac+U= From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Xiang Chen , John Garry , "Martin K . Petersen" , Sasha Levin , linux-scsi@vger.kernel.org Subject: [PATCH AUTOSEL 4.19 035/237] scsi: hisi_sas: Fix the race between IO completion and timeout for SMP/internal IO Date: Sat, 16 Nov 2019 10:37:50 -0500 Message-Id: <20191116154113.7417-35-sashal@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191116154113.7417-1-sashal@kernel.org> References: <20191116154113.7417-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore 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