Re: [PATCH 2/3] target: simplify cmd to task mapping

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2010-11-17 at 16:38 -0500, Christoph Hellwig wrote:
> The cmd to task mapping is almost the same for all control CDBs,
> except for calling different backend methods to do the backed-specific
> mapping.  Merge the code performing the mapping into a single
> new transport_map_control_cmd_to_task helper, and kill the
> transport_map_task callback by simplify calling the backend methods
> directly for the single task for a control CDB, and hardcoding
> ->map_task_SG for data CDBs.
> 
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>

This one looks very reasonable as the extra set of bitwise AND
instructions is limited to control path code.

As for the first one, I don't really have a strong preference either
way, as long as the difference for extra 4 AND instructions for the bulk
'fast past' case is really a wash on modern x86_64 silicon..

--nab

> 
> Index: lio-core/drivers/target/target_core_transport.c
> ===================================================================
> --- lio-core.orig/drivers/target/target_core_transport.c	2010-11-16 18:55:26.414004751 +0100
> +++ lio-core/drivers/target/target_core_transport.c	2010-11-16 18:55:30.075004681 +0100
> @@ -2258,132 +2258,6 @@ static struct se_task *transport_generic
>  	return task;
>  }
>  
> -static int transport_do_se_mem_map(struct se_device *, struct se_task *,
> -	struct list_head *, void *, struct se_mem *, struct se_mem **,
> -	u32 *, u32 *);
> -
> -/*	transport_process_control_sg_transform():
> - *
> - *
> - */
> -static int transport_process_control_sg_transform(
> -	struct se_cmd *cmd,
> -	struct se_transform_info *ti)
> -{
> -	unsigned char *cdb;
> -	struct se_task *task;
> -	struct se_mem *se_mem, *se_mem_lout = NULL;
> -	struct se_device *dev = SE_DEV(cmd);
> -	int ret;
> -	u32 se_mem_cnt = 0, task_offset = 0;
> -
> -	list_for_each_entry(se_mem, T_TASK(cmd)->t_mem_list, se_list)
> -		break;
> -
> -	if (!se_mem) {
> -		printk(KERN_ERR "se_mem is NULL!\n");
> -		return -1;
> -	}
> -
> -	task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr,
> -					  cmd->data_direction);
> -	if (!(task))
> -		return -1;
> -
> -	task->transport_map_task = ti->se_obj_ptr->transport->map_task_SG;
> -
> -	cdb = TRANSPORT(dev)->get_cdb(task);
> -	if (cdb)
> -		memcpy(cdb, T_TASK(cmd)->t_task_cdb,
> -			scsi_command_size(T_TASK(cmd)->t_task_cdb));
> -
> -	task->task_size = cmd->data_length;
> -	task->task_sg_num = 1;
> -
> -	atomic_inc(&T_TASK(cmd)->t_fe_count);
> -	atomic_inc(&T_TASK(cmd)->t_se_count);
> -
> -	ret = transport_do_se_mem_map(ti->se_obj_ptr, task,
> -			T_TASK(cmd)->t_mem_list, NULL, se_mem, &se_mem_lout,
> -			&se_mem_cnt, &task_offset);
> -	if (ret < 0)
> -		return ret;
> -
> -	DEBUG_CDB_H("task_no[%u]: SCF_SCSI_CONTROL_SG_IO_CDB task_size: %d\n",
> -			task->task_no, task->task_size);
> -	return 0;
> -}
> -
> -/*	transport_process_control_nonsg_transform():
> - *
> - *
> - */
> -static int transport_process_control_nonsg_transform(
> -	struct se_cmd *cmd,
> -	struct se_transform_info *ti)
> -{
> -	struct se_device *dev = SE_DEV(cmd);
> -	unsigned char *cdb;
> -	struct se_task *task;
> -
> -	task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr,
> -					  cmd->data_direction);
> -	if (!(task))
> -		return -1;
> -
> -	task->transport_map_task = ti->se_obj_ptr->transport->map_task_non_SG;
> -
> -	cdb = TRANSPORT(dev)->get_cdb(task);
> -	if (cdb)
> -		memcpy(cdb, T_TASK(cmd)->t_task_cdb,
> -			scsi_command_size(T_TASK(cmd)->t_task_cdb));
> -
> -	task->task_size = cmd->data_length;
> -	task->task_sg_num = 0;
> -
> -	atomic_inc(&T_TASK(cmd)->t_fe_count);
> -	atomic_inc(&T_TASK(cmd)->t_se_count);
> -
> -	DEBUG_CDB_H("task_no[%u]: SCF_SCSI_CONTROL_NONSG_IO_CDB task_size:"
> -			" %d\n", task->task_no, task->task_size);
> -	return 0;
> -}
> -
> -/*	transport_process_non_data_transform():
> - *
> - *
> - */
> -static int transport_process_non_data_transform(
> -	struct se_cmd *cmd,
> -	struct se_transform_info *ti)
> -{
> -	struct se_device *dev = SE_DEV(cmd);
> -	unsigned char *cdb;
> -	struct se_task *task;
> -
> -	task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr,
> -					  cmd->data_direction);
> -	if (!(task))
> -		return -1;
> -
> -	task->transport_map_task = ti->se_obj_ptr->transport->cdb_none;
> -
> -	cdb = TRANSPORT(dev)->get_cdb(task);
> -	if (cdb)
> -		memcpy(cdb, T_TASK(cmd)->t_task_cdb,
> -			scsi_command_size(T_TASK(cmd)->t_task_cdb));
> -
> -	task->task_size = cmd->data_length;
> -	task->task_sg_num = 0;
> -
> -	atomic_inc(&T_TASK(cmd)->t_fe_count);
> -	atomic_inc(&T_TASK(cmd)->t_se_count);
> -
> -	DEBUG_CDB_H("task_no[%u]: SCF_SCSI_NON_DATA_CDB task_size: %d\n",
> -			task->task_no, task->task_size);
> -	return 0;
> -}
> -
>  static int transport_generic_cmd_sequencer(struct se_cmd *, unsigned char *);
>  
>  void transport_device_setup_cmd(struct se_cmd *cmd)
> @@ -5942,8 +5816,6 @@ u32 transport_generic_get_cdb_count(
>  		task->task_size = (task->task_sectors *
>  				   DEV_ATTRIB(dev)->block_size);
>  
> -		task->transport_map_task = dev->transport->map_task_SG;
> -
>  		cdb = TRANSPORT(dev)->get_cdb(task);
>  		if ((cdb)) {
>  			memcpy(cdb, T_TASK(cmd)->t_task_cdb,
> @@ -6011,6 +5883,61 @@ out:
>  	return 0;
>  }
>  
> +static int
> +transport_map_control_cmd_to_task(struct se_cmd *cmd,
> +		struct se_transform_info *ti)
> +{
> +	struct se_device *dev = SE_DEV(cmd);
> +	unsigned char *cdb;
> +	struct se_task *task;
> +	int ret;
> +
> +	task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr,
> +				  cmd->data_direction);
> +	if (!task)
> +		return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
> +
> +	cdb = TRANSPORT(dev)->get_cdb(task);
> +	if (cdb)
> +		memcpy(cdb, cmd->t_task->t_task_cdb,
> +			scsi_command_size(cmd->t_task->t_task_cdb));
> +
> +	task->task_size = cmd->data_length;
> +	task->task_sg_num =
> +		(cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) ? 1 : 0;
> +
> +	atomic_inc(&cmd->t_task->t_fe_count);
> +	atomic_inc(&cmd->t_task->t_se_count);
> +
> +	if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) {
> +		struct se_mem *se_mem, *se_mem_lout = NULL;
> +		u32 se_mem_cnt = 0, task_offset = 0;
> +
> +		BUG_ON(list_empty(cmd->t_task->t_mem_list));
> +
> +		ret = transport_do_se_mem_map(dev, task,
> +				cmd->t_task->t_mem_list, NULL, se_mem,
> +				&se_mem_lout, &se_mem_cnt, &task_offset);
> +		if (ret < 0)
> +			return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
> +
> +		if (dev->transport->map_task_SG)
> +			return dev->transport->map_task_SG(task);
> +		return 0;
> +	} else if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_NONSG_IO_CDB) {
> +		if (dev->transport->map_task_non_SG(task))
> +			return dev->transport->map_task_non_SG(task);
> +		return 0;
> +	} else if (cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB) {
> +		if (dev->transport->cdb_none(task))
> +			return dev->transport->cdb_none(task);
> +		return 0;
> +	} else {
> +		BUG();
> +		return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
> +	}
> +}
> +
>  /*	 transport_generic_new_cmd(): Called from transport_processing_thread()
>   *
>   *	 Allocate storage transport resources from a set of values predefined
> @@ -6041,16 +5968,17 @@ int transport_generic_new_cmd(struct se_
>  		if (!(cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) {
>  			ret = transport_allocate_resources(cmd);
>  			if (ret < 0)
> -				goto failure;
> +				return ret;
>  		}
>  
>  		ret = transport_get_sectors(cmd);
>  		if (ret < 0)
> -			goto failure;
> +			return ret;
>  
>  		ret = transport_new_cmd_obj(cmd, &ti, 0);
>  		if (ret < 0)
> -			goto failure;
> +			return ret;
> +
>  		/*
>  		 * Determine if the calling TCM fabric module is talking to
>  		 * Linux/NET via kernel sockets and needs to allocate a
> @@ -6059,41 +5987,26 @@ int transport_generic_new_cmd(struct se_
>  		se_tpg = SE_LUN(cmd)->lun_sep->sep_tpg;
>  		if (TPG_TFO(se_tpg)->alloc_cmd_iovecs != NULL) {
>  			ret = TPG_TFO(se_tpg)->alloc_cmd_iovecs(cmd);
> -			if (ret < 0) {
> -				ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
> -				goto failure;
> -			}
> +			if (ret < 0)
> +				return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
>  		}
>  	}
>  
> -	if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)
> -		ret = transport_process_control_sg_transform(cmd, &ti);
> -	else if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_NONSG_IO_CDB)
> -		ret = transport_process_control_nonsg_transform(cmd, &ti);
> -	else if (cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB)
> -		ret = transport_process_non_data_transform(cmd, &ti);
> -	else
> -		BUG_ON(!(cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB));
> -
> -	if (ret < 0) {
> -		ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
> -		goto failure;
> -	}
> +	if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) {
> +		list_for_each_entry(task, &T_TASK(cmd)->t_task_list, t_list) {
> +			if (atomic_read(&task->task_sent))
> +				continue;
> +			if (!ti.se_obj_ptr->transport->map_task_SG)
> +				continue;
>  
> -	/*
> -	 * Set the correct (usually DMAable) buffer pointers from the master
> -	 * buffer list in struct se_cmd to the transport task's native
> -	 * buffers format.
> -	 */
> -	list_for_each_entry(task, &T_TASK(cmd)->t_task_list, t_list) {
> -		if (atomic_read(&task->task_sent))
> -			continue;
> -
> -		if (task->transport_map_task) {
> -			ret = task->transport_map_task(task);
> +			ret = ti.se_obj_ptr->transport->map_task_SG(task);
>  			if (ret < 0)
> -				goto failure;
> +				return ret;
>  		}
> +	} else {
> +		ret = transport_map_control_cmd_to_task(cmd, &ti);
> +		if (ret < 0)
> +			return ret;
>  	}
>  
>  	/*
> @@ -6113,9 +6026,6 @@ int transport_generic_new_cmd(struct se_
>  	 */
>  	transport_execute_tasks(cmd);
>  	return 0;
> -
> -failure:
> -	return ret;
>  }
>  
>  /*	transport_generic_process_write():
> Index: lio-core/include/target/target_core_base.h
> ===================================================================
> --- lio-core.orig/include/target/target_core_base.h	2010-11-16 18:55:26.415004611 +0100
> +++ lio-core/include/target/target_core_base.h	2010-11-16 18:55:30.076003773 +0100
> @@ -499,7 +499,6 @@ struct se_task {
>  	atomic_t	task_stop;
>  	atomic_t	task_state_active;
>  	struct timer_list	task_timer;
> -	int (*transport_map_task)(struct se_task *);
>  	struct se_device *se_obj_ptr;
>  	struct list_head t_list;
>  	struct list_head t_execute_list;
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux