forked from mirrors/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>
This commit is contained in:
		
							parent
							
								
									6b66f09c46
								
							
						
					
					
						commit
						db22de3eb0
					
				
					 12 changed files with 52 additions and 22 deletions
				
			
		|  | @ -971,6 +971,7 @@ static struct scsi_host_template iscsi_iser_sht = { | |||
| 	.proc_name              = "iscsi_iser", | ||||
| 	.this_id                = -1, | ||||
| 	.track_queue_depth	= 1, | ||||
| 	.cmd_size		= sizeof(struct iscsi_cmd), | ||||
| }; | ||||
| 
 | ||||
| static struct iscsi_transport iscsi_iser_transport = { | ||||
|  |  | |||
|  | @ -218,7 +218,7 @@ static char const *cqe_desc[] = { | |||
| 
 | ||||
| static int beiscsi_eh_abort(struct scsi_cmnd *sc) | ||||
| { | ||||
| 	struct iscsi_task *abrt_task = (struct iscsi_task *)sc->SCp.ptr; | ||||
| 	struct iscsi_task *abrt_task = iscsi_cmd(sc)->task; | ||||
| 	struct iscsi_cls_session *cls_session; | ||||
| 	struct beiscsi_io_task *abrt_io_task; | ||||
| 	struct beiscsi_conn *beiscsi_conn; | ||||
|  | @ -403,6 +403,7 @@ static struct scsi_host_template beiscsi_sht = { | |||
| 	.cmd_per_lun = BEISCSI_CMD_PER_LUN, | ||||
| 	.vendor_id = SCSI_NL_VID_TYPE_PCI | BE_VENDOR_ID, | ||||
| 	.track_queue_depth = 1, | ||||
| 	.cmd_size = sizeof(struct iscsi_cmd), | ||||
| }; | ||||
| 
 | ||||
| static struct scsi_transport_template *beiscsi_scsi_transport; | ||||
|  |  | |||
|  | @ -2268,6 +2268,7 @@ static struct scsi_host_template bnx2i_host_template = { | |||
| 	.sg_tablesize		= ISCSI_MAX_BDS_PER_CMD, | ||||
| 	.shost_groups		= bnx2i_dev_groups, | ||||
| 	.track_queue_depth	= 1, | ||||
| 	.cmd_size		= sizeof(struct iscsi_cmd), | ||||
| }; | ||||
| 
 | ||||
| struct iscsi_transport bnx2i_iscsi_transport = { | ||||
|  |  | |||
|  | @ -98,6 +98,7 @@ static struct scsi_host_template cxgb3i_host_template = { | |||
| 	.dma_boundary	= PAGE_SIZE - 1, | ||||
| 	.this_id	= -1, | ||||
| 	.track_queue_depth = 1, | ||||
| 	.cmd_size	= sizeof(struct iscsi_cmd), | ||||
| }; | ||||
| 
 | ||||
| static struct iscsi_transport cxgb3i_iscsi_transport = { | ||||
|  |  | |||
|  | @ -116,6 +116,7 @@ static struct scsi_host_template cxgb4i_host_template = { | |||
| 	.dma_boundary	= PAGE_SIZE - 1, | ||||
| 	.this_id	= -1, | ||||
| 	.track_queue_depth = 1, | ||||
| 	.cmd_size	= sizeof(struct iscsi_cmd), | ||||
| }; | ||||
| 
 | ||||
| static struct iscsi_transport cxgb4i_iscsi_transport = { | ||||
|  |  | |||
|  | @ -1007,6 +1007,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = { | |||
| 	.proc_name		= "iscsi_tcp", | ||||
| 	.this_id		= -1, | ||||
| 	.track_queue_depth	= 1, | ||||
| 	.cmd_size		= sizeof(struct iscsi_cmd), | ||||
| }; | ||||
| 
 | ||||
| static struct iscsi_transport iscsi_sw_tcp_transport = { | ||||
|  |  | |||
|  | @ -462,7 +462,7 @@ static void iscsi_free_task(struct iscsi_task *task) | |||
| 
 | ||||
| 	if (sc) { | ||||
| 		/* SCSI eh reuses commands to verify us */ | ||||
| 		sc->SCp.ptr = NULL; | ||||
| 		iscsi_cmd(sc)->task = NULL; | ||||
| 		/*
 | ||||
| 		 * queue command may call this to free the task, so | ||||
| 		 * 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) | |||
| 	if (!task || !task->sc) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	if (task->sc->SCp.phase != conn->session->age) { | ||||
| 	if (iscsi_cmd(task->sc)->age != conn->session->age) { | ||||
| 		iscsi_session_printk(KERN_ERR, conn->session, | ||||
| 				  "task's session age %d, expected %d\n", | ||||
| 				  task->sc->SCp.phase, conn->session->age); | ||||
| 				  iscsi_cmd(task->sc)->age, conn->session->age); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1645,8 +1645,8 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn, | |||
| 			 (void *) &task, sizeof(void *))) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	sc->SCp.phase = conn->session->age; | ||||
| 	sc->SCp.ptr = (char *) task; | ||||
| 	iscsi_cmd(sc)->age = conn->session->age; | ||||
| 	iscsi_cmd(sc)->task = task; | ||||
| 
 | ||||
| 	refcount_set(&task->refcount, 1); | ||||
| 	task->state = ISCSI_TASK_PENDING; | ||||
|  | @ -1683,7 +1683,7 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) | |||
| 	struct iscsi_task *task = NULL; | ||||
| 
 | ||||
| 	sc->result = 0; | ||||
| 	sc->SCp.ptr = NULL; | ||||
| 	iscsi_cmd(sc)->task = NULL; | ||||
| 
 | ||||
| 	ihost = shost_priv(host); | ||||
| 
 | ||||
|  | @ -1997,7 +1997,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) | |||
| 
 | ||||
| 	spin_lock_bh(&session->frwd_lock); | ||||
| 	spin_lock(&session->back_lock); | ||||
| 	task = (struct iscsi_task *)sc->SCp.ptr; | ||||
| 	task = iscsi_cmd(sc)->task; | ||||
| 	if (!task) { | ||||
| 		/*
 | ||||
| 		 * Raced with completion. Blk layer has taken ownership | ||||
|  | @ -2260,7 +2260,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) | |||
| 	 * if session was ISCSI_STATE_IN_RECOVERY then we may not have | ||||
| 	 * got the command. | ||||
| 	 */ | ||||
| 	if (!sc->SCp.ptr) { | ||||
| 	if (!iscsi_cmd(sc)->task) { | ||||
| 		ISCSI_DBG_EH(session, "sc never reached iscsi layer or " | ||||
| 				      "it completed.\n"); | ||||
| 		spin_unlock_bh(&session->frwd_lock); | ||||
|  | @ -2273,7 +2273,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) | |||
| 	 * then let the host reset code handle this | ||||
| 	 */ | ||||
| 	if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN || | ||||
| 	    sc->SCp.phase != session->age) { | ||||
| 	    iscsi_cmd(sc)->age != session->age) { | ||||
| 		spin_unlock_bh(&session->frwd_lock); | ||||
| 		mutex_unlock(&session->eh_mutex); | ||||
| 		ISCSI_DBG_EH(session, "failing abort due to dropped " | ||||
|  | @ -2282,7 +2282,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) | |||
| 	} | ||||
| 
 | ||||
| 	spin_lock(&session->back_lock); | ||||
| 	task = (struct iscsi_task *)sc->SCp.ptr; | ||||
| 	task = iscsi_cmd(sc)->task; | ||||
| 	if (!task || !task->sc) { | ||||
| 		/* task completed before time out */ | ||||
| 		ISCSI_DBG_EH(session, "sc completed while abort in progress\n"); | ||||
|  |  | |||
|  | @ -603,9 +603,9 @@ static void qedi_scsi_completion(struct qedi_ctx *qedi, | |||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!sc_cmd->SCp.ptr) { | ||||
| 	if (!iscsi_cmd(sc_cmd)->task) { | ||||
| 		QEDI_WARN(&qedi->dbg_ctx, | ||||
| 			  "SCp.ptr is NULL, returned in another context.\n"); | ||||
| 			  "NULL task pointer, returned in another context.\n"); | ||||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -59,6 +59,7 @@ struct scsi_host_template qedi_host_template = { | |||
| 	.dma_boundary = QEDI_HW_DMA_BOUNDARY, | ||||
| 	.cmd_per_lun = 128, | ||||
| 	.shost_groups = qedi_shost_groups, | ||||
| 	.cmd_size = sizeof(struct iscsi_cmd), | ||||
| }; | ||||
| 
 | ||||
| static void qedi_conn_free_login_resources(struct qedi_ctx *qedi, | ||||
|  |  | |||
|  | @ -216,11 +216,21 @@ | |||
| #define IDC_COMP_TOV			5 | ||||
| #define LINK_UP_COMP_TOV		30 | ||||
| 
 | ||||
| #define CMD_SP(Cmnd)			((Cmnd)->SCp.ptr) | ||||
| /*
 | ||||
|  * Note: the data structure below does not have a struct iscsi_cmd member since | ||||
|  * the qla4xxx driver does not use libiscsi for SCSI I/O. | ||||
|  */ | ||||
| struct qla4xxx_cmd_priv { | ||||
| 	struct srb *srb; | ||||
| }; | ||||
| 
 | ||||
| static inline struct qla4xxx_cmd_priv *qla4xxx_cmd_priv(struct scsi_cmnd *cmd) | ||||
| { | ||||
| 	return scsi_cmd_priv(cmd); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * SCSI Request Block structure	 (srb)	that is placed | ||||
|  * on cmd->SCp location of every I/O	 [We have 22 bytes available] | ||||
|  * SCSI Request Block structure (srb) that is associated with each scsi_cmnd. | ||||
|  */ | ||||
| struct srb { | ||||
| 	struct list_head list;	/* (8)	 */ | ||||
|  |  | |||
|  | @ -226,6 +226,7 @@ static struct scsi_host_template qla4xxx_driver_template = { | |||
| 	.name			= DRIVER_NAME, | ||||
| 	.proc_name		= DRIVER_NAME, | ||||
| 	.queuecommand		= qla4xxx_queuecommand, | ||||
| 	.cmd_size		= sizeof(struct qla4xxx_cmd_priv), | ||||
| 
 | ||||
| 	.eh_abort_handler	= qla4xxx_eh_abort, | ||||
| 	.eh_device_reset_handler = qla4xxx_eh_device_reset, | ||||
|  | @ -4054,7 +4055,7 @@ static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha, | |||
| 	srb->ddb = ddb_entry; | ||||
| 	srb->cmd = cmd; | ||||
| 	srb->flags = 0; | ||||
| 	CMD_SP(cmd) = (void *)srb; | ||||
| 	qla4xxx_cmd_priv(cmd)->srb = srb; | ||||
| 
 | ||||
| 	return srb; | ||||
| } | ||||
|  | @ -4067,7 +4068,7 @@ static void qla4xxx_srb_free_dma(struct scsi_qla_host *ha, struct srb *srb) | |||
| 		scsi_dma_unmap(cmd); | ||||
| 		srb->flags &= ~SRB_DMA_VALID; | ||||
| 	} | ||||
| 	CMD_SP(cmd) = NULL; | ||||
| 	qla4xxx_cmd_priv(cmd)->srb = NULL; | ||||
| } | ||||
| 
 | ||||
| void qla4xxx_srb_compl(struct kref *ref) | ||||
|  | @ -4640,7 +4641,7 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha) | |||
| 			 * the scsi/block layer is going to prevent | ||||
| 			 * the tag from being released. | ||||
| 			 */ | ||||
| 			if (cmd != NULL && CMD_SP(cmd)) | ||||
| 			if (cmd != NULL && qla4xxx_cmd_priv(cmd)->srb) | ||||
| 				break; | ||||
| 		} | ||||
| 		spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||||
|  | @ -9079,7 +9080,7 @@ struct srb *qla4xxx_del_from_active_array(struct scsi_qla_host *ha, | |||
| 	if (!cmd) | ||||
| 		return srb; | ||||
| 
 | ||||
| 	srb = (struct srb *)CMD_SP(cmd); | ||||
| 	srb = qla4xxx_cmd_priv(cmd)->srb; | ||||
| 	if (!srb) | ||||
| 		return srb; | ||||
| 
 | ||||
|  | @ -9121,7 +9122,7 @@ static int qla4xxx_eh_wait_on_command(struct scsi_qla_host *ha, | |||
| 
 | ||||
| 	do { | ||||
| 		/* Checking to see if its returned to OS */ | ||||
| 		rp = (struct srb *) CMD_SP(cmd); | ||||
| 		rp = qla4xxx_cmd_priv(cmd)->srb; | ||||
| 		if (rp == NULL) { | ||||
| 			done++; | ||||
| 			break; | ||||
|  | @ -9215,7 +9216,7 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd) | |||
| 	} | ||||
| 
 | ||||
| 	spin_lock_irqsave(&ha->hardware_lock, flags); | ||||
| 	srb = (struct srb *) CMD_SP(cmd); | ||||
| 	srb = qla4xxx_cmd_priv(cmd)->srb; | ||||
| 	if (!srb) { | ||||
| 		spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||||
| 		ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%llu: Specified command has already completed.\n", | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ | |||
| #include <linux/refcount.h> | ||||
| #include <scsi/iscsi_proto.h> | ||||
| #include <scsi/iscsi_if.h> | ||||
| #include <scsi/scsi_cmnd.h> | ||||
| #include <scsi/scsi_transport_iscsi.h> | ||||
| 
 | ||||
| struct scsi_transport_template; | ||||
|  | @ -152,6 +153,17 @@ static inline bool iscsi_task_is_completed(struct iscsi_task *task) | |||
| 	       task->state == ISCSI_TASK_ABRT_SESS_RECOV; | ||||
| } | ||||
| 
 | ||||
| /* Private data associated with struct scsi_cmnd. */ | ||||
| struct iscsi_cmd { | ||||
| 	struct iscsi_task	*task; | ||||
| 	int			age; | ||||
| }; | ||||
| 
 | ||||
| static inline struct iscsi_cmd *iscsi_cmd(struct scsi_cmnd *cmd) | ||||
| { | ||||
| 	return scsi_cmd_priv(cmd); | ||||
| } | ||||
| 
 | ||||
| /* Connection's states */ | ||||
| enum { | ||||
| 	ISCSI_CONN_INITIAL_STAGE, | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Bart Van Assche
						Bart Van Assche