]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.14.34/nvme_fcloop-fix-abort-race-condition.patch
Linux 4.14.95
[thirdparty/kernel/stable-queue.git] / releases / 4.14.34 / nvme_fcloop-fix-abort-race-condition.patch
CommitLineData
df1b7722
GKH
1From foo@baz Mon Apr 9 13:58:16 CEST 2018
2From: James Smart <jsmart2021@gmail.com>
3Date: Wed, 29 Nov 2017 16:47:30 -0800
4Subject: nvme_fcloop: fix abort race condition
5
6From: James Smart <jsmart2021@gmail.com>
7
8
9[ Upstream commit 278e096063f1914fccfc77a617be9fc8dbb31b0e ]
10
11A test case revealed a race condition of an i/o completing on a thread
12parallel to the delete_association generating the aborts for the
13outstanding ios on the controller. The i/o completion was freeing the
14target fcloop context, thus the abort task referenced the just-freed
15memory.
16
17Correct by clearing the target/initiator cross pointers in the io
18completion and abort tasks before calling the callbacks. On aborts
19that detect already finished io's, ensure the complete context is
20called.
21
22Signed-off-by: James Smart <james.smart@broadcom.com>
23Signed-off-by: Christoph Hellwig <hch@lst.de>
24Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
25Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
26---
27 drivers/nvme/target/fcloop.c | 12 +++++++-----
28 1 file changed, 7 insertions(+), 5 deletions(-)
29
30--- a/drivers/nvme/target/fcloop.c
31+++ b/drivers/nvme/target/fcloop.c
32@@ -374,6 +374,7 @@ fcloop_tgt_fcprqst_done_work(struct work
33
34 spin_lock(&tfcp_req->reqlock);
35 fcpreq = tfcp_req->fcpreq;
36+ tfcp_req->fcpreq = NULL;
37 spin_unlock(&tfcp_req->reqlock);
38
39 if (tport->remoteport && fcpreq) {
40@@ -615,11 +616,7 @@ fcloop_fcp_abort(struct nvme_fc_local_po
41
42 if (!tfcp_req)
43 /* abort has already been called */
44- return;
45-
46- if (rport->targetport)
47- nvmet_fc_rcv_fcp_abort(rport->targetport,
48- &tfcp_req->tgt_fcp_req);
49+ goto finish;
50
51 /* break initiator/target relationship for io */
52 spin_lock(&tfcp_req->reqlock);
53@@ -627,6 +624,11 @@ fcloop_fcp_abort(struct nvme_fc_local_po
54 tfcp_req->fcpreq = NULL;
55 spin_unlock(&tfcp_req->reqlock);
56
57+ if (rport->targetport)
58+ nvmet_fc_rcv_fcp_abort(rport->targetport,
59+ &tfcp_req->tgt_fcp_req);
60+
61+finish:
62 /* post the aborted io completion */
63 fcpreq->status = -ECANCELED;
64 schedule_work(&inireq->iniwork);