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
Unified · Split
| @@ -971,6 +971,7 @@ static struct scsi_host_template iscsi_iser_sht = { · 970 unmodified lines | |||
| 971 | .proc_name = "iscsi_iser", | 971 | .proc_name = "iscsi_iser", |
| 972 | .this_id = -1, | 972 | .this_id = -1, |
| 973 | .track_queue_depth = 1, | 973 | .track_queue_depth = 1, |
| 974 | .cmd_size = sizeof(struct iscsi_cmd), | ||
| 974 | }; | 975 | }; |
| 975 | 976 | ||
| 976 | static struct iscsi_transport iscsi_iser_transport = { | 977 | static struct iscsi_transport iscsi_iser_transport = { |
| @@ -218,7 +218,7 @@ static char const *cqe_desc[] = { · 217 unmodified lines | |||
| 218 | 218 | ||
| 219 | static int beiscsi_eh_abort(struct scsi_cmnd *sc) | 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 | struct iscsi_cls_session *cls_session; | 222 | struct iscsi_cls_session *cls_session; |
| 223 | struct beiscsi_io_task *abrt_io_task; | 223 | struct beiscsi_io_task *abrt_io_task; |
| 224 | struct beiscsi_conn *beiscsi_conn; | 224 | struct beiscsi_conn *beiscsi_conn; |
| @@ -403,6 +403,7 @@ static struct scsi_host_template beiscsi_sht = { · 178 unmodified lines | |||
| 403 | .cmd_per_lun = BEISCSI_CMD_PER_LUN, | 403 | .cmd_per_lun = BEISCSI_CMD_PER_LUN, |
| 404 | .vendor_id = SCSI_NL_VID_TYPE_PCI | BE_VENDOR_ID, | 404 | .vendor_id = SCSI_NL_VID_TYPE_PCI | BE_VENDOR_ID, |
| 405 | .track_queue_depth = 1, | 405 | .track_queue_depth = 1, |
| 406 | .cmd_size = sizeof(struct iscsi_cmd), | ||
| 406 | }; | 407 | }; |
| 407 | 408 | ||
| 408 | static struct scsi_transport_template *beiscsi_scsi_transport; | 409 | static struct scsi_transport_template *beiscsi_scsi_transport; |
| @@ -2268,6 +2268,7 @@ static struct scsi_host_template bnx2i_host_template = { · 2267 unmodified lines | |||
| 2268 | .sg_tablesize = ISCSI_MAX_BDS_PER_CMD, | 2268 | .sg_tablesize = ISCSI_MAX_BDS_PER_CMD, |
| 2269 | .shost_groups = bnx2i_dev_groups, | 2269 | .shost_groups = bnx2i_dev_groups, |
| 2270 | .track_queue_depth = 1, | 2270 | .track_queue_depth = 1, |
| 2271 | .cmd_size = sizeof(struct iscsi_cmd), | ||
| 2271 | }; | 2272 | }; |
| 2272 | 2273 | ||
| 2273 | struct iscsi_transport bnx2i_iscsi_transport = { | 2274 | struct iscsi_transport bnx2i_iscsi_transport = { |
| @@ -98,6 +98,7 @@ static struct scsi_host_template cxgb3i_host_template = { · 97 unmodified lines | |||
| 98 | .dma_boundary = PAGE_SIZE - 1, | 98 | .dma_boundary = PAGE_SIZE - 1, |
| 99 | .this_id = -1, | 99 | .this_id = -1, |
| 100 | .track_queue_depth = 1, | 100 | .track_queue_depth = 1, |
| 101 | .cmd_size = sizeof(struct iscsi_cmd), | ||
| 101 | }; | 102 | }; |
| 102 | 103 | ||
| 103 | static struct iscsi_transport cxgb3i_iscsi_transport = { | 104 | static struct iscsi_transport cxgb3i_iscsi_transport = { |
| @@ -116,6 +116,7 @@ static struct scsi_host_template cxgb4i_host_template = { · 115 unmodified lines | |||
| 116 | .dma_boundary = PAGE_SIZE - 1, | 116 | .dma_boundary = PAGE_SIZE - 1, |
| 117 | .this_id = -1, | 117 | .this_id = -1, |
| 118 | .track_queue_depth = 1, | 118 | .track_queue_depth = 1, |
| 119 | .cmd_size = sizeof(struct iscsi_cmd), | ||
| 119 | }; | 120 | }; |
| 120 | 121 | ||
| 121 | static struct iscsi_transport cxgb4i_iscsi_transport = { | 122 | static struct iscsi_transport cxgb4i_iscsi_transport = { |
| @@ -1007,6 +1007,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = { · 1006 unmodified lines | |||
| 1007 | .proc_name = "iscsi_tcp", | 1007 | .proc_name = "iscsi_tcp", |
| 1008 | .this_id = -1, | 1008 | .this_id = -1, |
| 1009 | .track_queue_depth = 1, | 1009 | .track_queue_depth = 1, |
| 1010 | .cmd_size = sizeof(struct iscsi_cmd), | ||
| 1010 | }; | 1011 | }; |
| 1011 | 1012 | ||
| 1012 | static struct iscsi_transport iscsi_sw_tcp_transport = { | 1013 | static struct iscsi_transport iscsi_sw_tcp_transport = { |
| @@ -462,7 +462,7 @@ static void iscsi_free_task(struct iscsi_task *task) · 461 unmodified lines | |||
| 462 | 462 | ||
| 463 | if (sc) { | 463 | if (sc) { |
| 464 | /* SCSI eh reuses commands to verify us */ | 464 | /* SCSI eh reuses commands to verify us */ |
| 465 | sc->SCp.ptr = NULL; | 465 | iscsi_cmd(sc)->task = NULL; |
| 466 | /* | 466 | /* |
| 467 | * queue command may call this to free the task, so | 467 | * queue command may call this to free the task, so |
| 468 | * it will decide how to return sc to scsi-ml. | 468 | * it will decide how to return sc to scsi-ml. |
| @@ -1344,10 +1344,10 @@ struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt) · 875 unmodified lines | |||
| 1344 | if (!task || !task->sc) | 1344 | if (!task || !task->sc) |
| 1345 | return NULL; | 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 | iscsi_session_printk(KERN_ERR, conn->session, | 1348 | iscsi_session_printk(KERN_ERR, conn->session, |
| 1349 | "task's session age %d, expected %d\n", | 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 | return NULL; | 1351 | return NULL; |
| 1352 | } | 1352 | } |
| 1353 | 1353 | ||
| @@ -1645,8 +1645,8 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn, · 291 unmodified lines | |||
| 1645 | (void *) &task, sizeof(void *))) | 1645 | (void *) &task, sizeof(void *))) |
| 1646 | return NULL; | 1646 | return NULL; |
| 1647 | 1647 | ||
| 1648 | sc->SCp.phase = conn->session->age; | 1648 | iscsi_cmd(sc)->age = conn->session->age; |
| 1649 | sc->SCp.ptr = (char *) task; | 1649 | iscsi_cmd(sc)->task = task; |
| 1650 | 1650 | ||
| 1651 | refcount_set(&task->refcount, 1); | 1651 | refcount_set(&task->refcount, 1); |
| 1652 | task->state = ISCSI_TASK_PENDING; | 1652 | task->state = ISCSI_TASK_PENDING; |
| @@ -1683,7 +1683,7 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) · 30 unmodified lines | |||
| 1683 | struct iscsi_task *task = NULL; | 1683 | struct iscsi_task *task = NULL; |
| 1684 | 1684 | ||
| 1685 | sc->result = 0; | 1685 | sc->result = 0; |
| 1686 | sc->SCp.ptr = NULL; | 1686 | iscsi_cmd(sc)->task = NULL; |
| 1687 | 1687 | ||
| 1688 | ihost = shost_priv(host); | 1688 | ihost = shost_priv(host); |
| 1689 | 1689 | ||
| @@ -1997,7 +1997,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) · 307 unmodified lines | |||
| 1997 | 1997 | ||
| 1998 | spin_lock_bh(&session->frwd_lock); | 1998 | spin_lock_bh(&session->frwd_lock); |
| 1999 | spin_lock(&session->back_lock); | 1999 | spin_lock(&session->back_lock); |
| 2000 | task = (struct iscsi_task *)sc->SCp.ptr; | 2000 | task = iscsi_cmd(sc)->task; |
| 2001 | if (!task) { | 2001 | if (!task) { |
| 2002 | /* | 2002 | /* |
| 2003 | * Raced with completion. Blk layer has taken ownership | 2003 | * Raced with completion. Blk layer has taken ownership |
| @@ -2260,7 +2260,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) · 256 unmodified lines | |||
| 2260 | * if session was ISCSI_STATE_IN_RECOVERY then we may not have | 2260 | * if session was ISCSI_STATE_IN_RECOVERY then we may not have |
| 2261 | * got the command. | 2261 | * got the command. |
| 2262 | */ | 2262 | */ |
| 2263 | if (!sc->SCp.ptr) { | 2263 | if (!iscsi_cmd(sc)->task) { |
| 2264 | ISCSI_DBG_EH(session, "sc never reached iscsi layer or " | 2264 | ISCSI_DBG_EH(session, "sc never reached iscsi layer or " |
| 2265 | "it completed.\n"); | 2265 | "it completed.\n"); |
| 2266 | spin_unlock_bh(&session->frwd_lock); | 2266 | spin_unlock_bh(&session->frwd_lock); |
| @@ -2273,7 +2273,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) · 6 unmodified lines | |||
| 2273 | * then let the host reset code handle this | 2273 | * then let the host reset code handle this |
| 2274 | */ | 2274 | */ |
| 2275 | if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN || | 2275 | if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN || |
| 2276 | sc->SCp.phase != session->age) { | 2276 | iscsi_cmd(sc)->age != session->age) { |
| 2277 | spin_unlock_bh(&session->frwd_lock); | 2277 | spin_unlock_bh(&session->frwd_lock); |
| 2278 | mutex_unlock(&session->eh_mutex); | 2278 | mutex_unlock(&session->eh_mutex); |
| 2279 | ISCSI_DBG_EH(session, "failing abort due to dropped " | 2279 | ISCSI_DBG_EH(session, "failing abort due to dropped " |
| @@ -2282,7 +2282,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) · 2 unmodified lines | |||
| 2282 | } | 2282 | } |
| 2283 | 2283 | ||
| 2284 | spin_lock(&session->back_lock); | 2284 | spin_lock(&session->back_lock); |
| 2285 | task = (struct iscsi_task *)sc->SCp.ptr; | 2285 | task = iscsi_cmd(sc)->task; |
| 2286 | if (!task || !task->sc) { | 2286 | if (!task || !task->sc) { |
| 2287 | /* task completed before time out */ | 2287 | /* task completed before time out */ |
| 2288 | ISCSI_DBG_EH(session, "sc completed while abort in progress\n"); | 2288 | ISCSI_DBG_EH(session, "sc completed while abort in progress\n"); |
| @@ -603,9 +603,9 @@ static void qedi_scsi_completion(struct qedi_ctx *qedi, · 602 unmodified lines | |||
| 603 | goto error; | 603 | goto error; |
| 604 | } | 604 | } |
| 605 | 605 | ||
| 606 | if (!sc_cmd->SCp.ptr) { | 606 | if (!iscsi_cmd(sc_cmd)->task) { |
| 607 | QEDI_WARN(&qedi->dbg_ctx, | 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 | goto error; | 609 | goto error; |
| 610 | } | 610 | } |
| 611 | 611 | ||
| @@ -59,6 +59,7 @@ struct scsi_host_template qedi_host_template = { · 58 unmodified lines | |||
| 59 | .dma_boundary = QEDI_HW_DMA_BOUNDARY, | 59 | .dma_boundary = QEDI_HW_DMA_BOUNDARY, |
| 60 | .cmd_per_lun = 128, | 60 | .cmd_per_lun = 128, |
| 61 | .shost_groups = qedi_shost_groups, | 61 | .shost_groups = qedi_shost_groups, |
| 62 | .cmd_size = sizeof(struct iscsi_cmd), | ||
| 62 | }; | 63 | }; |
| 63 | 64 | ||
| 64 | static void qedi_conn_free_login_resources(struct qedi_ctx *qedi, | 65 | static void qedi_conn_free_login_resources(struct qedi_ctx *qedi, |
| @@ -216,11 +216,21 @@ · 215 unmodified lines | |||
| 216 | #define IDC_COMP_TOV 5 | 216 | #define IDC_COMP_TOV 5 |
| 217 | #define LINK_UP_COMP_TOV 30 | 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 | 233 | * SCSI Request Block structure (srb) that is associated with each scsi_cmnd. |
| 223 | * on cmd->SCp location of every I/O [We have 22 bytes available] | ||
| 224 | */ | 234 | */ |
| 225 | struct srb { | 235 | struct srb { |
| 226 | struct list_head list; /* (8) */ | 236 | struct list_head list; /* (8) */ |
| @@ -226,6 +226,7 @@ static struct scsi_host_template qla4xxx_driver_template = { · 225 unmodified lines | |||
| 226 | .name = DRIVER_NAME, | 226 | .name = DRIVER_NAME, |
| 227 | .proc_name = DRIVER_NAME, | 227 | .proc_name = DRIVER_NAME, |
| 228 | .queuecommand = qla4xxx_queuecommand, | 228 | .queuecommand = qla4xxx_queuecommand, |
| 229 | .cmd_size = sizeof(struct qla4xxx_cmd_priv), | ||
| 229 | 230 | ||
| 230 | .eh_abort_handler = qla4xxx_eh_abort, | 231 | .eh_abort_handler = qla4xxx_eh_abort, |
| 231 | .eh_device_reset_handler = qla4xxx_eh_device_reset, | 232 | .eh_device_reset_handler = qla4xxx_eh_device_reset, |
| @@ -4054,7 +4055,7 @@ static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha, · 3822 unmodified lines | |||
| 4054 | srb->ddb = ddb_entry; | 4055 | srb->ddb = ddb_entry; |
| 4055 | srb->cmd = cmd; | 4056 | srb->cmd = cmd; |
| 4056 | srb->flags = 0; | 4057 | srb->flags = 0; |
| 4057 | CMD_SP(cmd) = (void *)srb; | 4058 | qla4xxx_cmd_priv(cmd)->srb = srb; |
| 4058 | 4059 | ||
| 4059 | return srb; | 4060 | return srb; |
| 4060 | } | 4061 | } |
| @@ -4067,7 +4068,7 @@ static void qla4xxx_srb_free_dma(struct scsi_qla_host *ha, struct srb *srb) · 6 unmodified lines | |||
| 4067 | scsi_dma_unmap(cmd); | 4068 | scsi_dma_unmap(cmd); |
| 4068 | srb->flags &= ~SRB_DMA_VALID; | 4069 | srb->flags &= ~SRB_DMA_VALID; |
| 4069 | } | 4070 | } |
| 4070 | CMD_SP(cmd) = NULL; | 4071 | qla4xxx_cmd_priv(cmd)->srb = NULL; |
| 4071 | } | 4072 | } |
| 4072 | 4073 | ||
| 4073 | void qla4xxx_srb_compl(struct kref *ref) | 4074 | void qla4xxx_srb_compl(struct kref *ref) |
| @@ -4640,7 +4641,7 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha) · 566 unmodified lines | |||
| 4640 | * the scsi/block layer is going to prevent | 4641 | * the scsi/block layer is going to prevent |
| 4641 | * the tag from being released. | 4642 | * the tag from being released. |
| 4642 | */ | 4643 | */ |
| 4643 | if (cmd != NULL && CMD_SP(cmd)) | 4644 | if (cmd != NULL && qla4xxx_cmd_priv(cmd)->srb) |
| 4644 | break; | 4645 | break; |
| 4645 | } | 4646 | } |
| 4646 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4647 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| @@ -9079,7 +9080,7 @@ struct srb *qla4xxx_del_from_active_array(struct scsi_qla_host *ha, · 4432 unmodified lines | |||
| 9079 | if (!cmd) | 9080 | if (!cmd) |
| 9080 | return srb; | 9081 | return srb; |
| 9081 | 9082 | ||
| 9082 | srb = (struct srb *)CMD_SP(cmd); | 9083 | srb = qla4xxx_cmd_priv(cmd)->srb; |
| 9083 | if (!srb) | 9084 | if (!srb) |
| 9084 | return srb; | 9085 | return srb; |
| 9085 | 9086 | ||
| @@ -9121,7 +9122,7 @@ static int qla4xxx_eh_wait_on_command(struct scsi_qla_host *ha, · 35 unmodified lines | |||
| 9121 | 9122 | ||
| 9122 | do { | 9123 | do { |
| 9123 | /* Checking to see if its returned to OS */ | 9124 | /* Checking to see if its returned to OS */ |
| 9124 | rp = (struct srb *) CMD_SP(cmd); | 9125 | rp = qla4xxx_cmd_priv(cmd)->srb; |
| 9125 | if (rp == NULL) { | 9126 | if (rp == NULL) { |
| 9126 | done++; | 9127 | done++; |
| 9127 | break; | 9128 | break; |
| @@ -9215,7 +9216,7 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd) · 87 unmodified lines | |||
| 9215 | } | 9216 | } |
| 9216 | 9217 | ||
| 9217 | spin_lock_irqsave(&ha->hardware_lock, flags); | 9218 | spin_lock_irqsave(&ha->hardware_lock, flags); |
| 9218 | srb = (struct srb *) CMD_SP(cmd); | 9219 | srb = qla4xxx_cmd_priv(cmd)->srb; |
| 9219 | if (!srb) { | 9220 | if (!srb) { |
| 9220 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 9221 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 9221 | ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Specified command has already completed.\n", | 9222 | ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Specified command has already completed.\n", |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/refcount.h> | 19 | #include <linux/refcount.h> |
| 20 | #include <scsi/iscsi_proto.h> | 20 | #include <scsi/iscsi_proto.h> |
| 21 | #include <scsi/iscsi_if.h> | 21 | #include <scsi/iscsi_if.h> |
| 22 | #include <scsi/scsi_cmnd.h> | ||
| 22 | #include <scsi/scsi_transport_iscsi.h> | 23 | #include <scsi/scsi_transport_iscsi.h> |
| 23 | 24 | ||
| 24 | struct scsi_transport_template; | 25 | struct scsi_transport_template; |
| @@ -152,6 +153,17 @@ static inline bool iscsi_task_is_completed(struct iscsi_task *task) · 127 unmodified lines | |||
| 152 | task->state == ISCSI_TASK_ABRT_SESS_RECOV; | 153 | task->state == ISCSI_TASK_ABRT_SESS_RECOV; |
| 153 | } | 154 | } |
| 154 | 155 | ||
| 156 | /* Private data associated with struct scsi_cmnd. */ | ||
| 157 | struct iscsi_cmd { | ||
| 158 | struct iscsi_task *task; | ||
| 159 | int age; | ||
| 160 | }; | ||
| 161 | |||
| 162 | static inline struct iscsi_cmd *iscsi_cmd(struct scsi_cmnd *cmd) | ||
| 163 | { | ||
| 164 | return scsi_cmd_priv(cmd); | ||
| 165 | } | ||
| 166 | |||
| 155 | /* Connection's states */ | 167 | /* Connection's states */ |
| 156 | enum { | 168 | enum { |
| 157 | ISCSI_CONN_INITIAL_STAGE, | 169 | ISCSI_CONN_INITIAL_STAGE, |