Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: iscsi: Stop using the SCSI pointer

Instead of storing the iSCSI task pointer and the session age in the SCSI
pointer, use command-private variables. This patch prepares for removal of
the SCSI pointer from struct scsi_cmnd.

The list of iSCSI drivers has been obtained as follows:
$ git grep -lw iscsi_host_alloc
drivers/infiniband/ulp/iser/iscsi_iser.c
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/bnx2i/bnx2i_iscsi.c
drivers/scsi/cxgbi/libcxgbi.c
drivers/scsi/iscsi_tcp.c
drivers/scsi/libiscsi.c
drivers/scsi/qedi/qedi_main.c
drivers/scsi/qla4xxx/ql4_os.c
include/scsi/libiscsi.h

Note: it is not clear to me how the qla4xxx driver can work without this
patch since it uses the scsi_cmnd::SCp.ptr member for two different
purposes:
- The qla4xxx driver uses this member to store a struct srb pointer.
- libiscsi uses this member to store a struct iscsi_task pointer.

Reviewed-by: Lee Duncan <lduncan@suse.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Cc: Chris Leech <cleech@redhat.com>
Cc: Sagi Grimberg <sagi@grimberg.me>
Cc: Nilesh Javali <njavali@marvell.com>
Cc: Manish Rangankar <mrangankar@marvell.com>
Cc: Karen Xie <kxie@chelsio.com>
Cc: Ketan Mukadam <ketan.mukadam@broadcom.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>

iscsi

Link: https://lore.kernel.org/r/20220218195117.25689-26-bvanassche@acm.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Bart Van Assche and committed by
Martin K. Petersen
db22de3e 6b66f09c

