hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/scsi/qedi/qedi_iscsi.c
....@@ -1,10 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * QLogic iSCSI Offload Driver
34 * Copyright (c) 2016 Cavium Inc.
4
- *
5
- * This software is available under the terms of the GNU General Public License
6
- * (GPL) Version 2, available from the file COPYING in the main directory of
7
- * this source tree.
85 */
96
107 #include <linux/blkdev.h>
....@@ -61,7 +58,6 @@
6158 .max_sectors = 0xffff,
6259 .dma_boundary = QEDI_HW_DMA_BOUNDARY,
6360 .cmd_per_lun = 128,
64
- .use_clustering = ENABLE_CLUSTERING,
6561 .shost_attrs = qedi_shost_attrs,
6662 };
6763
....@@ -334,12 +330,22 @@
334330
335331 void qedi_mark_device_missing(struct iscsi_cls_session *cls_session)
336332 {
337
- iscsi_block_session(cls_session);
333
+ struct iscsi_session *session = cls_session->dd_data;
334
+ struct qedi_conn *qedi_conn = session->leadconn->dd_data;
335
+
336
+ spin_lock_bh(&session->frwd_lock);
337
+ set_bit(QEDI_BLOCK_IO, &qedi_conn->qedi->flags);
338
+ spin_unlock_bh(&session->frwd_lock);
338339 }
339340
340341 void qedi_mark_device_available(struct iscsi_cls_session *cls_session)
341342 {
342
- iscsi_unblock_session(cls_session);
343
+ struct iscsi_session *session = cls_session->dd_data;
344
+ struct qedi_conn *qedi_conn = session->leadconn->dd_data;
345
+
346
+ spin_lock_bh(&session->frwd_lock);
347
+ clear_bit(QEDI_BLOCK_IO, &qedi_conn->qedi->flags);
348
+ spin_unlock_bh(&session->frwd_lock);
343349 }
344350
345351 static int qedi_bind_conn_to_iscsi_cid(struct qedi_ctx *qedi,
....@@ -381,6 +387,7 @@
381387 struct qedi_ctx *qedi = iscsi_host_priv(shost);
382388 struct qedi_endpoint *qedi_ep;
383389 struct iscsi_endpoint *ep;
390
+ int rc = 0;
384391
385392 ep = iscsi_lookup_endpoint(transport_fd);
386393 if (!ep)
....@@ -388,26 +395,37 @@
388395
389396 qedi_ep = ep->dd_data;
390397 if ((qedi_ep->state == EP_STATE_TCP_FIN_RCVD) ||
391
- (qedi_ep->state == EP_STATE_TCP_RST_RCVD))
392
- return -EINVAL;
398
+ (qedi_ep->state == EP_STATE_TCP_RST_RCVD)) {
399
+ rc = -EINVAL;
400
+ goto put_ep;
401
+ }
393402
394
- if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
395
- return -EINVAL;
403
+ if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) {
404
+ rc = -EINVAL;
405
+ goto put_ep;
406
+ }
407
+
396408
397409 qedi_ep->conn = qedi_conn;
398410 qedi_conn->ep = qedi_ep;
411
+ qedi_conn->iscsi_ep = ep;
399412 qedi_conn->iscsi_conn_id = qedi_ep->iscsi_cid;
400413 qedi_conn->fw_cid = qedi_ep->fw_cid;
401414 qedi_conn->cmd_cleanup_req = 0;
402415 qedi_conn->cmd_cleanup_cmpl = 0;
403416
404
- if (qedi_bind_conn_to_iscsi_cid(qedi, qedi_conn))
405
- return -EINVAL;
417
+ if (qedi_bind_conn_to_iscsi_cid(qedi, qedi_conn)) {
418
+ rc = -EINVAL;
419
+ goto put_ep;
420
+ }
421
+
406422
407423 spin_lock_init(&qedi_conn->tmf_work_lock);
408424 INIT_LIST_HEAD(&qedi_conn->tmf_work_list);
409425 init_waitqueue_head(&qedi_conn->wait_queue);
410
- return 0;
426
+put_ep:
427
+ iscsi_put_endpoint(ep);
428
+ return rc;
411429 }
412430
413431 static int qedi_iscsi_update_conn(struct qedi_ctx *qedi,
....@@ -580,7 +598,7 @@
580598 rval = qedi_iscsi_update_conn(qedi, qedi_conn);
581599 if (rval) {
582600 iscsi_conn_printk(KERN_ALERT, conn,
583
- "conn_start: FW oflload conn failed.\n");
601
+ "conn_start: FW offload conn failed.\n");
584602 rval = -EINVAL;
585603 goto start_err;
586604 }
....@@ -591,7 +609,7 @@
591609 rval = iscsi_conn_start(cls_conn);
592610 if (rval) {
593611 iscsi_conn_printk(KERN_ALERT, conn,
594
- "iscsi_conn_start: FW oflload conn failed!!\n");
612
+ "iscsi_conn_start: FW offload conn failed!!\n");
595613 }
596614
597615 start_err:
....@@ -775,7 +793,6 @@
775793 }
776794
777795 cmd->conn = conn->dd_data;
778
- cmd->scsi_cmd = NULL;
779796 return qedi_iscsi_send_generic_request(task);
780797 }
781798
....@@ -785,6 +802,16 @@
785802 struct qedi_conn *qedi_conn = conn->dd_data;
786803 struct qedi_cmd *cmd = task->dd_data;
787804 struct scsi_cmnd *sc = task->sc;
805
+
806
+ /* Clear now so in cleanup_task we know it didn't make it */
807
+ cmd->scsi_cmd = NULL;
808
+ cmd->task_id = U16_MAX;
809
+
810
+ if (test_bit(QEDI_IN_SHUTDOWN, &qedi_conn->qedi->flags))
811
+ return -ENODEV;
812
+
813
+ if (test_bit(QEDI_BLOCK_IO, &qedi_conn->qedi->flags))
814
+ return -EACCES;
788815
789816 cmd->state = 0;
790817 cmd->task = NULL;
....@@ -799,6 +826,37 @@
799826
800827 cmd->scsi_cmd = sc;
801828 return qedi_iscsi_send_ioreq(task);
829
+}
830
+
831
+static void qedi_offload_work(struct work_struct *work)
832
+{
833
+ struct qedi_endpoint *qedi_ep =
834
+ container_of(work, struct qedi_endpoint, offload_work);
835
+ struct qedi_ctx *qedi;
836
+ int wait_delay = 5 * HZ;
837
+ int ret;
838
+
839
+ qedi = qedi_ep->qedi;
840
+
841
+ ret = qedi_iscsi_offload_conn(qedi_ep);
842
+ if (ret) {
843
+ QEDI_ERR(&qedi->dbg_ctx,
844
+ "offload error: iscsi_cid=%u, qedi_ep=%p, ret=%d\n",
845
+ qedi_ep->iscsi_cid, qedi_ep, ret);
846
+ qedi_ep->state = EP_STATE_OFLDCONN_FAILED;
847
+ return;
848
+ }
849
+
850
+ ret = wait_event_interruptible_timeout(qedi_ep->tcp_ofld_wait,
851
+ (qedi_ep->state ==
852
+ EP_STATE_OFLDCONN_COMPL),
853
+ wait_delay);
854
+ if (ret <= 0 || qedi_ep->state != EP_STATE_OFLDCONN_COMPL) {
855
+ qedi_ep->state = EP_STATE_OFLDCONN_FAILED;
856
+ QEDI_ERR(&qedi->dbg_ctx,
857
+ "Offload conn TIMEOUT iscsi_cid=%u, qedi_ep=%p\n",
858
+ qedi_ep->iscsi_cid, qedi_ep);
859
+ }
802860 }
803861
804862 static struct iscsi_endpoint *
....@@ -836,6 +894,11 @@
836894 return ERR_PTR(ret);
837895 }
838896
897
+ if (atomic_read(&qedi->link_state) != QEDI_LINK_UP) {
898
+ QEDI_WARN(&qedi->dbg_ctx, "qedi link down\n");
899
+ return ERR_PTR(-ENXIO);
900
+ }
901
+
839902 ep = iscsi_create_endpoint(sizeof(struct qedi_endpoint));
840903 if (!ep) {
841904 QEDI_ERR(&qedi->dbg_ctx, "endpoint create fail\n");
....@@ -844,6 +907,7 @@
844907 }
845908 qedi_ep = ep->dd_data;
846909 memset(qedi_ep, 0, sizeof(struct qedi_endpoint));
910
+ INIT_WORK(&qedi_ep->offload_work, qedi_offload_work);
847911 qedi_ep->state = EP_STATE_IDLE;
848912 qedi_ep->iscsi_cid = (u32)-1;
849913 qedi_ep->qedi = qedi;
....@@ -868,12 +932,6 @@
868932 qedi_ep->dst_addr, qedi_ep->dst_port);
869933 } else {
870934 QEDI_ERR(&qedi->dbg_ctx, "Invalid endpoint\n");
871
- }
872
-
873
- if (atomic_read(&qedi->link_state) != QEDI_LINK_UP) {
874
- QEDI_WARN(&qedi->dbg_ctx, "qedi link down\n");
875
- ret = -ENXIO;
876
- goto ep_conn_exit;
877935 }
878936
879937 ret = qedi_alloc_sq(qedi, qedi_ep);
....@@ -992,18 +1050,18 @@
9921050 struct iscsi_conn *conn = NULL;
9931051 struct qedi_ctx *qedi;
9941052 int ret = 0;
995
- int wait_delay = 20 * HZ;
1053
+ int wait_delay;
9961054 int abrt_conn = 0;
9971055 int count = 10;
9981056
1057
+ wait_delay = 60 * HZ + DEF_MAX_RT_TIME;
9991058 qedi_ep = ep->dd_data;
10001059 qedi = qedi_ep->qedi;
10011060
1061
+ flush_work(&qedi_ep->offload_work);
1062
+
10021063 if (qedi_ep->state == EP_STATE_OFLDCONN_START)
10031064 goto ep_exit_recover;
1004
-
1005
- if (qedi_ep->state != EP_STATE_OFLDCONN_NONE)
1006
- flush_work(&qedi_ep->offload_work);
10071065
10081066 if (qedi_ep->conn) {
10091067 qedi_conn = qedi_ep->conn;
....@@ -1071,6 +1129,11 @@
10711129 wait_delay += qedi->pf_params.iscsi_pf_params.two_msl_timer;
10721130
10731131 qedi_ep->state = EP_STATE_DISCONN_START;
1132
+
1133
+ if (test_bit(QEDI_IN_SHUTDOWN, &qedi->flags) ||
1134
+ test_bit(QEDI_IN_RECOVERY, &qedi->flags))
1135
+ goto ep_release_conn;
1136
+
10741137 ret = qedi_ops->destroy_conn(qedi->cdev, qedi_ep->handle, abrt_conn);
10751138 if (ret) {
10761139 QEDI_WARN(&qedi->dbg_ctx,
....@@ -1162,37 +1225,6 @@
11621225 uctrl->hw_tx_cons++;
11631226
11641227 return rc;
1165
-}
1166
-
1167
-static void qedi_offload_work(struct work_struct *work)
1168
-{
1169
- struct qedi_endpoint *qedi_ep =
1170
- container_of(work, struct qedi_endpoint, offload_work);
1171
- struct qedi_ctx *qedi;
1172
- int wait_delay = 20 * HZ;
1173
- int ret;
1174
-
1175
- qedi = qedi_ep->qedi;
1176
-
1177
- ret = qedi_iscsi_offload_conn(qedi_ep);
1178
- if (ret) {
1179
- QEDI_ERR(&qedi->dbg_ctx,
1180
- "offload error: iscsi_cid=%u, qedi_ep=%p, ret=%d\n",
1181
- qedi_ep->iscsi_cid, qedi_ep, ret);
1182
- qedi_ep->state = EP_STATE_OFLDCONN_FAILED;
1183
- return;
1184
- }
1185
-
1186
- ret = wait_event_interruptible_timeout(qedi_ep->tcp_ofld_wait,
1187
- (qedi_ep->state ==
1188
- EP_STATE_OFLDCONN_COMPL),
1189
- wait_delay);
1190
- if ((ret <= 0) || (qedi_ep->state != EP_STATE_OFLDCONN_COMPL)) {
1191
- qedi_ep->state = EP_STATE_OFLDCONN_FAILED;
1192
- QEDI_ERR(&qedi->dbg_ctx,
1193
- "Offload conn TIMEOUT iscsi_cid=%u, qedi_ep=%p\n",
1194
- qedi_ep->iscsi_cid, qedi_ep);
1195
- }
11961228 }
11971229
11981230 static int qedi_set_path(struct Scsi_Host *shost, struct iscsi_path *path_data)
....@@ -1310,7 +1342,6 @@
13101342 qedi_ep->dst_addr, qedi_ep->dst_port);
13111343 }
13121344
1313
- INIT_WORK(&qedi_ep->offload_work, qedi_offload_work);
13141345 queue_work(qedi->offload_thread, &qedi_ep->offload_work);
13151346
13161347 ret = 0;
....@@ -1378,13 +1409,24 @@
13781409
13791410 static void qedi_cleanup_task(struct iscsi_task *task)
13801411 {
1381
- if (!task->sc || task->state == ISCSI_TASK_PENDING) {
1412
+ struct qedi_cmd *cmd;
1413
+
1414
+ if (task->state == ISCSI_TASK_PENDING) {
13821415 QEDI_INFO(NULL, QEDI_LOG_IO, "Returning ref_cnt=%d\n",
13831416 refcount_read(&task->refcount));
13841417 return;
13851418 }
13861419
1387
- qedi_iscsi_unmap_sg_list(task->dd_data);
1420
+ if (task->sc)
1421
+ qedi_iscsi_unmap_sg_list(task->dd_data);
1422
+
1423
+ cmd = task->dd_data;
1424
+ if (cmd->task_id != U16_MAX)
1425
+ qedi_clear_task_idx(iscsi_host_priv(task->conn->session->host),
1426
+ cmd->task_id);
1427
+
1428
+ cmd->task_id = U16_MAX;
1429
+ cmd->scsi_cmd = NULL;
13881430 }
13891431
13901432 struct iscsi_transport qedi_iscsi_transport = {
....@@ -1396,6 +1438,7 @@
13961438 .destroy_session = qedi_session_destroy,
13971439 .create_conn = qedi_conn_create,
13981440 .bind_conn = qedi_conn_bind,
1441
+ .unbind_conn = iscsi_conn_unbind,
13991442 .start_conn = qedi_conn_start,
14001443 .stop_conn = iscsi_conn_stop,
14011444 .destroy_conn = qedi_conn_destroy,
....@@ -1548,7 +1591,7 @@
15481591 },
15491592 };
15501593
1551
-char *qedi_get_iscsi_error(enum iscsi_error_types err_code)
1594
+static char *qedi_get_iscsi_error(enum iscsi_error_types err_code)
15521595 {
15531596 int i;
15541597 char *msg = NULL;
....@@ -1609,6 +1652,20 @@
16091652 qedi_start_conn_recovery(qedi_conn->qedi, qedi_conn);
16101653 }
16111654
1655
+void qedi_clear_session_ctx(struct iscsi_cls_session *cls_sess)
1656
+{
1657
+ struct iscsi_session *session = cls_sess->dd_data;
1658
+ struct iscsi_conn *conn = session->leadconn;
1659
+ struct qedi_conn *qedi_conn = conn->dd_data;
1660
+
1661
+ if (iscsi_is_session_online(cls_sess))
1662
+ qedi_ep_disconnect(qedi_conn->iscsi_ep);
1663
+
1664
+ qedi_conn_destroy(qedi_conn->cls_conn);
1665
+
1666
+ qedi_session_destroy(cls_sess);
1667
+}
1668
+
16121669 void qedi_process_tcp_error(struct qedi_endpoint *ep,
16131670 struct iscsi_eqe_data *data)
16141671 {