Re: [PATCH 1/3] target: Add tracepoints for SCSI commands being processed

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

 



On Wed, 2013-06-26 at 17:36 -0700, Roland Dreier wrote:
> From: Roland Dreier <roland@xxxxxxxxxxxxxxx>
> 
> This patch adds tracepoints to the target code for commands being
> received and being completed, which is quite useful for debugging
> interactions with initiators. For example, one can do something like the
> following to watch commands that are completing unsuccessfully:
> 
>     # echo 'scsi_status!=0' > /sys/kernel/debug/tracing/events/target/target_cmd_complete/filter
>     # echo 1 > /sys/kernel/debug/tracing/events/target/target_cmd_complete/enable
> 
>         <run command that fails>
> 
>     # cat /sys/kernel/debug/tracing/trace
>          iscsi_trx-0-1902  [003] ...1 990185.810385: target_cmd_complete: iqn.1993-08.org.debian:01:e51ede6aacfd <- LUN 001 status CHECK CONDITION (sense len 18 / 70 00 05 00 00 00 00 0a 00 00 00 00 20 00 00 00 00 00)  0x95 data_length    512  CDB 95 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  (TA:SIMPLE C:00)
> 
> Signed-off-by: Roland Dreier <roland@xxxxxxxxxxxxxxx>
> ---

Hi Roland,

Apologies for the delay.

Applied to for-next w/ the extra patch to drop COMPARE_AND_WRITE for
now..

Thanks,

--nab