+52 -22
+1
drivers/infiniband/ulp/iser/iscsi_iser.c
··· 971 971 .proc_name = "iscsi_iser", 972 972 .this_id = -1, 973 973 .track_queue_depth = 1, 974 + .cmd_size = sizeof(struct iscsi_cmd), 974 975 }; 975 976 976 977 static struct iscsi_transport iscsi_iser_transport = {
+2 -1
drivers/scsi/be2iscsi/be_main.c
··· 218 218 219 219 static int beiscsi_eh_abort(struct scsi_cmnd *sc) 220 220 { 221 - struct iscsi_task *abrt_task = (struct iscsi_task *)sc->SCp.ptr; 221 + struct iscsi_task *abrt_task = iscsi_cmd(sc)->task; 222 222 struct iscsi_cls_session *cls_session; 223 223 struct beiscsi_io_task *abrt_io_task; 224 224 struct beiscsi_conn *beiscsi_conn; ··· 403 403 .cmd_per_lun = BEISCSI_CMD_PER_LUN, 404 404 .vendor_id = SCSI_NL_VID_TYPE_PCI | BE_VENDOR_ID, 405 405 .track_queue_depth = 1, 406 + .cmd_size = sizeof(struct iscsi_cmd), 406 407 }; 407 408 408 409 static struct scsi_transport_template *beiscsi_scsi_transport;
+1
drivers/scsi/bnx2i/bnx2i_iscsi.c
··· 2268 2268 .sg_tablesize = ISCSI_MAX_BDS_PER_CMD, 2269 2269 .shost_groups = bnx2i_dev_groups, 2270 2270 .track_queue_depth = 1, 2271 + .cmd_size = sizeof(struct iscsi_cmd), 2271 2272 }; 2272 2273 2273 2274 struct iscsi_transport bnx2i_iscsi_transport = {
+1
drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
··· 98 98 .dma_boundary = PAGE_SIZE - 1, 99 99 .this_id = -1, 100 100 .track_queue_depth = 1, 101 + .cmd_size = sizeof(struct iscsi_cmd), 101 102 }; 102 103 103 104 static struct iscsi_transport cxgb3i_iscsi_transport = {
+1
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
··· 116 116 .dma_boundary = PAGE_SIZE - 1, 117 117 .this_id = -1, 118 118 .track_queue_depth = 1, 119 + .cmd_size = sizeof(struct iscsi_cmd), 119 120 }; 120 121 121 122 static struct iscsi_transport cxgb4i_iscsi_transport = {
+1
drivers/scsi/iscsi_tcp.c
··· 1007 1007 .proc_name = "iscsi_tcp", 1008 1008 .this_id = -1, 1009 1009 .track_queue_depth = 1, 1010 + .cmd_size = sizeof(struct iscsi_cmd), 1010 1011 }; 1011 1012 1012 1013 static struct iscsi_transport iscsi_sw_tcp_transport = {
+10 -10
drivers/scsi/libiscsi.c
··· 462 462 463 463 if (sc) { 464 464 /* SCSI eh reuses commands to verify us */ 465 - sc->SCp.ptr = NULL; 465 + iscsi_cmd(sc)->task = NULL; 466 466 /* 467 467 * queue command may call this to free the task, so 468 468 * it will decide how to return sc to scsi-ml. ··· 1344 1344 if (!task || !task->sc) 1345 1345 return NULL; 1346 1346 1347 - if (task->sc->SCp.phase != conn->session->age) { 1347 + if (iscsi_cmd(task->sc)->age != conn->session->age) { 1348 1348 iscsi_session_printk(KERN_ERR, conn->session, 1349 1349 "task's session age %d, expected %d\n", 1350 - task->sc->SCp.phase, conn->session->age); 1350 + iscsi_cmd(task->sc)->age, conn->session->age); 1351 1351 return NULL; 1352 1352 } 1353 1353 ··· 1645 1645 (void *) &task, sizeof(void *))) 1646 1646 return NULL; 1647 1647 1648 - sc->SCp.phase = conn->session->age; 1649 - sc->SCp.ptr = (char *) task; 1648 + iscsi_cmd(sc)->age = conn->session->age; 1649 + iscsi_cmd(sc)->task = task; 1650 1650 1651 1651 refcount_set(&task->refcount, 1); 1652 1652 task->state = ISCSI_TASK_PENDING; ··· 1683 1683 struct iscsi_task *task = NULL; 1684 1684 1685 1685 sc->result = 0; 1686 - sc->SCp.ptr = NULL; 1686 + iscsi_cmd(sc)->task = NULL; 1687 1687 1688 1688 ihost = shost_priv(host); 1689 1689 ··· 1997 1997 1998 1998 spin_lock_bh(&session->frwd_lock); 1999 1999 spin_lock(&session->back_lock); 2000 - task = (struct iscsi_task *)sc->SCp.ptr; 2000 + task = iscsi_cmd(sc)->task; 2001 2001 if (!task) { 2002 2002 /* 2003 2003 * Raced with completion. Blk layer has taken ownership ··· 2260 2260 * if session was ISCSI_STATE_IN_RECOVERY then we may not have 2261 2261 * got the command. 2262 2262 */ 2263 - if (!sc->SCp.ptr) { 2263 + if (!iscsi_cmd(sc)->task) { 2264 2264 ISCSI_DBG_EH(session, "sc never reached iscsi layer or " 2265 2265 "it completed.\n"); 2266 2266 spin_unlock_bh(&session->frwd_lock); ··· 2273 2273 * then let the host reset code handle this 2274 2274 */ 2275 2275 if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN || 2276 - sc->SCp.phase != session->age) { 2276 + iscsi_cmd(sc)->age != session->age) { 2277 2277 spin_unlock_bh(&session->frwd_lock); 2278 2278 mutex_unlock(&session->eh_mutex); 2279 2279 ISCSI_DBG_EH(session, "failing abort due to dropped " ··· 2282 2282 } 2283 2283 2284 2284 spin_lock(&session->back_lock); 2285 - task = (struct iscsi_task *)sc->SCp.ptr; 2285 + task = iscsi_cmd(sc)->task; 2286 2286 if (!task || !task->sc) { 2287 2287 /* task completed before time out */ 2288 2288 ISCSI_DBG_EH(session, "sc completed while abort in progress\n");
+2 -2
drivers/scsi/qedi/qedi_fw.c
··· 603 603 goto error; 604 604 } 605 605 606 - if (!sc_cmd->SCp.ptr) { 606 + if (!iscsi_cmd(sc_cmd)->task) { 607 607 QEDI_WARN(&qedi->dbg_ctx, 608 - "SCp.ptr is NULL, returned in another context.\n"); 608 + "NULL task pointer, returned in another context.\n"); 609 609 goto error; 610 610 } 611 611
+1
drivers/scsi/qedi/qedi_iscsi.c
··· 59 59 .dma_boundary = QEDI_HW_DMA_BOUNDARY, 60 60 .cmd_per_lun = 128, 61 61 .shost_groups = qedi_shost_groups, 62 + .cmd_size = sizeof(struct iscsi_cmd), 62 63 }; 63 64 64 65 static void qedi_conn_free_login_resources(struct qedi_ctx *qedi,
+13 -3
drivers/scsi/qla4xxx/ql4_def.h
··· 216 216 #define IDC_COMP_TOV 5 217 217 #define LINK_UP_COMP_TOV 30 218 218 219 - #define CMD_SP(Cmnd) ((Cmnd)->SCp.ptr) 219 + /* 220 + * Note: the data structure below does not have a struct iscsi_cmd member since 221 + * the qla4xxx driver does not use libiscsi for SCSI I/O. 222 + */ 223 + struct qla4xxx_cmd_priv { 224 + struct srb *srb; 225 + }; 226 + 227 + static inline struct qla4xxx_cmd_priv *qla4xxx_cmd_priv(struct scsi_cmnd *cmd) 228 + { 229 + return scsi_cmd_priv(cmd); 230 + } 220 231 221 232 /* 222 - * SCSI Request Block structure (srb) that is placed 223 - * on cmd->SCp location of every I/O [We have 22 bytes available] 233 + * SCSI Request Block structure (srb) that is associated with each scsi_cmnd. 224 234 */ 225 235 struct srb { 226 236 struct list_head list; /* (8) */
+7 -6
drivers/scsi/qla4xxx/ql4_os.c
··· 226 226 .name = DRIVER_NAME, 227 227 .proc_name = DRIVER_NAME, 228 228 .queuecommand = qla4xxx_queuecommand, 229 + .cmd_size = sizeof(struct qla4xxx_cmd_priv), 229 230 230 231 .eh_abort_handler = qla4xxx_eh_abort, 231 232 .eh_device_reset_handler = qla4xxx_eh_device_reset, ··· 4055 4054 srb->ddb = ddb_entry; 4056 4055 srb->cmd = cmd; 4057 4056 srb->flags = 0; 4058 - CMD_SP(cmd) = (void *)srb; 4057 + qla4xxx_cmd_priv(cmd)->srb = srb; 4059 4058 4060 4059 return srb; 4061 4060 } ··· 4068 4067 scsi_dma_unmap(cmd); 4069 4068 srb->flags &= ~SRB_DMA_VALID; 4070 4069 } 4071 - CMD_SP(cmd) = NULL; 4070 + qla4xxx_cmd_priv(cmd)->srb = NULL; 4072 4071 } 4073 4072 4074 4073 void qla4xxx_srb_compl(struct kref *ref) ··· 4641 4640 * the scsi/block layer is going to prevent 4642 4641 * the tag from being released. 4643 4642 */ 4644 - if (cmd != NULL && CMD_SP(cmd)) 4643 + if (cmd != NULL && qla4xxx_cmd_priv(cmd)->srb) 4645 4644 break; 4646 4645 } 4647 4646 spin_unlock_irqrestore(&ha->hardware_lock, flags); ··· 9080 9079 if (!cmd) 9081 9080 return srb; 9082 9081 9083 - srb = (struct srb *)CMD_SP(cmd); 9082 + srb = qla4xxx_cmd_priv(cmd)->srb; 9084 9083 if (!srb) 9085 9084 return srb; 9086 9085 ··· 9122 9121 9123 9122 do { 9124 9123 /* Checking to see if its returned to OS */ 9125 - rp = (struct srb *) CMD_SP(cmd); 9124 + rp = qla4xxx_cmd_priv(cmd)->srb; 9126 9125 if (rp == NULL) { 9127 9126 done++; 9128 9127 break; ··· 9216 9215 } 9217 9216 9218 9217 spin_lock_irqsave(&ha->hardware_lock, flags); 9219 - srb = (struct srb *) CMD_SP(cmd); 9218 + srb = qla4xxx_cmd_priv(cmd)->srb; 9220 9219 if (!srb) { 9221 9220 spin_unlock_irqrestore(&ha->hardware_lock, flags); 9222 9221 ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Specified command has already completed.\n",
+12
include/scsi/libiscsi.h
··· 19 19 #include <linux/refcount.h> 20 20 #include <scsi/iscsi_proto.h> 21 21 #include <scsi/iscsi_if.h> 22 + #include <scsi/scsi_cmnd.h> 22 23 #include <scsi/scsi_transport_iscsi.h> 23 24 24 25 struct scsi_transport_template; ··· 151 150 return task->state == ISCSI_TASK_COMPLETED || 152 151 task->state == ISCSI_TASK_ABRT_TMF || 153 152 task->state == ISCSI_TASK_ABRT_SESS_RECOV; 153 + } 154 + 155 + /* Private data associated with struct scsi_cmnd. */ 156 + struct iscsi_cmd { 157 + struct iscsi_task *task; 158 + int age; 159 + }; 160 + 161 + static inline struct iscsi_cmd *iscsi_cmd(struct scsi_cmnd *cmd) 162 + { 163 + return scsi_cmd_priv(cmd); 154 164 } 155 165 156 166 /* Connection's states */