Skip to content

Commit 857b065

Browse files
mikechristiemartinkpetersen
authored andcommitted
scsi: qedi: Fix failed disconnect handling
We set the qedi_ep state to EP_STATE_OFLDCONN_START when the ep is created. Then in qedi_set_path we kick off the offload work. If userspace times out the connection and calls ep_disconnect, qedi will only flush the offload work if the qedi_ep state has transitioned away from EP_STATE_OFLDCONN_START. If we can't connect we will not have transitioned state and will leave the offload work running, and we will free the qedi_ep from under it. This patch just has us init the work when we create the ep, then always flush it. Link: https://lore.kernel.org/r/20220408001314.5014-10-michael.christie@oracle.com Tested-by: Manish Rangankar <mrangankar@marvell.com> Reviewed-by: Lee Duncan <lduncan@suse.com> Reviewed-by: Chris Leech <cleech@redhat.com> Acked-by: Manish Rangankar <mrangankar@marvell.com> Signed-off-by: Mike Christie <michael.christie@oracle.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 44ac971 commit 857b065

File tree

1 file changed

+34
-35
lines changed

1 file changed

+34
-35
lines changed

drivers/scsi/qedi/qedi_iscsi.c

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,37 @@ static int qedi_task_xmit(struct iscsi_task *task)
860860
return qedi_iscsi_send_ioreq(task);
861861
}
862862

863+
static void qedi_offload_work(struct work_struct *work)
864+
{
865+
struct qedi_endpoint *qedi_ep =
866+
container_of(work, struct qedi_endpoint, offload_work);
867+
struct qedi_ctx *qedi;
868+
int wait_delay = 5 * HZ;
869+
int ret;
870+
871+
qedi = qedi_ep->qedi;
872+
873+
ret = qedi_iscsi_offload_conn(qedi_ep);
874+
if (ret) {
875+
QEDI_ERR(&qedi->dbg_ctx,
876+
"offload error: iscsi_cid=%u, qedi_ep=%p, ret=%d\n",
877+
qedi_ep->iscsi_cid, qedi_ep, ret);
878+
qedi_ep->state = EP_STATE_OFLDCONN_FAILED;
879+
return;
880+
}
881+
882+
ret = wait_event_interruptible_timeout(qedi_ep->tcp_ofld_wait,
883+
(qedi_ep->state ==
884+
EP_STATE_OFLDCONN_COMPL),
885+
wait_delay);
886+
if (ret <= 0 || qedi_ep->state != EP_STATE_OFLDCONN_COMPL) {
887+
qedi_ep->state = EP_STATE_OFLDCONN_FAILED;
888+
QEDI_ERR(&qedi->dbg_ctx,
889+
"Offload conn TIMEOUT iscsi_cid=%u, qedi_ep=%p\n",
890+
qedi_ep->iscsi_cid, qedi_ep);
891+
}
892+
}
893+
863894
static struct iscsi_endpoint *
864895
qedi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
865896
int non_blocking)
@@ -908,6 +939,7 @@ qedi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
908939
}
909940
qedi_ep = ep->dd_data;
910941
memset(qedi_ep, 0, sizeof(struct qedi_endpoint));
942+
INIT_WORK(&qedi_ep->offload_work, qedi_offload_work);
911943
qedi_ep->state = EP_STATE_IDLE;
912944
qedi_ep->iscsi_cid = (u32)-1;
913945
qedi_ep->qedi = qedi;
@@ -1056,12 +1088,11 @@ static void qedi_ep_disconnect(struct iscsi_endpoint *ep)
10561088
qedi_ep = ep->dd_data;
10571089
qedi = qedi_ep->qedi;
10581090

1091+
flush_work(&qedi_ep->offload_work);
1092+
10591093
if (qedi_ep->state == EP_STATE_OFLDCONN_START)
10601094
goto ep_exit_recover;
10611095

1062-
if (qedi_ep->state != EP_STATE_OFLDCONN_NONE)
1063-
flush_work(&qedi_ep->offload_work);
1064-
10651096
if (qedi_ep->conn) {
10661097
qedi_conn = qedi_ep->conn;
10671098
abrt_conn = qedi_conn->abrt_conn;
@@ -1235,37 +1266,6 @@ static int qedi_data_avail(struct qedi_ctx *qedi, u16 vlanid)
12351266
return rc;
12361267
}
12371268

1238-
static void qedi_offload_work(struct work_struct *work)
1239-
{
1240-
struct qedi_endpoint *qedi_ep =
1241-
container_of(work, struct qedi_endpoint, offload_work);
1242-
struct qedi_ctx *qedi;
1243-
int wait_delay = 5 * HZ;
1244-
int ret;
1245-
1246-
qedi = qedi_ep->qedi;
1247-
1248-
ret = qedi_iscsi_offload_conn(qedi_ep);
1249-
if (ret) {
1250-
QEDI_ERR(&qedi->dbg_ctx,
1251-
"offload error: iscsi_cid=%u, qedi_ep=%p, ret=%d\n",
1252-
qedi_ep->iscsi_cid, qedi_ep, ret);
1253-
qedi_ep->state = EP_STATE_OFLDCONN_FAILED;
1254-
return;
1255-
}
1256-
1257-
ret = wait_event_interruptible_timeout(qedi_ep->tcp_ofld_wait,
1258-
(qedi_ep->state ==
1259-
EP_STATE_OFLDCONN_COMPL),
1260-
wait_delay);
1261-
if ((ret <= 0) || (qedi_ep->state != EP_STATE_OFLDCONN_COMPL)) {
1262-
qedi_ep->state = EP_STATE_OFLDCONN_FAILED;
1263-
QEDI_ERR(&qedi->dbg_ctx,
1264-
"Offload conn TIMEOUT iscsi_cid=%u, qedi_ep=%p\n",
1265-
qedi_ep->iscsi_cid, qedi_ep);
1266-
}
1267-
}
1268-
12691269
static int qedi_set_path(struct Scsi_Host *shost, struct iscsi_path *path_data)
12701270
{
12711271
struct qedi_ctx *qedi;
@@ -1381,7 +1381,6 @@ static int qedi_set_path(struct Scsi_Host *shost, struct iscsi_path *path_data)
13811381
qedi_ep->dst_addr, qedi_ep->dst_port);
13821382
}
13831383

1384-
INIT_WORK(&qedi_ep->offload_work, qedi_offload_work);
13851384
queue_work(qedi->offload_thread, &qedi_ep->offload_work);
13861385

13871386
ret = 0;

0 commit comments

Comments
 (0)