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 | 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 = { |
| @@ -218,7 +218,7 @@ static char const *cqe_desc[] = { · 217 unmodified lines | ||
| 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,6 +403,7 @@ static struct scsi_host_template beiscsi_sht = { · 178 unmodified lines | ||
| 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; |
| @@ -2268,6 +2268,7 @@ static struct scsi_host_template bnx2i_host_template = { · 2267 unmodified lines | ||
| 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 = { |
| @@ -98,6 +98,7 @@ static struct scsi_host_template cxgb3i_host_template = { · 97 unmodified lines | ||
| 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 = { |
| @@ -116,6 +116,7 @@ static struct scsi_host_template cxgb4i_host_template = { · 115 unmodified lines | ||
| 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 = { |
| @@ -1007,6 +1007,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = { · 1006 unmodified lines | ||
| 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 = { |
| @@ -462,7 +462,7 @@ static void iscsi_free_task(struct iscsi_task *task) · 461 unmodified lines | ||
| 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,10 +1344,10 @@ struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt) · 875 unmodified lines | ||
| 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,8 +1645,8 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn, · 291 unmodified lines | ||
| 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,7 +1683,7 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) · 30 unmodified lines | ||
| 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,7 +1997,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) · 307 unmodified lines | ||
| 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,7 +2260,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) · 256 unmodified lines | ||
| 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,7 +2273,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) · 6 unmodified lines | ||
| 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,7 +2282,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) · 2 unmodified lines | ||
| 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"); |
| @@ -603,9 +603,9 @@ static void qedi_scsi_completion(struct qedi_ctx *qedi, · 602 unmodified lines | ||
| 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 | |
| @@ -59,6 +59,7 @@ struct scsi_host_template qedi_host_template = { · 58 unmodified lines | ||
| 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, |
| @@ -216,11 +216,21 @@ · 215 unmodified lines | ||
| 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) */ |
| @@ -226,6 +226,7 @@ static struct scsi_host_template qla4xxx_driver_template = { · 225 unmodified lines | ||
| 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, |
| @@ -4054,7 +4055,7 @@ static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha, · 3822 unmodified lines | ||
| 4054 | 4055 | srb->ddb = ddb_entry; |
| 4055 | 4056 | srb->cmd = cmd; |
| 4056 | 4057 | srb->flags = 0; |
| 4057 | − CMD_SP(cmd) = (void *)srb; | |
| 4058 | + qla4xxx_cmd_priv(cmd)->srb = srb; | |
| 4058 | 4059 | |
| 4059 | 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 | 4068 | scsi_dma_unmap(cmd); |
| 4068 | 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 | 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 | 4641 | * the scsi/block layer is going to prevent |
| 4641 | 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 | 4645 | break; |
| 4645 | 4646 | } |
| 4646 | 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 | 9080 | if (!cmd) |
| 9080 | 9081 | return srb; |
| 9081 | 9082 | |
| 9082 | − srb = (struct srb *)CMD_SP(cmd); | |
| 9083 | + srb = qla4xxx_cmd_priv(cmd)->srb; | |
| 9083 | 9084 | if (!srb) |
| 9084 | 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 | 9123 | do { |
| 9123 | 9124 | /* Checking to see if its returned to OS */ |
| 9124 | − rp = (struct srb *) CMD_SP(cmd); | |
| 9125 | + rp = qla4xxx_cmd_priv(cmd)->srb; | |
| 9125 | 9126 | if (rp == NULL) { |
| 9126 | 9127 | done++; |
| 9127 | 9128 | break; |
| @@ -9215,7 +9216,7 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd) · 87 unmodified lines | ||
| 9215 | 9216 | } |
| 9216 | 9217 | |
| 9217 | 9218 | spin_lock_irqsave(&ha->hardware_lock, flags); |
| 9218 | − srb = (struct srb *) CMD_SP(cmd); | |
| 9219 | + srb = qla4xxx_cmd_priv(cmd)->srb; | |
| 9219 | 9220 | if (!srb) { |
| 9220 | 9221 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 9221 | 9222 | ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Specified command has already completed.\n", |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 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; |
| @@ -152,6 +153,17 @@ static inline bool iscsi_task_is_completed(struct iscsi_task *task) · 127 unmodified lines | ||
| 152 | 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 | 167 | /* Connection's states */ |
| 156 | 168 | enum { |
| 157 | 169 | ISCSI_CONN_INITIAL_STAGE, |