>  drivers/target/target_core_transport.c |  16 ++-
>  include/trace/events/target.h          | 215 +++++++++++++++++++++++++++++++++
>  2 files changed, 230 insertions(+), 1 deletion(-)
>  create mode 100644 include/trace/events/target.h
> 
> diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
> index 21e3158..054fb3d 100644
> --- a/drivers/target/target_core_transport.c
> +++ b/drivers/target/target_core_transport.c
> @@ -52,6 +52,9 @@
>  #include "target_core_pr.h"
>  #include "target_core_ua.h"
>  
> +#define CREATE_TRACE_POINTS
> +#include <trace/events/target.h>
> +
>  static struct workqueue_struct *target_completion_wq;
>  static struct kmem_cache *se_sess_cache;
>  struct kmem_cache *se_ua_cache;
> @@ -1127,6 +1130,8 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
>  	 */
>  	memcpy(cmd->t_task_cdb, cdb, scsi_command_size(cdb));
>  
> +	trace_target_sequencer_start(cmd);
> +
>  	/*
>  	 * Check for an existing UNIT ATTENTION condition
>  	 */
> @@ -1552,7 +1557,8 @@ void transport_generic_request_failure(struct se_cmd *cmd,
>  				cmd->orig_fe_lun, 0x2C,
>  				ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS);
>  
> -		ret = cmd->se_tfo->queue_status(cmd);
> +		trace_target_cmd_complete(cmd);
> +		ret = cmd->se_tfo-> queue_status(cmd);
>  		if (ret == -EAGAIN || ret == -ENOMEM)
>  			goto queue_full;
>  		goto check_stop;
> @@ -1770,6 +1776,7 @@ static void transport_complete_qf(struct se_cmd *cmd)
>  	transport_complete_task_attr(cmd);
>  
>  	if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) {
> +		trace_target_cmd_complete(cmd);
>  		ret = cmd->se_tfo->queue_status(cmd);
>  		if (ret)
>  			goto out;
> @@ -1777,6 +1784,7 @@ static void transport_complete_qf(struct se_cmd *cmd)
>  
>  	switch (cmd->data_direction) {
>  	case DMA_FROM_DEVICE:
> +		trace_target_cmd_complete(cmd);
>  		ret = cmd->se_tfo->queue_data_in(cmd);
>  		break;
>  	case DMA_TO_DEVICE:
> @@ -1787,6 +1795,7 @@ static void transport_complete_qf(struct se_cmd *cmd)
>  		}
>  		/* Fall through for DMA_TO_DEVICE */
>  	case DMA_NONE:
> +		trace_target_cmd_complete(cmd);
>  		ret = cmd->se_tfo->queue_status(cmd);
>  		break;
>  	default:
> @@ -1865,6 +1874,7 @@ static void target_complete_ok_work(struct work_struct *work)
>  		}
>  		spin_unlock(&cmd->se_lun->lun_sep_lock);
>  
> +		trace_target_cmd_complete(cmd);
>  		ret = cmd->se_tfo->queue_data_in(cmd);
>  		if (ret == -EAGAIN || ret == -ENOMEM)
>  			goto queue_full;
> @@ -1893,6 +1903,7 @@ static void target_complete_ok_work(struct work_struct *work)
>  		}
>  		/* Fall through for DMA_TO_DEVICE */
>  	case DMA_NONE:
> +		trace_target_cmd_complete(cmd);
>  		ret = cmd->se_tfo->queue_status(cmd);
>  		if (ret == -EAGAIN || ret == -ENOMEM)
>  			goto queue_full;
> @@ -2778,6 +2789,7 @@ transport_send_check_condition_and_sense(struct se_cmd *cmd,
>  	cmd->scsi_sense_length  = TRANSPORT_SENSE_BUFFER;
>  
>  after_reason:
> +	trace_target_cmd_complete(cmd);
>  	return cmd->se_tfo->queue_status(cmd);
>  }
>  EXPORT_SYMBOL(transport_send_check_condition_and_sense);
> @@ -2794,6 +2806,7 @@ int transport_check_aborted_status(struct se_cmd *cmd, int send_status)
>  		 cmd->t_task_cdb[0], cmd->se_tfo->get_task_tag(cmd));
>  
>  	cmd->se_cmd_flags |= SCF_SENT_DELAYED_TAS;
> +	trace_target_cmd_complete(cmd);
>  	cmd->se_tfo->queue_status(cmd);
>  
>  	return 1;
> @@ -2831,6 +2844,7 @@ void transport_send_task_abort(struct se_cmd *cmd)
>  		" ITT: 0x%08x\n", cmd->t_task_cdb[0],
>  		cmd->se_tfo->get_task_tag(cmd));
>  
> +	trace_target_cmd_complete(cmd);
>  	cmd->se_tfo->queue_status(cmd);
>  }
>  
> diff --git a/include/trace/events/target.h b/include/trace/events/target.h
> new file mode 100644
> index 0000000..bcb9967
> --- /dev/null
> +++ b/include/trace/events/target.h
> @@ -0,0 +1,215 @@
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM target
> +
> +#if !defined(_TRACE_TARGET_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_TARGET_H
> +
> +#include <linux/tracepoint.h>
> +#include <linux/trace_seq.h>
> +#include <scsi/scsi.h>
> +#include <scsi/scsi_tcq.h>
> +#include <target/target_core_base.h>
> +
> +/* cribbed verbatim from <trace/event/scsi.h> */
> +#define scsi_opcode_name(opcode)	{ opcode, #opcode }
> +#define show_opcode_name(val)					\
> +	__print_symbolic(val,					\
> +		scsi_opcode_name(TEST_UNIT_READY),		\
> +		scsi_opcode_name(REZERO_UNIT),			\
> +		scsi_opcode_name(REQUEST_SENSE),		\
> +		scsi_opcode_name(FORMAT_UNIT),			\
> +		scsi_opcode_name(READ_BLOCK_LIMITS),		\
> +		scsi_opcode_name(REASSIGN_BLOCKS),		\
> +		scsi_opcode_name(INITIALIZE_ELEMENT_STATUS),	\
> +		scsi_opcode_name(READ_6),			\
> +		scsi_opcode_name(WRITE_6),			\
> +		scsi_opcode_name(SEEK_6),			\
> +		scsi_opcode_name(READ_REVERSE),			\
> +		scsi_opcode_name(WRITE_FILEMARKS),		\
> +		scsi_opcode_name(SPACE),			\
> +		scsi_opcode_name(INQUIRY),			\
> +		scsi_opcode_name(RECOVER_BUFFERED_DATA),	\
> +		scsi_opcode_name(MODE_SELECT),			\
> +		scsi_opcode_name(RESERVE),			\
> +		scsi_opcode_name(RELEASE),			\
> +		scsi_opcode_name(COPY),				\
> +		scsi_opcode_name(ERASE),			\
> +		scsi_opcode_name(MODE_SENSE),			\
> +		scsi_opcode_name(START_STOP),			\
> +		scsi_opcode_name(RECEIVE_DIAGNOSTIC),		\
> +		scsi_opcode_name(SEND_DIAGNOSTIC),		\
> +		scsi_opcode_name(ALLOW_MEDIUM_REMOVAL),		\
> +		scsi_opcode_name(SET_WINDOW),			\
> +		scsi_opcode_name(READ_CAPACITY),		\
> +		scsi_opcode_name(READ_10),			\
> +		scsi_opcode_name(WRITE_10),			\
> +		scsi_opcode_name(SEEK_10),			\
> +		scsi_opcode_name(POSITION_TO_ELEMENT),		\
> +		scsi_opcode_name(WRITE_VERIFY),			\
> +		scsi_opcode_name(VERIFY),			\
> +		scsi_opcode_name(SEARCH_HIGH),			\
> +		scsi_opcode_name(SEARCH_EQUAL),			\
> +		scsi_opcode_name(SEARCH_LOW),			\
> +		scsi_opcode_name(SET_LIMITS),			\
> +		scsi_opcode_name(PRE_FETCH),			\
> +		scsi_opcode_name(READ_POSITION),		\
> +		scsi_opcode_name(SYNCHRONIZE_CACHE),		\
> +		scsi_opcode_name(LOCK_UNLOCK_CACHE),		\
> +		scsi_opcode_name(READ_DEFECT_DATA),		\
> +		scsi_opcode_name(MEDIUM_SCAN),			\
> +		scsi_opcode_name(COMPARE),			\
> +		scsi_opcode_name(COPY_VERIFY),			\
> +		scsi_opcode_name(WRITE_BUFFER),			\
> +		scsi_opcode_name(READ_BUFFER),			\
> +		scsi_opcode_name(UPDATE_BLOCK),			\
> +		scsi_opcode_name(READ_LONG),			\
> +		scsi_opcode_name(WRITE_LONG),			\
> +		scsi_opcode_name(CHANGE_DEFINITION),		\
> +		scsi_opcode_name(WRITE_SAME),			\
> +		scsi_opcode_name(UNMAP),			\
> +		scsi_opcode_name(READ_TOC),			\
> +		scsi_opcode_name(LOG_SELECT),			\
> +		scsi_opcode_name(LOG_SENSE),			\
> +		scsi_opcode_name(XDWRITEREAD_10),		\
> +		scsi_opcode_name(MODE_SELECT_10),		\
> +		scsi_opcode_name(RESERVE_10),			\
> +		scsi_opcode_name(RELEASE_10),			\
> +		scsi_opcode_name(MODE_SENSE_10),		\
> +		scsi_opcode_name(PERSISTENT_RESERVE_IN),	\
> +		scsi_opcode_name(PERSISTENT_RESERVE_OUT),	\
> +		scsi_opcode_name(VARIABLE_LENGTH_CMD),		\
> +		scsi_opcode_name(COMPARE_AND_WRITE),		\
> +		scsi_opcode_name(REPORT_LUNS),			\
> +		scsi_opcode_name(MAINTENANCE_IN),		\
> +		scsi_opcode_name(MAINTENANCE_OUT),		\
> +		scsi_opcode_name(MOVE_MEDIUM),			\
> +		scsi_opcode_name(EXCHANGE_MEDIUM),		\
> +		scsi_opcode_name(READ_12),			\
> +		scsi_opcode_name(WRITE_12),			\
> +		scsi_opcode_name(WRITE_VERIFY_12),		\
> +		scsi_opcode_name(SEARCH_HIGH_12),		\
> +		scsi_opcode_name(SEARCH_EQUAL_12),		\
> +		scsi_opcode_name(SEARCH_LOW_12),		\
> +		scsi_opcode_name(READ_ELEMENT_STATUS),		\
> +		scsi_opcode_name(SEND_VOLUME_TAG),		\
> +		scsi_opcode_name(WRITE_LONG_2),			\
> +		scsi_opcode_name(READ_16),			\
> +		scsi_opcode_name(WRITE_16),			\
> +		scsi_opcode_name(VERIFY_16),			\
> +		scsi_opcode_name(WRITE_SAME_16),		\
> +		scsi_opcode_name(SERVICE_ACTION_IN),		\
> +		scsi_opcode_name(SAI_READ_CAPACITY_16),		\
> +		scsi_opcode_name(SAI_GET_LBA_STATUS),		\
> +		scsi_opcode_name(MI_REPORT_TARGET_PGS),		\
> +		scsi_opcode_name(MO_SET_TARGET_PGS),		\
> +		scsi_opcode_name(READ_32),			\
> +		scsi_opcode_name(WRITE_32),			\
> +		scsi_opcode_name(WRITE_SAME_32),		\
> +		scsi_opcode_name(ATA_16),			\
> +		scsi_opcode_name(ATA_12))
> +
> +#define show_task_attribute_name(val)				\
> +	__print_symbolic(val,					\
> +		{ MSG_SIMPLE_TAG,	"SIMPLE"	},	\
> +		{ MSG_HEAD_TAG,		"HEAD"		},	\
> +		{ MSG_ORDERED_TAG,	"ORDERED"	},	\
> +		{ MSG_ACA_TAG,		"ACA"		} )
> +
> +#define show_scsi_status_name(val)				\
> +	__print_symbolic(val,					\
> +		{ SAM_STAT_GOOD,	"GOOD" },		\
> +		{ SAM_STAT_CHECK_CONDITION, "CHECK CONDITION" }, \
> +		{ SAM_STAT_CONDITION_MET, "CONDITION MET" },	\
> +		{ SAM_STAT_BUSY,	"BUSY" },		\
> +		{ SAM_STAT_INTERMEDIATE, "INTERMEDIATE" },	\
> +		{ SAM_STAT_INTERMEDIATE_CONDITION_MET, "INTERMEDIATE CONDITION MET" }, \
> +		{ SAM_STAT_RESERVATION_CONFLICT, "RESERVATION CONFLICT" }, \
> +		{ SAM_STAT_COMMAND_TERMINATED, "COMMAND TERMINATED" }, \
> +		{ SAM_STAT_TASK_SET_FULL, "TASK SET FULL" },	\
> +		{ SAM_STAT_ACA_ACTIVE, "ACA ACTIVE" },		\
> +		{ SAM_STAT_TASK_ABORTED, "TASK ABORTED" } )
> +
> +TRACE_EVENT(target_sequencer_start,
> +
> +	TP_PROTO(struct se_cmd *cmd),
> +
> +	TP_ARGS(cmd),
> +
> +	TP_STRUCT__entry(
> +		__field( unsigned int,	unpacked_lun	)
> +		__field( unsigned int,	opcode		)
> +		__field( unsigned int,	data_length	)
> +		__field( unsigned int,	task_attribute  )
> +		__array( unsigned char,	cdb, TCM_MAX_COMMAND_SIZE	)
> +		__string( initiator,	cmd->se_sess->se_node_acl->initiatorname	)
> +	),
> +
> +	TP_fast_assign(
> +		__entry->unpacked_lun	= cmd->se_lun->unpacked_lun;
> +		__entry->opcode		= cmd->t_task_cdb[0];
> +		__entry->data_length	= cmd->data_length;
> +		__entry->task_attribute	= cmd->sam_task_attr;
> +		memcpy(__entry->cdb, cmd->t_task_cdb, TCM_MAX_COMMAND_SIZE);
> +		__assign_str(initiator, cmd->se_sess->se_node_acl->initiatorname);
> +	),
> +
> +	TP_printk("%s -> LUN %03u %s data_length %6u  CDB %s  (TA:%s C:%02x)",
> +		  __get_str(initiator), __entry->unpacked_lun,
> +		  show_opcode_name(__entry->opcode),
> +		  __entry->data_length, __print_hex(__entry->cdb, 16),
> +		  show_task_attribute_name(__entry->task_attribute),
> +		  scsi_command_size(__entry->cdb) <= 16 ?
> +			__entry->cdb[scsi_command_size(__entry->cdb) - 1] :
> +			__entry->cdb[1]
> +	)
> +);
> +
> +TRACE_EVENT(target_cmd_complete,
> +
> +	TP_PROTO(struct se_cmd *cmd),
> +
> +	TP_ARGS(cmd),
> +
> +	TP_STRUCT__entry(
> +		__field( unsigned int,	unpacked_lun	)
> +		__field( unsigned int,	opcode		)
> +		__field( unsigned int,	data_length	)
> +		__field( unsigned int,	task_attribute  )
> +		__field( unsigned char,	scsi_status	)
> +		__field( unsigned char,	sense_length	)
> +		__array( unsigned char,	cdb, TCM_MAX_COMMAND_SIZE	)
> +		__array( unsigned char,	sense_data, 18	)
> +		__string(initiator,	cmd->se_sess->se_node_acl->initiatorname)
> +	),
> +
> +	TP_fast_assign(
> +		__entry->unpacked_lun	= cmd->se_lun->unpacked_lun;
> +		__entry->opcode		= cmd->t_task_cdb[0];
> +		__entry->data_length	= cmd->data_length;
> +		__entry->task_attribute	= cmd->sam_task_attr;
> +		__entry->scsi_status	= cmd->scsi_status;
> +		__entry->sense_length	= cmd->scsi_status == SAM_STAT_CHECK_CONDITION ?
> +			min(18, ((u8 *) cmd->sense_buffer)[SPC_ADD_SENSE_LEN_OFFSET] + 8) : 0;
> +		memcpy(__entry->cdb, cmd->t_task_cdb, TCM_MAX_COMMAND_SIZE);
> +		memcpy(__entry->sense_data, cmd->sense_buffer, __entry->sense_length);
> +		__assign_str(initiator, cmd->se_sess->se_node_acl->initiatorname);
> +	),
> +
> +	TP_printk("%s <- LUN %03u status %s (sense len %d%s%s)  %s data_length %6u  CDB %s  (TA:%s C:%02x)",
> +		  __get_str(initiator), __entry->unpacked_lun,
> +		  show_scsi_status_name(__entry->scsi_status),
> +		  __entry->sense_length, __entry->sense_length ? " / " : "",
> +		  __print_hex(__entry->sense_data, __entry->sense_length),
> +		  show_opcode_name(__entry->opcode),
> +		  __entry->data_length, __print_hex(__entry->cdb, 16),
> +		  show_task_attribute_name(__entry->task_attribute),
> +		  scsi_command_size(__entry->cdb) <= 16 ?
> +			__entry->cdb[scsi_command_size(__entry->cdb) - 1] :
> +			__entry->cdb[1]
> +	)
> +);
> +
> +#endif /*  _TRACE_TARGET_H */
> +
> +/* This part must be outside protection */
> +#include <trace/define_trace.h>


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




[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux