mirror of
https://github.com/SCST-project/scst.git
synced 2026-07-27 10:32:49 +00:00
Merge branch 'svn-trunk'
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
#include <linux/version.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
@@ -125,7 +125,6 @@ function make_dpkg {
|
||||
|
||||
function compile_scst {
|
||||
(
|
||||
export KCFLAGS=-DCONFIG_SCST_MEASURE_LATENCY
|
||||
for p in scst scst_local iscsi-scst srpt qla2x00t $(if [ "${mpt_scst}" = "true" ]; then echo mpt; fi); do
|
||||
if [ "${p%qla2x00t}" != "$p" ]; then
|
||||
BUILD_2X_MODULE=y CONFIG_SCSI_QLA_FC=y CONFIG_SCSI_QLA2XXX_TARGET=y \
|
||||
|
||||
+1
-9
@@ -343,11 +343,6 @@ in/out in Makefile and scst.h:
|
||||
Then sometimes get crazy itself. So, this option is disabled by
|
||||
default.
|
||||
|
||||
- CONFIG_SCST_MEASURE_LATENCY - if defined, provides in "latency" files
|
||||
global and per-LUN average commands processing latency statistic. You
|
||||
can clear already measured results by writing 0 in each file. Note,
|
||||
you need a non-preemptible kernel to have correct results.
|
||||
|
||||
- CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS - if defined, allows injection
|
||||
of corrupted DIF tags according to the Oracle specification. This
|
||||
functionality is working only if dif_mode doesn't contain dev_store
|
||||
@@ -844,9 +839,6 @@ following entries:
|
||||
- unknown_cmd_count - number of unknown SCSI commands received since
|
||||
beginning or last reset (writing 0 in this attribute)
|
||||
|
||||
- latency - if CONFIG_SCST_MEASURE_LATENCY enabled, contains latency
|
||||
statistics for this session.
|
||||
|
||||
- *count*, e.g. read_io_count_kb, - statistics about executed
|
||||
commands and transferred data. See above for more details.
|
||||
|
||||
@@ -2509,7 +2501,7 @@ In order to get the maximum performance you should:
|
||||
|
||||
- Disable in Makefile and scst.h CONFIG_SCST_STRICT_SERIALIZING,
|
||||
CONFIG_SCST_EXTRACHECKS, CONFIG_SCST_TRACING, CONFIG_SCST_DEBUG*,
|
||||
CONFIG_SCST_STRICT_SECURITY, CONFIG_SCST_MEASURE_LATENCY
|
||||
CONFIG_SCST_STRICT_SECURITY.
|
||||
|
||||
2. For target drivers:
|
||||
|
||||
|
||||
+1
-10
@@ -233,11 +233,6 @@ your favorite kernel configuration Makefile target, e.g. "make xconfig":
|
||||
Then sometimes get crazy itself. So, this option is disabled by
|
||||
default.
|
||||
|
||||
- CONFIG_SCST_MEASURE_LATENCY - if defined, provides in "latency" files
|
||||
global and per-LUN average commands processing latency statistic. You
|
||||
can clear already measured results by writing 0 in each file. Note,
|
||||
you need a non-preemptible kernel to have correct results.
|
||||
|
||||
- CONFIG_SCST_DIF_INJECT_CORRUPTED_TAGS - if defined, allows injection
|
||||
of corrupted DIF tags according to the Oracle specification. This
|
||||
functionality is working only if dif_mode doesn't contain dev_store
|
||||
@@ -708,9 +703,6 @@ following entries:
|
||||
- unknown_cmd_count - number of unknown SCSI commands received since
|
||||
beginning or last reset (writing 0 in this attribute)
|
||||
|
||||
- latency - if CONFIG_SCST_MEASURE_LATENCY enabled, contains latency
|
||||
statistics for this session.
|
||||
|
||||
- *count*, e.g. read_io_count_kb, - statistics about executed
|
||||
commands and transferred data. See above for more details.
|
||||
|
||||
@@ -2342,8 +2334,7 @@ In order to get the maximum performance you should:
|
||||
1. For SCST:
|
||||
|
||||
- Disable CONFIG_SCST_STRICT_SERIALIZING, CONFIG_SCST_EXTRACHECKS,
|
||||
CONFIG_SCST_TRACING, CONFIG_SCST_DEBUG*, CONFIG_SCST_STRICT_SECURITY,
|
||||
CONFIG_SCST_MEASURE_LATENCY
|
||||
CONFIG_SCST_TRACING, CONFIG_SCST_DEBUG*, CONFIG_SCST_STRICT_SECURITY.
|
||||
|
||||
2. For target drivers:
|
||||
|
||||
|
||||
+4
-83
@@ -23,7 +23,6 @@
|
||||
#define __SCST_H
|
||||
|
||||
/** See README for description of those conditional defines **/
|
||||
/* #define CONFIG_SCST_MEASURE_LATENCY */
|
||||
/* #define CONFIG_SCST_DEBUG_TM */
|
||||
/* #define CONFIG_SCST_TM_DBG_GO_OFFLINE */
|
||||
|
||||
@@ -41,9 +40,6 @@
|
||||
#include <linux/wait.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/dlm.h>
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
#include <linux/log2.h>
|
||||
#endif
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#if 0 /* Let's disable it for now to see if users will complain about it */
|
||||
@@ -114,7 +110,7 @@
|
||||
** !! Adding new states don't forget to update scst_cmd_state_name
|
||||
** !! as well!
|
||||
*************************************************************/
|
||||
enum {
|
||||
enum scst_cmd_state {
|
||||
/** Active states **/
|
||||
|
||||
/* Dev handler's parse() is going to be called */
|
||||
@@ -165,7 +161,8 @@ enum {
|
||||
/* Internal cmd finished */
|
||||
SCST_CMD_STATE_FINISHED_INTERNAL,
|
||||
|
||||
SCST_CMD_STATE_LAST_ACTIVE = (SCST_CMD_STATE_FINISHED_INTERNAL+100),
|
||||
/* An invalid command state */
|
||||
SCST_CMD_STATE_LAST_ACTIVE,
|
||||
|
||||
/** Passive states **/
|
||||
|
||||
@@ -1847,51 +1844,6 @@ struct scst_tgt {
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
|
||||
/* Divide two 64-bit numbers with reasonably accuracy. */
|
||||
static inline void __scst_time_per_cmd(uint64_t *t, uint64_t n)
|
||||
{
|
||||
unsigned int shift;
|
||||
|
||||
if (!n)
|
||||
return;
|
||||
shift = max(0, ilog2(n) - 32 + 1);
|
||||
*t >>= shift;
|
||||
n >>= shift;
|
||||
WARN_ON(n != (uint32_t)n);
|
||||
do_div(*t, (uint32_t)n);
|
||||
}
|
||||
|
||||
#define scst_time_per_cmd(t, n) __scst_time_per_cmd(&(t), (n))
|
||||
|
||||
/* Defines extended latency statistics */
|
||||
struct scst_ext_latency_stat {
|
||||
uint64_t scst_time_rd, tgt_time_rd, dev_time_rd;
|
||||
uint64_t processed_cmds_rd;
|
||||
uint64_t min_scst_time_rd, min_tgt_time_rd, min_dev_time_rd;
|
||||
uint64_t max_scst_time_rd, max_tgt_time_rd, max_dev_time_rd;
|
||||
|
||||
uint64_t scst_time_wr, tgt_time_wr, dev_time_wr;
|
||||
uint64_t processed_cmds_wr;
|
||||
uint64_t min_scst_time_wr, min_tgt_time_wr, min_dev_time_wr;
|
||||
uint64_t max_scst_time_wr, max_tgt_time_wr, max_dev_time_wr;
|
||||
};
|
||||
|
||||
#define SCST_IO_SIZE_THRESHOLD_SMALL (8*1024)
|
||||
#define SCST_IO_SIZE_THRESHOLD_MEDIUM (32*1024)
|
||||
#define SCST_IO_SIZE_THRESHOLD_LARGE (128*1024)
|
||||
#define SCST_IO_SIZE_THRESHOLD_VERY_LARGE (512*1024)
|
||||
|
||||
#define SCST_LATENCY_STAT_INDEX_SMALL 0
|
||||
#define SCST_LATENCY_STAT_INDEX_MEDIUM 1
|
||||
#define SCST_LATENCY_STAT_INDEX_LARGE 2
|
||||
#define SCST_LATENCY_STAT_INDEX_VERY_LARGE 3
|
||||
#define SCST_LATENCY_STAT_INDEX_OTHER 4
|
||||
#define SCST_LATENCY_STATS_NUM (SCST_LATENCY_STAT_INDEX_OTHER + 1)
|
||||
|
||||
#endif /* CONFIG_SCST_MEASURE_LATENCY */
|
||||
|
||||
struct scst_io_stat_entry {
|
||||
uint64_t cmd_count;
|
||||
uint64_t io_byte_count;
|
||||
@@ -2033,15 +1985,6 @@ struct scst_session {
|
||||
void (*init_result_fn)(struct scst_session *sess, void *data,
|
||||
int result);
|
||||
void (*unreg_done_fn)(struct scst_session *sess);
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
spinlock_t lat_lock;
|
||||
uint64_t scst_time, tgt_time, dev_time;
|
||||
uint64_t processed_cmds;
|
||||
uint64_t min_scst_time, min_tgt_time, min_dev_time;
|
||||
uint64_t max_scst_time, max_tgt_time, max_dev_time;
|
||||
struct scst_ext_latency_stat sess_latency_stat[SCST_LATENCY_STATS_NUM];
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -2176,7 +2119,7 @@ struct scst_cmd {
|
||||
atomic_t *cpu_cmd_counter;
|
||||
|
||||
/* Cmd state, one of SCST_CMD_STATE_* constants */
|
||||
int state;
|
||||
enum scst_cmd_state state;
|
||||
|
||||
/*************************************************************
|
||||
** Cmd's flags
|
||||
@@ -2595,16 +2538,6 @@ struct scst_cmd {
|
||||
char not_parsed_op_name[8];
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
uint64_t start, curr_start, parse_time;
|
||||
uint64_t tgt_alloc_buf_time, dev_alloc_buf_time;
|
||||
uint64_t restart_waiting_time, rdy_to_xfer_time;
|
||||
uint64_t pre_exec_time;
|
||||
bool exec_time_counting;
|
||||
uint64_t exec_time, dev_done_time;
|
||||
uint64_t xmit_time;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCST_DEBUG_TM
|
||||
/* Set if the cmd was delayed by task management debugging code */
|
||||
unsigned int tm_dbg_delayed:1;
|
||||
@@ -3262,15 +3195,6 @@ struct scst_tgt_dev {
|
||||
|
||||
struct kobject tgt_dev_kobj; /* sessions' LUNs sysfs entry */
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
/*
|
||||
* Protected by sess->lat_lock.
|
||||
*/
|
||||
uint64_t scst_time, tgt_time, dev_time;
|
||||
uint64_t processed_cmds;
|
||||
struct scst_ext_latency_stat dev_latency_stat[SCST_LATENCY_STATS_NUM];
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -5265,9 +5189,6 @@ void scst_resume_activity(void);
|
||||
|
||||
void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic);
|
||||
|
||||
void scst_post_parse(struct scst_cmd *cmd);
|
||||
void scst_post_dev_alloc_data_buf(struct scst_cmd *cmd);
|
||||
|
||||
int __scst_check_local_events(struct scst_cmd *cmd, bool preempt_tests_only);
|
||||
|
||||
/**
|
||||
|
||||
@@ -236,18 +236,6 @@ config SCST_TM_DBG_GO_OFFLINE
|
||||
completely unresponsive. When disabled, the device will receive
|
||||
ABORT and RESET commands.
|
||||
|
||||
config SCST_MEASURE_LATENCY
|
||||
bool "Commands processing latency measurement facility"
|
||||
depends on SCST
|
||||
help
|
||||
This option enables commands processing latency measurement
|
||||
facility in SCST. It will provide in the sysfs interface
|
||||
average commands processing latency statistics. You can clear
|
||||
already measured results by writing 0 in the corresponding sysfs file.
|
||||
Note, you need a non-preemtible kernel to have correct results.
|
||||
|
||||
If unsure, say "N".
|
||||
|
||||
source "drivers/scst/fcst/Kconfig"
|
||||
source "drivers/scst/iscsi-scst/Kconfig"
|
||||
source "drivers/scst/scst_local/Kconfig"
|
||||
|
||||
@@ -1352,7 +1352,6 @@ static int dev_user_process_reply_alloc(struct scst_user_cmd *ucmd,
|
||||
}
|
||||
|
||||
out_process:
|
||||
scst_post_dev_alloc_data_buf(cmd);
|
||||
scst_process_active_cmd(cmd, false);
|
||||
|
||||
TRACE_DBG("%s", "ALLOC_MEM finished");
|
||||
@@ -1419,7 +1418,6 @@ static int dev_user_process_reply_parse(struct scst_user_cmd *ucmd,
|
||||
cmd->op_flags = preply->op_flags;
|
||||
|
||||
out_process:
|
||||
scst_post_parse(cmd);
|
||||
TRACE_DBG("%s", "PARSE finished");
|
||||
|
||||
scst_process_active_cmd(cmd, false);
|
||||
@@ -2668,11 +2666,6 @@ static void dev_user_unjam_cmd(struct scst_user_cmd *ucmd, int busy,
|
||||
}
|
||||
scst_set_cmd_abnormal_done_state(ucmd->cmd);
|
||||
|
||||
if (state == UCMD_STATE_PARSING)
|
||||
scst_post_parse(ucmd->cmd);
|
||||
else
|
||||
scst_post_dev_alloc_data_buf(ucmd->cmd);
|
||||
|
||||
TRACE_MGMT_DBG("Adding ucmd %p to active list", ucmd);
|
||||
list_add(&ucmd->cmd->cmd_list_entry,
|
||||
&ucmd->cmd->cmd_threads->active_cmd_list);
|
||||
|
||||
@@ -1444,8 +1444,6 @@ void scst_ext_copy_remap_done(struct scst_cmd *ec_cmd,
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
scst_set_exec_time(ec_cmd);
|
||||
|
||||
if (dds == NULL)
|
||||
scst_cm_ec_sched_next_seg(ec_cmd);
|
||||
else
|
||||
@@ -1549,7 +1547,6 @@ static int scst_cm_try_to_remap(struct scst_cmd *ec_cmd)
|
||||
TRACE_DBG("Calling ext_copy_remap() for dev %s (ec_cmd %p)",
|
||||
sd->dst_tgt_dev->dev->virt_name, ec_cmd);
|
||||
|
||||
scst_set_exec_start(ec_cmd);
|
||||
handler->ext_copy_remap(ec_cmd, sd);
|
||||
|
||||
out:
|
||||
|
||||
+15
-309
@@ -3190,10 +3190,12 @@ void scst_set_cmd_abnormal_done_state(struct scst_cmd *cmd)
|
||||
PRINT_CRIT_ERROR("Wrong cmd state %d (cmd %p, op %s)",
|
||||
cmd->state, cmd, scst_get_opcode_name(cmd));
|
||||
sBUG();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
cmd->state = scst_get_cmd_abnormal_done_state(cmd);
|
||||
scst_set_cmd_state(cmd, scst_get_cmd_abnormal_done_state(cmd));
|
||||
|
||||
switch (cmd->state) {
|
||||
case SCST_CMD_STATE_INIT_WAIT:
|
||||
@@ -5795,15 +5797,13 @@ struct scst_cmd *__scst_create_prepare_internal_cmd(const uint8_t *cdb,
|
||||
if (res->tgt_dev != NULL)
|
||||
res->cpu_cmd_counter = scst_get();
|
||||
|
||||
scst_set_start_time(res);
|
||||
|
||||
TRACE(TRACE_SCSI, "New internal cmd %p (op %s)", res,
|
||||
scst_get_opcode_name(res));
|
||||
|
||||
rc = scst_pre_parse(res);
|
||||
sBUG_ON(rc != 0);
|
||||
|
||||
res->state = SCST_CMD_STATE_PARSE;
|
||||
scst_set_cmd_state(res, SCST_CMD_STATE_PARSE);
|
||||
|
||||
out:
|
||||
TRACE_EXIT_HRES((unsigned long)res);
|
||||
@@ -6498,8 +6498,6 @@ void scst_write_same(struct scst_cmd *cmd, struct scst_data_descriptor *where)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
scst_set_exec_time(cmd);
|
||||
|
||||
if (unlikely(cmd->data_len <= 0)) {
|
||||
scst_set_invalid_field_in_cdb(cmd, cmd->len_off, 0);
|
||||
goto out_done;
|
||||
@@ -7071,10 +7069,6 @@ struct scst_session *scst_alloc_session(struct scst_tgt *tgt, gfp_t gfp_mask,
|
||||
INIT_WORK(&sess->hw_pending_work, scst_hw_pending_work_fn, sess);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
spin_lock_init(&sess->lat_lock);
|
||||
#endif
|
||||
|
||||
sess->initiator_name = kstrdup(initiator_name, gfp_mask);
|
||||
if (sess->initiator_name == NULL) {
|
||||
PRINT_ERROR("%s", "Unable to dup sess->initiator_name");
|
||||
@@ -7276,7 +7270,7 @@ int scst_pre_init_cmd(struct scst_cmd *cmd, const uint8_t *cdb,
|
||||
}
|
||||
#endif
|
||||
|
||||
cmd->state = SCST_CMD_STATE_INIT_WAIT;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_INIT_WAIT);
|
||||
cmd->start_time = jiffies;
|
||||
atomic_set(&cmd->cmd_ref, 1);
|
||||
cmd->cmd_threads = &scst_main_cmd_threads;
|
||||
@@ -8029,9 +8023,13 @@ static struct request *blk_make_request(struct request_queue *q,
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
|
||||
rq = blk_get_request(q, bio_data_dir(bio), gfp_mask);
|
||||
#else
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
|
||||
rq = blk_get_request(q, bio_data_dir(bio) == READ ? REQ_OP_SCSI_IN :
|
||||
REQ_OP_SCSI_OUT, gfp_mask);
|
||||
#else
|
||||
WARN_ON_ONCE(gfp_mask != GFP_KERNEL);
|
||||
rq = blk_get_request(q, bio_data_dir(bio) == READ ? REQ_OP_SCSI_IN :
|
||||
REQ_OP_SCSI_OUT, 0);
|
||||
#endif
|
||||
|
||||
if (IS_ERR(rq))
|
||||
@@ -8273,9 +8271,13 @@ static struct request *blk_map_kern_sg(struct request_queue *q,
|
||||
if (!sgl) {
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
|
||||
rq = blk_get_request(q, reading ? READ : WRITE, gfp);
|
||||
#else
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0)
|
||||
rq = blk_get_request(q, reading ? REQ_OP_SCSI_IN :
|
||||
REQ_OP_SCSI_OUT, gfp);
|
||||
#else
|
||||
WARN_ON_ONCE(gfp != GFP_KERNEL);
|
||||
rq = blk_get_request(q, reading ? REQ_OP_SCSI_IN :
|
||||
REQ_OP_SCSI_OUT, 0);
|
||||
#endif
|
||||
if (unlikely(!rq))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
@@ -15778,299 +15780,3 @@ void scst_check_debug_sn(struct scst_cmd *cmd)
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_SCST_DEBUG_SN */
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
|
||||
|
||||
static uint64_t scst_get_usec(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
ktime_get_ts(&ts);
|
||||
return ((uint64_t)ts.tv_sec * 1000000000 + ts.tv_nsec) / 1000;
|
||||
}
|
||||
|
||||
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) */
|
||||
|
||||
static uint64_t scst_get_usec(void)
|
||||
{
|
||||
ktime_t t;
|
||||
|
||||
t = ktime_get();
|
||||
return ktime_to_us(t);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void scst_set_start_time(struct scst_cmd *cmd)
|
||||
{
|
||||
cmd->start = scst_get_usec();
|
||||
TRACE_DBG("cmd %p: start %lld", cmd, cmd->start);
|
||||
}
|
||||
|
||||
void scst_set_cur_start(struct scst_cmd *cmd)
|
||||
{
|
||||
cmd->curr_start = scst_get_usec();
|
||||
TRACE_DBG("cmd %p: cur_start %lld", cmd, cmd->curr_start);
|
||||
}
|
||||
|
||||
void scst_set_parse_time(struct scst_cmd *cmd)
|
||||
{
|
||||
cmd->parse_time += scst_get_usec() - cmd->curr_start;
|
||||
TRACE_DBG("cmd %p: parse_time %lld", cmd, cmd->parse_time);
|
||||
}
|
||||
|
||||
void scst_set_dev_alloc_buf_time(struct scst_cmd *cmd)
|
||||
{
|
||||
cmd->dev_alloc_buf_time += scst_get_usec() - cmd->curr_start;
|
||||
TRACE_DBG("cmd %p: dev_alloc_buf_time %lld", cmd, cmd->dev_alloc_buf_time);
|
||||
}
|
||||
|
||||
void scst_set_tgt_alloc_buf_time(struct scst_cmd *cmd)
|
||||
{
|
||||
cmd->tgt_alloc_buf_time += scst_get_usec() - cmd->curr_start;
|
||||
TRACE_DBG("cmd %p: tgt_alloc_buf_time %lld", cmd, cmd->tgt_alloc_buf_time);
|
||||
}
|
||||
|
||||
void scst_set_restart_waiting_time(struct scst_cmd *cmd)
|
||||
{
|
||||
cmd->restart_waiting_time += scst_get_usec() - cmd->curr_start;
|
||||
TRACE_DBG("cmd %p: restart_waiting_time %lld", cmd,
|
||||
cmd->restart_waiting_time);
|
||||
}
|
||||
|
||||
void scst_set_rdy_to_xfer_time(struct scst_cmd *cmd)
|
||||
{
|
||||
cmd->rdy_to_xfer_time += scst_get_usec() - cmd->curr_start;
|
||||
TRACE_DBG("cmd %p: rdy_to_xfer_time %lld", cmd, cmd->rdy_to_xfer_time);
|
||||
}
|
||||
|
||||
void scst_set_pre_exec_time(struct scst_cmd *cmd)
|
||||
{
|
||||
cmd->pre_exec_time += scst_get_usec() - cmd->curr_start;
|
||||
TRACE_DBG("cmd %p: pre_exec_time %lld", cmd, cmd->pre_exec_time);
|
||||
}
|
||||
|
||||
void scst_set_exec_start(struct scst_cmd *cmd)
|
||||
{
|
||||
cmd->exec_time_counting = true;
|
||||
scst_set_cur_start(cmd);
|
||||
}
|
||||
|
||||
void scst_set_exec_time(struct scst_cmd *cmd)
|
||||
{
|
||||
if (!cmd->exec_time_counting)
|
||||
return;
|
||||
cmd->exec_time_counting = false;
|
||||
cmd->exec_time += scst_get_usec() - cmd->curr_start;
|
||||
TRACE_DBG("cmd %p: exec_time %lld", cmd, cmd->exec_time);
|
||||
}
|
||||
|
||||
void scst_set_dev_done_time(struct scst_cmd *cmd)
|
||||
{
|
||||
cmd->dev_done_time += scst_get_usec() - cmd->curr_start;
|
||||
TRACE_DBG("cmd %p: dev_done_time %lld", cmd, cmd->dev_done_time);
|
||||
}
|
||||
|
||||
void scst_set_xmit_time(struct scst_cmd *cmd)
|
||||
{
|
||||
cmd->xmit_time += scst_get_usec() - cmd->curr_start;
|
||||
TRACE_DBG("cmd %p: xmit_time %lld", cmd, cmd->xmit_time);
|
||||
}
|
||||
|
||||
void scst_update_lat_stats(struct scst_cmd *cmd)
|
||||
{
|
||||
int64_t finish, scst_time, tgt_time, dev_time;
|
||||
struct scst_session *sess = cmd->sess;
|
||||
int data_len;
|
||||
int i;
|
||||
struct scst_ext_latency_stat *latency_stat, *dev_latency_stat;
|
||||
bool ignore_max = false;
|
||||
|
||||
finish = scst_get_usec();
|
||||
|
||||
/* Determine the IO size for extended latency statistics */
|
||||
data_len = cmd->bufflen;
|
||||
i = SCST_LATENCY_STAT_INDEX_OTHER;
|
||||
if (data_len <= SCST_IO_SIZE_THRESHOLD_SMALL)
|
||||
i = SCST_LATENCY_STAT_INDEX_SMALL;
|
||||
else if (data_len <= SCST_IO_SIZE_THRESHOLD_MEDIUM)
|
||||
i = SCST_LATENCY_STAT_INDEX_MEDIUM;
|
||||
else if (data_len <= SCST_IO_SIZE_THRESHOLD_LARGE)
|
||||
i = SCST_LATENCY_STAT_INDEX_LARGE;
|
||||
else if (data_len <= SCST_IO_SIZE_THRESHOLD_VERY_LARGE)
|
||||
i = SCST_LATENCY_STAT_INDEX_VERY_LARGE;
|
||||
latency_stat = &sess->sess_latency_stat[i];
|
||||
if (cmd->tgt_dev != NULL)
|
||||
dev_latency_stat = &cmd->tgt_dev->dev_latency_stat[i];
|
||||
else
|
||||
dev_latency_stat = NULL;
|
||||
|
||||
/* Calculate the latencies */
|
||||
scst_time = finish - cmd->start - (cmd->parse_time +
|
||||
cmd->dev_alloc_buf_time + cmd->tgt_alloc_buf_time +
|
||||
cmd->restart_waiting_time +
|
||||
cmd->rdy_to_xfer_time + cmd->pre_exec_time +
|
||||
cmd->exec_time + cmd->dev_done_time + cmd->xmit_time);
|
||||
tgt_time = cmd->tgt_alloc_buf_time + cmd->restart_waiting_time +
|
||||
cmd->rdy_to_xfer_time + cmd->pre_exec_time + cmd->xmit_time;
|
||||
dev_time = cmd->parse_time + cmd->dev_alloc_buf_time +
|
||||
cmd->exec_time + cmd->dev_done_time;
|
||||
|
||||
if (unlikely((scst_time < 0) || (tgt_time < 0) || (dev_time < 0))) {
|
||||
/* It might happen due to small difference in time between CPUs */
|
||||
static int q;
|
||||
|
||||
if (q++ < 20) {
|
||||
PRINT_WARNING("Ignoring max latency sample, because time is "
|
||||
"moving backward (cmd %p, scst %lld, tgt %lld, "
|
||||
"dev %lld)", cmd, (long long) scst_time,
|
||||
(long long) tgt_time, (long long) dev_time);
|
||||
}
|
||||
ignore_max = true;
|
||||
/*
|
||||
* We should not ignore this sample, because the time
|
||||
* difference mistake can be both negative and positive.
|
||||
*/
|
||||
}
|
||||
|
||||
spin_lock_bh(&sess->lat_lock);
|
||||
|
||||
/* Save the basic latency information */
|
||||
sess->scst_time += scst_time;
|
||||
sess->tgt_time += tgt_time;
|
||||
sess->dev_time += dev_time;
|
||||
sess->processed_cmds++;
|
||||
|
||||
if ((sess->min_scst_time == 0) ||
|
||||
(sess->min_scst_time > scst_time))
|
||||
sess->min_scst_time = scst_time;
|
||||
if ((sess->min_tgt_time == 0) ||
|
||||
(sess->min_tgt_time > tgt_time))
|
||||
sess->min_tgt_time = tgt_time;
|
||||
if ((sess->min_dev_time == 0) ||
|
||||
(sess->min_dev_time > dev_time))
|
||||
sess->min_dev_time = dev_time;
|
||||
|
||||
if (likely(!ignore_max)) {
|
||||
if (sess->max_scst_time < scst_time)
|
||||
sess->max_scst_time = scst_time;
|
||||
if (sess->max_tgt_time < tgt_time)
|
||||
sess->max_tgt_time = tgt_time;
|
||||
if (sess->max_dev_time < dev_time)
|
||||
sess->max_dev_time = dev_time;
|
||||
}
|
||||
|
||||
/* Save the extended latency information */
|
||||
if (cmd->data_direction & SCST_DATA_READ) {
|
||||
latency_stat->scst_time_rd += scst_time;
|
||||
latency_stat->tgt_time_rd += tgt_time;
|
||||
latency_stat->dev_time_rd += dev_time;
|
||||
latency_stat->processed_cmds_rd++;
|
||||
|
||||
if ((latency_stat->min_scst_time_rd == 0) ||
|
||||
(latency_stat->min_scst_time_rd > scst_time))
|
||||
latency_stat->min_scst_time_rd = scst_time;
|
||||
if ((latency_stat->min_tgt_time_rd == 0) ||
|
||||
(latency_stat->min_tgt_time_rd > tgt_time))
|
||||
latency_stat->min_tgt_time_rd = tgt_time;
|
||||
if ((latency_stat->min_dev_time_rd == 0) ||
|
||||
(latency_stat->min_dev_time_rd > dev_time))
|
||||
latency_stat->min_dev_time_rd = dev_time;
|
||||
|
||||
if (likely(!ignore_max)) {
|
||||
if (latency_stat->max_scst_time_rd < scst_time)
|
||||
latency_stat->max_scst_time_rd = scst_time;
|
||||
if (latency_stat->max_tgt_time_rd < tgt_time)
|
||||
latency_stat->max_tgt_time_rd = tgt_time;
|
||||
if (latency_stat->max_dev_time_rd < dev_time)
|
||||
latency_stat->max_dev_time_rd = dev_time;
|
||||
}
|
||||
|
||||
if (dev_latency_stat != NULL) {
|
||||
dev_latency_stat->scst_time_rd += scst_time;
|
||||
dev_latency_stat->tgt_time_rd += tgt_time;
|
||||
dev_latency_stat->dev_time_rd += dev_time;
|
||||
dev_latency_stat->processed_cmds_rd++;
|
||||
|
||||
if ((dev_latency_stat->min_scst_time_rd == 0) ||
|
||||
(dev_latency_stat->min_scst_time_rd > scst_time))
|
||||
dev_latency_stat->min_scst_time_rd = scst_time;
|
||||
if ((dev_latency_stat->min_tgt_time_rd == 0) ||
|
||||
(dev_latency_stat->min_tgt_time_rd > tgt_time))
|
||||
dev_latency_stat->min_tgt_time_rd = tgt_time;
|
||||
if ((dev_latency_stat->min_dev_time_rd == 0) ||
|
||||
(dev_latency_stat->min_dev_time_rd > dev_time))
|
||||
dev_latency_stat->min_dev_time_rd = dev_time;
|
||||
|
||||
if (likely(!ignore_max)) {
|
||||
if (dev_latency_stat->max_scst_time_rd < scst_time)
|
||||
dev_latency_stat->max_scst_time_rd = scst_time;
|
||||
if (dev_latency_stat->max_tgt_time_rd < tgt_time)
|
||||
dev_latency_stat->max_tgt_time_rd = tgt_time;
|
||||
if (dev_latency_stat->max_dev_time_rd < dev_time)
|
||||
dev_latency_stat->max_dev_time_rd = dev_time;
|
||||
}
|
||||
}
|
||||
} else if (cmd->data_direction & SCST_DATA_WRITE) {
|
||||
latency_stat->scst_time_wr += scst_time;
|
||||
latency_stat->tgt_time_wr += tgt_time;
|
||||
latency_stat->dev_time_wr += dev_time;
|
||||
latency_stat->processed_cmds_wr++;
|
||||
|
||||
if ((latency_stat->min_scst_time_wr == 0) ||
|
||||
(latency_stat->min_scst_time_wr > scst_time))
|
||||
latency_stat->min_scst_time_wr = scst_time;
|
||||
if ((latency_stat->min_tgt_time_wr == 0) ||
|
||||
(latency_stat->min_tgt_time_wr > tgt_time))
|
||||
latency_stat->min_tgt_time_wr = tgt_time;
|
||||
if ((latency_stat->min_dev_time_wr == 0) ||
|
||||
(latency_stat->min_dev_time_wr > dev_time))
|
||||
latency_stat->min_dev_time_wr = dev_time;
|
||||
|
||||
if (likely(!ignore_max)) {
|
||||
if (latency_stat->max_scst_time_wr < scst_time)
|
||||
latency_stat->max_scst_time_wr = scst_time;
|
||||
if (latency_stat->max_tgt_time_wr < tgt_time)
|
||||
latency_stat->max_tgt_time_wr = tgt_time;
|
||||
if (latency_stat->max_dev_time_wr < dev_time)
|
||||
latency_stat->max_dev_time_wr = dev_time;
|
||||
}
|
||||
|
||||
if (dev_latency_stat != NULL) {
|
||||
dev_latency_stat->scst_time_wr += scst_time;
|
||||
dev_latency_stat->tgt_time_wr += tgt_time;
|
||||
dev_latency_stat->dev_time_wr += dev_time;
|
||||
dev_latency_stat->processed_cmds_wr++;
|
||||
|
||||
if ((dev_latency_stat->min_scst_time_wr == 0) ||
|
||||
(dev_latency_stat->min_scst_time_wr > scst_time))
|
||||
dev_latency_stat->min_scst_time_wr = scst_time;
|
||||
if ((dev_latency_stat->min_tgt_time_wr == 0) ||
|
||||
(dev_latency_stat->min_tgt_time_wr > tgt_time))
|
||||
dev_latency_stat->min_tgt_time_wr = tgt_time;
|
||||
if ((dev_latency_stat->min_dev_time_wr == 0) ||
|
||||
(dev_latency_stat->min_dev_time_wr > dev_time))
|
||||
dev_latency_stat->min_dev_time_wr = dev_time;
|
||||
|
||||
if (likely(!ignore_max)) {
|
||||
if (dev_latency_stat->max_scst_time_wr < scst_time)
|
||||
dev_latency_stat->max_scst_time_wr = scst_time;
|
||||
if (dev_latency_stat->max_tgt_time_wr < tgt_time)
|
||||
dev_latency_stat->max_tgt_time_wr = tgt_time;
|
||||
if (dev_latency_stat->max_dev_time_wr < dev_time)
|
||||
dev_latency_stat->max_dev_time_wr = dev_time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_bh(&sess->lat_lock);
|
||||
|
||||
TRACE_DBG("cmd %p: finish %lld, scst_time %lld, "
|
||||
"tgt_time %lld, dev_time %lld", cmd, finish, scst_time,
|
||||
tgt_time, dev_time);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SCST_MEASURE_LATENCY */
|
||||
|
||||
@@ -2590,26 +2590,16 @@ static int __init init_scst(void)
|
||||
goto out_destroy_sense_cache;
|
||||
if (!INIT_CACHEP_ALIGN(scst_cmd_cachep, scst_cmd))
|
||||
goto out_destroy_aen_cache;
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
if (!INIT_CACHEP_ALIGN(scst_sess_cachep, scst_session))
|
||||
goto out_destroy_cmd_cache;
|
||||
#else
|
||||
/* Big enough with read-mostly head and tail */
|
||||
if (!INIT_CACHEP(scst_sess_cachep, scst_session))
|
||||
goto out_destroy_cmd_cache;
|
||||
#endif
|
||||
if (!INIT_CACHEP(scst_dev_cachep, scst_device)) /* big enough */
|
||||
goto out_destroy_sess_cache;
|
||||
if (!INIT_CACHEP(scst_tgt_cachep, scst_tgt)) /* read-mostly */
|
||||
goto out_destroy_dev_cache;
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
if (!INIT_CACHEP_ALIGN(scst_tgtd_cachep, scst_tgt_dev)) /* big enough */
|
||||
goto out_destroy_tgt_cache;
|
||||
#else
|
||||
/* Big enough with read-mostly head and tail */
|
||||
if (!INIT_CACHEP(scst_tgtd_cachep, scst_tgt_dev)) /* big enough */
|
||||
goto out_destroy_tgt_cache;
|
||||
#endif
|
||||
if (!INIT_CACHEP(scst_acgd_cachep, scst_acg_dev)) /* read-mostly */
|
||||
goto out_destroy_tgtd_cache;
|
||||
if (!INIT_CACHEP_ALIGN(scst_thr_cachep, scst_cmd_thread_t))
|
||||
|
||||
+5
-34
@@ -88,6 +88,11 @@ extern unsigned long scst_trace_flag;
|
||||
/* Set if new commands initialization is suspended for a while */
|
||||
#define SCST_FLAG_SUSPENDED 1
|
||||
|
||||
static inline void scst_set_cmd_state(struct scst_cmd *cmd, enum scst_cmd_state new_state)
|
||||
{
|
||||
cmd->state = new_state;
|
||||
}
|
||||
|
||||
/**
|
||||
** Return codes for cmd state process functions. Codes are the same as
|
||||
** for SCST_EXEC_* to avoid translation to them and, hence, have better code.
|
||||
@@ -1029,38 +1034,4 @@ typedef void __printf(2, 3) (*scst_show_fn)(void *arg, const char *fmt, ...);
|
||||
void scst_trace_cmds(scst_show_fn show, void *arg);
|
||||
void scst_trace_mcmds(scst_show_fn show, void *arg);
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
|
||||
void scst_set_start_time(struct scst_cmd *cmd);
|
||||
void scst_set_cur_start(struct scst_cmd *cmd);
|
||||
void scst_set_parse_time(struct scst_cmd *cmd);
|
||||
void scst_set_dev_alloc_buf_time(struct scst_cmd *cmd);
|
||||
void scst_set_tgt_alloc_buf_time(struct scst_cmd *cmd);
|
||||
void scst_set_restart_waiting_time(struct scst_cmd *cmd);
|
||||
void scst_set_rdy_to_xfer_time(struct scst_cmd *cmd);
|
||||
void scst_set_pre_exec_time(struct scst_cmd *cmd);
|
||||
void scst_set_exec_start(struct scst_cmd *cmd);
|
||||
void scst_set_exec_time(struct scst_cmd *cmd);
|
||||
void scst_set_dev_done_time(struct scst_cmd *cmd);
|
||||
void scst_set_xmit_time(struct scst_cmd *cmd);
|
||||
void scst_update_lat_stats(struct scst_cmd *cmd);
|
||||
|
||||
#else
|
||||
|
||||
static inline void scst_set_start_time(struct scst_cmd *cmd) {}
|
||||
static inline void scst_set_cur_start(struct scst_cmd *cmd) {}
|
||||
static inline void scst_set_parse_time(struct scst_cmd *cmd) {}
|
||||
static inline void scst_set_dev_alloc_buf_time(struct scst_cmd *cmd) {}
|
||||
static inline void scst_set_tgt_alloc_buf_time(struct scst_cmd *cmd) {}
|
||||
static inline void scst_set_restart_waiting_time(struct scst_cmd *cmd) {}
|
||||
static inline void scst_set_rdy_to_xfer_time(struct scst_cmd *cmd) {}
|
||||
static inline void scst_set_pre_exec_time(struct scst_cmd *cmd) {}
|
||||
static inline void scst_set_exec_start(struct scst_cmd *cmd) {}
|
||||
static inline void scst_set_exec_time(struct scst_cmd *cmd) {}
|
||||
static inline void scst_set_dev_done_time(struct scst_cmd *cmd) {}
|
||||
static inline void scst_set_xmit_time(struct scst_cmd *cmd) {}
|
||||
static inline void scst_update_lat_stats(struct scst_cmd *cmd) {}
|
||||
|
||||
#endif /* CONFIG_SCST_MEASURE_LATENCY */
|
||||
|
||||
#endif /* __SCST_PRIV_H */
|
||||
|
||||
+1
-357
@@ -90,10 +90,6 @@ static struct scst_proc_data scst_dev_handler_proc_data;
|
||||
#define SCST_PROC_GROUPS_USERS_ENTRY_NAME "names"
|
||||
#define SCST_PROC_GROUPS_ADDR_METHOD_ENTRY_NAME "addr_method"
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
#define SCST_PROC_LAT_ENTRY_NAME "latency"
|
||||
#endif
|
||||
|
||||
#define SCST_PROC_ACTION_ALL 1
|
||||
#define SCST_PROC_ACTION_NONE 2
|
||||
#define SCST_PROC_ACTION_DEFAULT 3
|
||||
@@ -469,344 +465,10 @@ out:
|
||||
|
||||
#endif /* defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) */
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
|
||||
static char *scst_io_size_names[] = {
|
||||
"<=8K ",
|
||||
"<=32K ",
|
||||
"<=128K",
|
||||
"<=512K",
|
||||
">512K "
|
||||
};
|
||||
|
||||
static int lat_info_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
int res = 0;
|
||||
struct scst_acg *acg;
|
||||
struct scst_session *sess;
|
||||
char buf[50];
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
BUILD_BUG_ON(SCST_LATENCY_STATS_NUM != ARRAY_SIZE(scst_io_size_names));
|
||||
BUILD_BUG_ON(SCST_LATENCY_STATS_NUM != ARRAY_SIZE(sess->sess_latency_stat));
|
||||
|
||||
if (mutex_lock_interruptible(&scst_mutex) != 0) {
|
||||
res = -EINTR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
list_for_each_entry(acg, &scst_acg_list, acg_list_entry) {
|
||||
bool header_printed = false;
|
||||
|
||||
list_for_each_entry(sess, &acg->acg_sess_list,
|
||||
acg_sess_list_entry) {
|
||||
unsigned int i;
|
||||
int t;
|
||||
uint64_t scst_time, tgt_time, dev_time;
|
||||
uint64_t processed_cmds;
|
||||
|
||||
if (!header_printed) {
|
||||
seq_printf(seq, "%-15s %-15s %-46s %-46s %-46s\n",
|
||||
"T-L names", "Total commands", "SCST latency",
|
||||
"Target latency", "Dev latency (min/avg/max/all us)");
|
||||
header_printed = true;
|
||||
}
|
||||
|
||||
seq_printf(seq, "Target name: %s\nInitiator name: %s\n",
|
||||
sess->tgt->tgtt->name,
|
||||
sess->initiator_name);
|
||||
|
||||
spin_lock_bh(&sess->lat_lock);
|
||||
|
||||
for (i = 0; i < SCST_LATENCY_STATS_NUM ; i++) {
|
||||
uint64_t scst_time_wr, tgt_time_wr, dev_time_wr;
|
||||
uint64_t processed_cmds_wr;
|
||||
uint64_t scst_time_rd, tgt_time_rd, dev_time_rd;
|
||||
uint64_t processed_cmds_rd;
|
||||
struct scst_ext_latency_stat *latency_stat;
|
||||
|
||||
latency_stat = &sess->sess_latency_stat[i];
|
||||
scst_time_wr = latency_stat->scst_time_wr;
|
||||
scst_time_rd = latency_stat->scst_time_rd;
|
||||
tgt_time_wr = latency_stat->tgt_time_wr;
|
||||
tgt_time_rd = latency_stat->tgt_time_rd;
|
||||
dev_time_wr = latency_stat->dev_time_wr;
|
||||
dev_time_rd = latency_stat->dev_time_rd;
|
||||
processed_cmds_wr = latency_stat->processed_cmds_wr;
|
||||
processed_cmds_rd = latency_stat->processed_cmds_rd;
|
||||
|
||||
seq_printf(seq, "%-5s %-9s %-15llu ",
|
||||
"Write", scst_io_size_names[i],
|
||||
processed_cmds_wr);
|
||||
|
||||
scst_time_per_cmd(scst_time_wr, processed_cmds_wr);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_scst_time_wr,
|
||||
(unsigned long)scst_time_wr,
|
||||
(unsigned long)latency_stat->max_scst_time_wr,
|
||||
(unsigned long)latency_stat->scst_time_wr);
|
||||
seq_printf(seq, "%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(tgt_time_wr, processed_cmds_wr);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_tgt_time_wr,
|
||||
(unsigned long)tgt_time_wr,
|
||||
(unsigned long)latency_stat->max_tgt_time_wr,
|
||||
(unsigned long)latency_stat->tgt_time_wr);
|
||||
seq_printf(seq, "%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(dev_time_wr, processed_cmds_wr);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_dev_time_wr,
|
||||
(unsigned long)dev_time_wr,
|
||||
(unsigned long)latency_stat->max_dev_time_wr,
|
||||
(unsigned long)latency_stat->dev_time_wr);
|
||||
seq_printf(seq, "%-46s\n", buf);
|
||||
|
||||
seq_printf(seq, "%-5s %-9s %-15llu ",
|
||||
"Read", scst_io_size_names[i],
|
||||
processed_cmds_rd);
|
||||
|
||||
scst_time_per_cmd(scst_time_rd, processed_cmds_rd);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_scst_time_rd,
|
||||
(unsigned long)scst_time_rd,
|
||||
(unsigned long)latency_stat->max_scst_time_rd,
|
||||
(unsigned long)latency_stat->scst_time_rd);
|
||||
seq_printf(seq, "%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(tgt_time_rd, processed_cmds_rd);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_tgt_time_rd,
|
||||
(unsigned long)tgt_time_rd,
|
||||
(unsigned long)latency_stat->max_tgt_time_rd,
|
||||
(unsigned long)latency_stat->tgt_time_rd);
|
||||
seq_printf(seq, "%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(dev_time_rd, processed_cmds_rd);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_dev_time_rd,
|
||||
(unsigned long)dev_time_rd,
|
||||
(unsigned long)latency_stat->max_dev_time_rd,
|
||||
(unsigned long)latency_stat->dev_time_rd);
|
||||
seq_printf(seq, "%-46s\n", buf);
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) {
|
||||
struct list_head *head =
|
||||
&sess->sess_tgt_dev_list[t];
|
||||
struct scst_tgt_dev *tgt_dev;
|
||||
|
||||
list_for_each_entry_rcu(tgt_dev, head,
|
||||
sess_tgt_dev_list_entry) {
|
||||
|
||||
seq_printf(seq, "\nLUN: %llu\n", tgt_dev->lun);
|
||||
|
||||
for (i = 0; i < SCST_LATENCY_STATS_NUM ; i++) {
|
||||
uint64_t scst_time_wr, tgt_time_wr, dev_time_wr;
|
||||
uint64_t processed_cmds_wr;
|
||||
uint64_t scst_time_rd, tgt_time_rd, dev_time_rd;
|
||||
uint64_t processed_cmds_rd;
|
||||
struct scst_ext_latency_stat *latency_stat;
|
||||
|
||||
latency_stat = &tgt_dev->dev_latency_stat[i];
|
||||
scst_time_wr = latency_stat->scst_time_wr;
|
||||
scst_time_rd = latency_stat->scst_time_rd;
|
||||
tgt_time_wr = latency_stat->tgt_time_wr;
|
||||
tgt_time_rd = latency_stat->tgt_time_rd;
|
||||
dev_time_wr = latency_stat->dev_time_wr;
|
||||
dev_time_rd = latency_stat->dev_time_rd;
|
||||
processed_cmds_wr = latency_stat->processed_cmds_wr;
|
||||
processed_cmds_rd = latency_stat->processed_cmds_rd;
|
||||
|
||||
seq_printf(seq, "%-5s %-9s %-15llu ",
|
||||
"Write", scst_io_size_names[i],
|
||||
processed_cmds_wr);
|
||||
|
||||
scst_time_per_cmd(scst_time_wr, processed_cmds_wr);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_scst_time_wr,
|
||||
(unsigned long)scst_time_wr,
|
||||
(unsigned long)latency_stat->max_scst_time_wr,
|
||||
(unsigned long)latency_stat->scst_time_wr);
|
||||
seq_printf(seq, "%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(tgt_time_wr, processed_cmds_wr);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_tgt_time_wr,
|
||||
(unsigned long)tgt_time_wr,
|
||||
(unsigned long)latency_stat->max_tgt_time_wr,
|
||||
(unsigned long)latency_stat->tgt_time_wr);
|
||||
seq_printf(seq, "%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(dev_time_wr, processed_cmds_wr);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_dev_time_wr,
|
||||
(unsigned long)dev_time_wr,
|
||||
(unsigned long)latency_stat->max_dev_time_wr,
|
||||
(unsigned long)latency_stat->dev_time_wr);
|
||||
seq_printf(seq, "%-46s\n", buf);
|
||||
|
||||
seq_printf(seq, "%-5s %-9s %-15llu ",
|
||||
"Read", scst_io_size_names[i],
|
||||
processed_cmds_rd);
|
||||
if (processed_cmds_rd == 0)
|
||||
processed_cmds_rd = 1;
|
||||
|
||||
scst_time_per_cmd(scst_time_rd, processed_cmds_rd);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_scst_time_rd,
|
||||
(unsigned long)scst_time_rd,
|
||||
(unsigned long)latency_stat->max_scst_time_rd,
|
||||
(unsigned long)latency_stat->scst_time_rd);
|
||||
seq_printf(seq, "%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(tgt_time_rd, processed_cmds_rd);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_tgt_time_rd,
|
||||
(unsigned long)tgt_time_rd,
|
||||
(unsigned long)latency_stat->max_tgt_time_rd,
|
||||
(unsigned long)latency_stat->tgt_time_rd);
|
||||
seq_printf(seq, "%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(dev_time_rd, processed_cmds_rd);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_dev_time_rd,
|
||||
(unsigned long)dev_time_rd,
|
||||
(unsigned long)latency_stat->max_dev_time_rd,
|
||||
(unsigned long)latency_stat->dev_time_rd);
|
||||
seq_printf(seq, "%-46s\n", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
scst_time = sess->scst_time;
|
||||
tgt_time = sess->tgt_time;
|
||||
dev_time = sess->dev_time;
|
||||
processed_cmds = sess->processed_cmds;
|
||||
|
||||
seq_printf(seq, "\n%-15s %-16llu", "Overall ",
|
||||
processed_cmds);
|
||||
|
||||
if (processed_cmds == 0)
|
||||
processed_cmds = 1;
|
||||
|
||||
scst_time_per_cmd(scst_time, processed_cmds);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)sess->min_scst_time,
|
||||
(unsigned long)scst_time,
|
||||
(unsigned long)sess->max_scst_time,
|
||||
(unsigned long)sess->scst_time);
|
||||
seq_printf(seq, "%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(tgt_time, processed_cmds);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)sess->min_tgt_time,
|
||||
(unsigned long)tgt_time,
|
||||
(unsigned long)sess->max_tgt_time,
|
||||
(unsigned long)sess->tgt_time);
|
||||
seq_printf(seq, "%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(dev_time, processed_cmds);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)sess->min_dev_time,
|
||||
(unsigned long)dev_time,
|
||||
(unsigned long)sess->max_dev_time,
|
||||
(unsigned long)sess->dev_time);
|
||||
seq_printf(seq, "%-46s\n\n", buf);
|
||||
|
||||
spin_unlock_bh(&sess->lat_lock);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&scst_mutex);
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t scst_proc_scsi_tgt_gen_write_lat(struct file *file,
|
||||
const char __user *buf,
|
||||
size_t length, loff_t *off)
|
||||
{
|
||||
int res = length, t;
|
||||
struct scst_acg *acg;
|
||||
struct scst_session *sess;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
if (mutex_lock_interruptible(&scst_mutex) != 0) {
|
||||
res = -EINTR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
list_for_each_entry(acg, &scst_acg_list, acg_list_entry) {
|
||||
list_for_each_entry(sess, &acg->acg_sess_list,
|
||||
acg_sess_list_entry) {
|
||||
PRINT_INFO("Zeroing latency statistics for initiator "
|
||||
"%s", sess->initiator_name);
|
||||
|
||||
spin_lock_bh(&sess->lat_lock);
|
||||
rcu_read_lock();
|
||||
|
||||
sess->scst_time = 0;
|
||||
sess->tgt_time = 0;
|
||||
sess->dev_time = 0;
|
||||
sess->min_scst_time = 0;
|
||||
sess->min_tgt_time = 0;
|
||||
sess->min_dev_time = 0;
|
||||
sess->max_scst_time = 0;
|
||||
sess->max_tgt_time = 0;
|
||||
sess->max_dev_time = 0;
|
||||
sess->processed_cmds = 0;
|
||||
memset(sess->sess_latency_stat, 0,
|
||||
sizeof(sess->sess_latency_stat));
|
||||
|
||||
for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) {
|
||||
struct list_head *head =
|
||||
&sess->sess_tgt_dev_list[t];
|
||||
struct scst_tgt_dev *tgt_dev;
|
||||
|
||||
list_for_each_entry_rcu(tgt_dev, head,
|
||||
sess_tgt_dev_list_entry) {
|
||||
tgt_dev->scst_time = 0;
|
||||
tgt_dev->tgt_time = 0;
|
||||
tgt_dev->dev_time = 0;
|
||||
tgt_dev->processed_cmds = 0;
|
||||
memset(tgt_dev->dev_latency_stat, 0,
|
||||
sizeof(tgt_dev->dev_latency_stat));
|
||||
}
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
spin_unlock_bh(&sess->lat_lock);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&scst_mutex);
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct scst_proc_data scst_lat_proc_data = {
|
||||
SCST_DEF_RW_SEQ_OP(scst_proc_scsi_tgt_gen_write_lat)
|
||||
.show = lat_info_show,
|
||||
.data = "scsi_tgt",
|
||||
};
|
||||
|
||||
#endif /* CONFIG_SCST_MEASURE_LATENCY */
|
||||
|
||||
static int __init scst_proc_init_module_log(void)
|
||||
{
|
||||
int res = 0;
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING) || \
|
||||
defined(CONFIG_SCST_MEASURE_LATENCY)
|
||||
#if defined(CONFIG_SCST_DEBUG) || defined(CONFIG_SCST_TRACING)
|
||||
struct proc_dir_entry *generic;
|
||||
#endif
|
||||
|
||||
@@ -823,20 +485,6 @@ static int __init scst_proc_init_module_log(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
if (res == 0) {
|
||||
generic = scst_create_proc_entry(scst_proc_scsi_tgt,
|
||||
SCST_PROC_LAT_ENTRY_NAME,
|
||||
&scst_lat_proc_data);
|
||||
if (!generic) {
|
||||
PRINT_ERROR("cannot init /proc/%s/%s",
|
||||
SCST_PROC_ENTRY_NAME,
|
||||
SCST_PROC_LAT_ENTRY_NAME);
|
||||
res = -ENOMEM;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
@@ -849,10 +497,6 @@ static void scst_proc_cleanup_module_log(void)
|
||||
remove_proc_entry(SCST_PROC_LOG_ENTRY_NAME, scst_proc_scsi_tgt);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
remove_proc_entry(SCST_PROC_LAT_ENTRY_NAME, scst_proc_scsi_tgt);
|
||||
#endif
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4127,117 +4127,6 @@ static ssize_t scst_tgt_dev_thread_index_show(struct kobject *kobj,
|
||||
static struct kobj_attribute tgt_dev_thread_idx_attr =
|
||||
__ATTR(thread_index, S_IRUGO, scst_tgt_dev_thread_index_show, NULL);
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
|
||||
static char *scst_io_size_names[] = {
|
||||
"<=8K ",
|
||||
"<=32K ",
|
||||
"<=128K",
|
||||
"<=512K",
|
||||
">512K "
|
||||
};
|
||||
|
||||
static ssize_t scst_tgt_dev_latency_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buffer)
|
||||
{
|
||||
int res = 0, i;
|
||||
char buf[50];
|
||||
struct scst_tgt_dev *tgt_dev;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
tgt_dev = container_of(kobj, struct scst_tgt_dev, tgt_dev_kobj);
|
||||
|
||||
for (i = 0; i < SCST_LATENCY_STATS_NUM; i++) {
|
||||
uint64_t scst_time_wr, tgt_time_wr, dev_time_wr;
|
||||
uint64_t processed_cmds_wr;
|
||||
uint64_t scst_time_rd, tgt_time_rd, dev_time_rd;
|
||||
uint64_t processed_cmds_rd;
|
||||
struct scst_ext_latency_stat *latency_stat;
|
||||
|
||||
latency_stat = &tgt_dev->dev_latency_stat[i];
|
||||
scst_time_wr = latency_stat->scst_time_wr;
|
||||
scst_time_rd = latency_stat->scst_time_rd;
|
||||
tgt_time_wr = latency_stat->tgt_time_wr;
|
||||
tgt_time_rd = latency_stat->tgt_time_rd;
|
||||
dev_time_wr = latency_stat->dev_time_wr;
|
||||
dev_time_rd = latency_stat->dev_time_rd;
|
||||
processed_cmds_wr = latency_stat->processed_cmds_wr;
|
||||
processed_cmds_rd = latency_stat->processed_cmds_rd;
|
||||
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-5s %-9s %-15llu ", "Write", scst_io_size_names[i],
|
||||
processed_cmds_wr);
|
||||
|
||||
scst_time_per_cmd(scst_time_wr, processed_cmds_wr);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_scst_time_wr,
|
||||
(unsigned long)scst_time_wr,
|
||||
(unsigned long)latency_stat->max_scst_time_wr,
|
||||
(unsigned long)latency_stat->scst_time_wr);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(tgt_time_wr, processed_cmds_wr);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_tgt_time_wr,
|
||||
(unsigned long)tgt_time_wr,
|
||||
(unsigned long)latency_stat->max_tgt_time_wr,
|
||||
(unsigned long)latency_stat->tgt_time_wr);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(dev_time_wr, processed_cmds_wr);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_dev_time_wr,
|
||||
(unsigned long)dev_time_wr,
|
||||
(unsigned long)latency_stat->max_dev_time_wr,
|
||||
(unsigned long)latency_stat->dev_time_wr);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s\n", buf);
|
||||
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-5s %-9s %-15llu ", "Read", scst_io_size_names[i],
|
||||
processed_cmds_rd);
|
||||
|
||||
scst_time_per_cmd(scst_time_rd, processed_cmds_rd);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_scst_time_rd,
|
||||
(unsigned long)scst_time_rd,
|
||||
(unsigned long)latency_stat->max_scst_time_rd,
|
||||
(unsigned long)latency_stat->scst_time_rd);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(tgt_time_rd, processed_cmds_rd);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_tgt_time_rd,
|
||||
(unsigned long)tgt_time_rd,
|
||||
(unsigned long)latency_stat->max_tgt_time_rd,
|
||||
(unsigned long)latency_stat->tgt_time_rd);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(dev_time_rd, processed_cmds_rd);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_dev_time_rd,
|
||||
(unsigned long)dev_time_rd,
|
||||
(unsigned long)latency_stat->max_dev_time_rd,
|
||||
(unsigned long)latency_stat->dev_time_rd);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s\n", buf);
|
||||
}
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct kobj_attribute tgt_dev_latency_attr =
|
||||
__ATTR(latency, S_IRUGO,
|
||||
scst_tgt_dev_latency_show, NULL);
|
||||
|
||||
#endif /* CONFIG_SCST_MEASURE_LATENCY */
|
||||
|
||||
static ssize_t scst_tgt_dev_thread_pid_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr,
|
||||
char *buffer)
|
||||
@@ -4336,9 +4225,6 @@ static struct attribute *scst_tgt_dev_attrs[] = {
|
||||
&tgt_dev_thread_idx_attr.attr,
|
||||
&tgt_dev_thread_pid_attr.attr,
|
||||
&tgt_dev_active_commands_attr.attr,
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
&tgt_dev_latency_attr.attr,
|
||||
#endif
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -4426,237 +4312,6 @@ void scst_tgt_dev_sysfs_del(struct scst_tgt_dev *tgt_dev)
|
||||
** Sessions subdirectory implementation
|
||||
**/
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
|
||||
static ssize_t scst_sess_latency_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buffer)
|
||||
{
|
||||
ssize_t res = 0;
|
||||
struct scst_session *sess;
|
||||
int i;
|
||||
char buf[50];
|
||||
uint64_t scst_time, tgt_time, dev_time;
|
||||
uint64_t processed_cmds;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
sess = container_of(kobj, struct scst_session, sess_kobj);
|
||||
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-15s %-15s %-46s %-46s %-46s\n",
|
||||
"T-L names", "Total commands", "SCST latency",
|
||||
"Target latency", "Dev latency (min/avg/max/all us)");
|
||||
|
||||
spin_lock_bh(&sess->lat_lock);
|
||||
|
||||
for (i = 0; i < SCST_LATENCY_STATS_NUM; i++) {
|
||||
uint64_t scst_time_wr, tgt_time_wr, dev_time_wr;
|
||||
uint64_t processed_cmds_wr;
|
||||
uint64_t scst_time_rd, tgt_time_rd, dev_time_rd;
|
||||
uint64_t processed_cmds_rd;
|
||||
struct scst_ext_latency_stat *latency_stat;
|
||||
|
||||
latency_stat = &sess->sess_latency_stat[i];
|
||||
scst_time_wr = latency_stat->scst_time_wr;
|
||||
scst_time_rd = latency_stat->scst_time_rd;
|
||||
tgt_time_wr = latency_stat->tgt_time_wr;
|
||||
tgt_time_rd = latency_stat->tgt_time_rd;
|
||||
dev_time_wr = latency_stat->dev_time_wr;
|
||||
dev_time_rd = latency_stat->dev_time_rd;
|
||||
processed_cmds_wr = latency_stat->processed_cmds_wr;
|
||||
processed_cmds_rd = latency_stat->processed_cmds_rd;
|
||||
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-5s %-9s %-15llu ",
|
||||
"Write", scst_io_size_names[i],
|
||||
processed_cmds_wr);
|
||||
|
||||
scst_time_per_cmd(scst_time_wr, processed_cmds_wr);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_scst_time_wr,
|
||||
(unsigned long)scst_time_wr,
|
||||
(unsigned long)latency_stat->max_scst_time_wr,
|
||||
(unsigned long)latency_stat->scst_time_wr);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(tgt_time_wr, processed_cmds_wr);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_tgt_time_wr,
|
||||
(unsigned long)tgt_time_wr,
|
||||
(unsigned long)latency_stat->max_tgt_time_wr,
|
||||
(unsigned long)latency_stat->tgt_time_wr);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(dev_time_wr, processed_cmds_wr);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_dev_time_wr,
|
||||
(unsigned long)dev_time_wr,
|
||||
(unsigned long)latency_stat->max_dev_time_wr,
|
||||
(unsigned long)latency_stat->dev_time_wr);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s\n", buf);
|
||||
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-5s %-9s %-15llu ",
|
||||
"Read", scst_io_size_names[i],
|
||||
processed_cmds_rd);
|
||||
|
||||
scst_time_per_cmd(scst_time_rd, processed_cmds_rd);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_scst_time_rd,
|
||||
(unsigned long)scst_time_rd,
|
||||
(unsigned long)latency_stat->max_scst_time_rd,
|
||||
(unsigned long)latency_stat->scst_time_rd);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(tgt_time_rd, processed_cmds_rd);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_tgt_time_rd,
|
||||
(unsigned long)tgt_time_rd,
|
||||
(unsigned long)latency_stat->max_tgt_time_rd,
|
||||
(unsigned long)latency_stat->tgt_time_rd);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(dev_time_rd, processed_cmds_rd);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)latency_stat->min_dev_time_rd,
|
||||
(unsigned long)dev_time_rd,
|
||||
(unsigned long)latency_stat->max_dev_time_rd,
|
||||
(unsigned long)latency_stat->dev_time_rd);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s\n", buf);
|
||||
}
|
||||
|
||||
scst_time = sess->scst_time;
|
||||
tgt_time = sess->tgt_time;
|
||||
dev_time = sess->dev_time;
|
||||
processed_cmds = sess->processed_cmds;
|
||||
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"\n%-15s %-16llu", "Overall ", processed_cmds);
|
||||
|
||||
scst_time_per_cmd(scst_time, processed_cmds);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)sess->min_scst_time,
|
||||
(unsigned long)scst_time,
|
||||
(unsigned long)sess->max_scst_time,
|
||||
(unsigned long)sess->scst_time);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(tgt_time, processed_cmds);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)sess->min_tgt_time,
|
||||
(unsigned long)tgt_time,
|
||||
(unsigned long)sess->max_tgt_time,
|
||||
(unsigned long)sess->tgt_time);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s ", buf);
|
||||
|
||||
scst_time_per_cmd(dev_time, processed_cmds);
|
||||
snprintf(buf, sizeof(buf), "%lu/%lu/%lu/%lu",
|
||||
(unsigned long)sess->min_dev_time,
|
||||
(unsigned long)dev_time,
|
||||
(unsigned long)sess->max_dev_time,
|
||||
(unsigned long)sess->dev_time);
|
||||
res += scnprintf(&buffer[res], SCST_SYSFS_BLOCK_SIZE - res,
|
||||
"%-46s\n\n", buf);
|
||||
|
||||
spin_unlock_bh(&sess->lat_lock);
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int scst_sess_zero_latency(struct scst_sysfs_work_item *work)
|
||||
{
|
||||
int res = 0, t;
|
||||
struct scst_session *sess = work->sess;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
PRINT_INFO("Zeroing latency statistics for initiator "
|
||||
"%s", sess->initiator_name);
|
||||
|
||||
spin_lock_bh(&sess->lat_lock);
|
||||
rcu_read_lock();
|
||||
|
||||
sess->scst_time = 0;
|
||||
sess->tgt_time = 0;
|
||||
sess->dev_time = 0;
|
||||
sess->min_scst_time = 0;
|
||||
sess->min_tgt_time = 0;
|
||||
sess->min_dev_time = 0;
|
||||
sess->max_scst_time = 0;
|
||||
sess->max_tgt_time = 0;
|
||||
sess->max_dev_time = 0;
|
||||
sess->processed_cmds = 0;
|
||||
memset(sess->sess_latency_stat, 0,
|
||||
sizeof(sess->sess_latency_stat));
|
||||
|
||||
for (t = SESS_TGT_DEV_LIST_HASH_SIZE-1; t >= 0; t--) {
|
||||
struct list_head *head = &sess->sess_tgt_dev_list[t];
|
||||
struct scst_tgt_dev *tgt_dev;
|
||||
|
||||
list_for_each_entry_rcu(tgt_dev, head,
|
||||
sess_tgt_dev_list_entry) {
|
||||
tgt_dev->scst_time = 0;
|
||||
tgt_dev->tgt_time = 0;
|
||||
tgt_dev->dev_time = 0;
|
||||
tgt_dev->processed_cmds = 0;
|
||||
memset(tgt_dev->dev_latency_stat, 0,
|
||||
sizeof(tgt_dev->dev_latency_stat));
|
||||
}
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
spin_unlock_bh(&sess->lat_lock);
|
||||
|
||||
kobject_put(&sess->sess_kobj);
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static ssize_t scst_sess_latency_store(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
int res;
|
||||
struct scst_session *sess;
|
||||
struct scst_sysfs_work_item *work;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
sess = container_of(kobj, struct scst_session, sess_kobj);
|
||||
|
||||
res = scst_alloc_sysfs_work(scst_sess_zero_latency, false, &work);
|
||||
if (res != 0)
|
||||
goto out;
|
||||
|
||||
work->sess = sess;
|
||||
|
||||
SCST_SET_DEP_MAP(work, &scst_sess_dep_map);
|
||||
kobject_get(&sess->sess_kobj);
|
||||
|
||||
res = scst_sysfs_queue_wait_work(work);
|
||||
if (res == 0)
|
||||
res = count;
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct kobj_attribute session_latency_attr =
|
||||
__ATTR(latency, S_IRUGO | S_IWUSR, scst_sess_latency_show,
|
||||
scst_sess_latency_store);
|
||||
|
||||
#endif /* CONFIG_SCST_MEASURE_LATENCY */
|
||||
|
||||
static ssize_t scst_sess_sysfs_commands_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
@@ -4987,9 +4642,6 @@ static struct attribute *scst_session_attrs[] = {
|
||||
&session_bidi_io_count_kb_attr.attr,
|
||||
&session_bidi_unaligned_cmd_count_attr.attr,
|
||||
&session_none_cmd_count_attr.attr,
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
&session_latency_attr.attr,
|
||||
#endif /* CONFIG_SCST_MEASURE_LATENCY */
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
+38
-106
@@ -47,31 +47,6 @@ static struct scst_cmd *__scst_find_cmd_by_tag(struct scst_session *sess,
|
||||
static void scst_process_redirect_cmd(struct scst_cmd *cmd,
|
||||
enum scst_exec_context context, int check_retries);
|
||||
|
||||
/*
|
||||
* scst_post_parse() - do post parse actions
|
||||
*
|
||||
* This function must be called by dev handler after its parse() callback
|
||||
* returned SCST_CMD_STATE_STOP before calling scst_process_active_cmd().
|
||||
*/
|
||||
void scst_post_parse(struct scst_cmd *cmd)
|
||||
{
|
||||
scst_set_parse_time(cmd);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(scst_post_parse);
|
||||
|
||||
/*
|
||||
* scst_post_dev_alloc_data_buf() - do post dev_alloc_data_buf actions
|
||||
*
|
||||
* This function must be called by dev handler after its dev_alloc_data_buf()
|
||||
* callback returned SCST_CMD_STATE_STOP before calling
|
||||
* scst_process_active_cmd().
|
||||
*/
|
||||
void scst_post_dev_alloc_data_buf(struct scst_cmd *cmd)
|
||||
{
|
||||
scst_set_dev_alloc_buf_time(cmd);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(scst_post_dev_alloc_data_buf);
|
||||
|
||||
static inline void scst_schedule_tasklet(struct scst_cmd *cmd)
|
||||
{
|
||||
struct scst_percpu_info *i;
|
||||
@@ -818,8 +793,6 @@ void scst_cmd_init_done(struct scst_cmd *cmd,
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
scst_set_start_time(cmd);
|
||||
|
||||
TRACE_DBG("Preferred context: %d (cmd %p)", pref_context, cmd);
|
||||
TRACE(TRACE_SCSI, "NEW CDB: len %d, lun %lld, initiator %s, "
|
||||
"target %s, queue_type %x, tag %llu (cmd %p, sess %p)",
|
||||
@@ -894,7 +867,7 @@ set_state:
|
||||
* already preliminary completed by target driver we need to init
|
||||
* cmd anyway to find out in which format we should return sense.
|
||||
*/
|
||||
cmd->state = SCST_CMD_STATE_INIT;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_INIT);
|
||||
rc = scst_init_cmd(cmd, &pref_context);
|
||||
if (unlikely(rc < 0))
|
||||
goto out;
|
||||
@@ -1060,7 +1033,6 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
|
||||
|
||||
TRACE_DBG("Calling dev handler %s parse(%p)",
|
||||
devt->name, cmd);
|
||||
scst_set_cur_start(cmd);
|
||||
state = devt->parse(cmd);
|
||||
/* Caution: cmd can be already dead here */
|
||||
TRACE_DBG("Dev handler %s parse() returned %d",
|
||||
@@ -1068,7 +1040,6 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
|
||||
|
||||
switch (state) {
|
||||
case SCST_CMD_STATE_NEED_THREAD_CTX:
|
||||
scst_set_parse_time(cmd);
|
||||
TRACE_DBG("Dev handler %s parse() requested thread "
|
||||
"context, rescheduling", devt->name);
|
||||
res = SCST_CMD_STATE_RES_NEED_THREAD;
|
||||
@@ -1083,8 +1054,6 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
|
||||
res = SCST_CMD_STATE_RES_CONT_NEXT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
scst_set_parse_time(cmd);
|
||||
} else
|
||||
state = scst_do_internal_parsing(cmd);
|
||||
|
||||
@@ -1323,7 +1292,7 @@ set_res:
|
||||
case SCST_CMD_STATE_FINISHED:
|
||||
case SCST_CMD_STATE_FINISHED_INTERNAL:
|
||||
#endif
|
||||
cmd->state = state;
|
||||
scst_set_cmd_state(cmd, state);
|
||||
res = SCST_CMD_STATE_RES_CONT_SAME;
|
||||
#ifdef CONFIG_SCST_EXTRACHECKS
|
||||
break;
|
||||
@@ -1504,7 +1473,6 @@ static int scst_prepare_space(struct scst_cmd *cmd)
|
||||
|
||||
TRACE_DBG("Calling dev handler's %s dev_alloc_data_buf(%p)",
|
||||
devt->name, cmd);
|
||||
scst_set_cur_start(cmd);
|
||||
state = devt->dev_alloc_data_buf(cmd);
|
||||
/*
|
||||
* Caution: cmd can be already dead here
|
||||
@@ -1516,7 +1484,6 @@ static int scst_prepare_space(struct scst_cmd *cmd)
|
||||
|
||||
switch (state) {
|
||||
case SCST_CMD_STATE_NEED_THREAD_CTX:
|
||||
scst_set_dev_alloc_buf_time(cmd);
|
||||
TRACE_DBG("Dev handler %s dev_alloc_data_buf() requested "
|
||||
"thread context, rescheduling", devt->name);
|
||||
res = SCST_CMD_STATE_RES_NEED_THREAD;
|
||||
@@ -1530,10 +1497,8 @@ static int scst_prepare_space(struct scst_cmd *cmd)
|
||||
goto out;
|
||||
}
|
||||
|
||||
scst_set_dev_alloc_buf_time(cmd);
|
||||
|
||||
if (unlikely(state != SCST_CMD_STATE_DEFAULT)) {
|
||||
cmd->state = state;
|
||||
scst_set_cmd_state(cmd, state);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -1544,10 +1509,7 @@ static int scst_prepare_space(struct scst_cmd *cmd)
|
||||
TRACE_MEM("Calling tgt %s tgt_alloc_data_buf(cmd %p)",
|
||||
cmd->tgt->tgt_name, cmd);
|
||||
|
||||
scst_set_cur_start(cmd);
|
||||
r = cmd->tgtt->tgt_alloc_data_buf(cmd);
|
||||
scst_set_tgt_alloc_buf_time(cmd);
|
||||
|
||||
if (r > 0)
|
||||
goto alloc;
|
||||
else if (r == 0) {
|
||||
@@ -1613,14 +1575,14 @@ check:
|
||||
|
||||
done:
|
||||
if (cmd->preprocessing_only) {
|
||||
cmd->state = SCST_CMD_STATE_PREPROCESSING_DONE;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_PREPROCESSING_DONE);
|
||||
if (cmd->data_direction & SCST_DATA_WRITE)
|
||||
scst_set_write_len(cmd);
|
||||
} else if (cmd->data_direction & SCST_DATA_WRITE) {
|
||||
cmd->state = SCST_CMD_STATE_RDY_TO_XFER;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_RDY_TO_XFER);
|
||||
scst_set_write_len(cmd);
|
||||
} else
|
||||
cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_TGT_PRE_EXEC);
|
||||
|
||||
out:
|
||||
TRACE_EXIT_HRES(res);
|
||||
@@ -1655,10 +1617,9 @@ static int scst_preprocessing_done(struct scst_cmd *cmd)
|
||||
cmd->preprocessing_only = 0;
|
||||
|
||||
res = SCST_CMD_STATE_RES_CONT_NEXT;
|
||||
cmd->state = SCST_CMD_STATE_PREPROCESSING_DONE_CALLED;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_PREPROCESSING_DONE_CALLED);
|
||||
|
||||
TRACE_DBG("Calling preprocessing_done(cmd %p)", cmd);
|
||||
scst_set_cur_start(cmd);
|
||||
cmd->tgtt->preprocessing_done(cmd);
|
||||
TRACE_DBG("%s", "preprocessing_done() returned");
|
||||
|
||||
@@ -1687,8 +1648,6 @@ void scst_restart_cmd(struct scst_cmd *cmd, int status,
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
scst_set_restart_waiting_time(cmd);
|
||||
|
||||
TRACE_DBG("Preferred context: %d", pref_context);
|
||||
TRACE_DBG("tag=%llu, status=%#x",
|
||||
(unsigned long long int)scst_cmd_get_tag(cmd),
|
||||
@@ -1709,13 +1668,13 @@ void scst_restart_cmd(struct scst_cmd *cmd, int status,
|
||||
switch (status) {
|
||||
case SCST_PREPROCESS_STATUS_SUCCESS:
|
||||
if (unlikely(cmd->tgt_dev == NULL)) {
|
||||
cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_PRE_XMIT_RESP);
|
||||
pref_context = SCST_CONTEXT_THREAD;
|
||||
break;
|
||||
} else if (cmd->data_direction & SCST_DATA_WRITE)
|
||||
cmd->state = SCST_CMD_STATE_RDY_TO_XFER;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_RDY_TO_XFER);
|
||||
else
|
||||
cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_TGT_PRE_EXEC);
|
||||
if (cmd->set_sn_on_restart_cmd) {
|
||||
EXTRACHECKS_BUG_ON(cmd->tgtt->multithreaded_init_done);
|
||||
scst_cmd_set_sn(cmd);
|
||||
@@ -1778,7 +1737,7 @@ static int scst_rdy_to_xfer(struct scst_cmd *cmd)
|
||||
}
|
||||
|
||||
if ((tgtt->rdy_to_xfer == NULL) || unlikely(cmd->internal)) {
|
||||
cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_TGT_PRE_EXEC);
|
||||
#ifndef CONFIG_SCST_TEST_IO_IN_SIRQ
|
||||
/* We can't allow atomic command on the exec stages */
|
||||
if (scst_cmd_atomic(cmd)) {
|
||||
@@ -1803,7 +1762,7 @@ static int scst_rdy_to_xfer(struct scst_cmd *cmd)
|
||||
}
|
||||
|
||||
res = SCST_CMD_STATE_RES_CONT_NEXT;
|
||||
cmd->state = SCST_CMD_STATE_DATA_WAIT;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_DATA_WAIT);
|
||||
|
||||
if (tgtt->on_hw_pending_cmd_timeout != NULL) {
|
||||
struct scst_session *sess = cmd->sess;
|
||||
@@ -1821,8 +1780,6 @@ static int scst_rdy_to_xfer(struct scst_cmd *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
scst_set_cur_start(cmd);
|
||||
|
||||
TRACE_DBG("Calling rdy_to_xfer(%p)", cmd);
|
||||
#ifdef CONFIG_SCST_DEBUG_RETRY
|
||||
if (((scst_random() % 100) == 75))
|
||||
@@ -1835,12 +1792,10 @@ static int scst_rdy_to_xfer(struct scst_cmd *cmd)
|
||||
if (likely(rc == SCST_TGT_RES_SUCCESS))
|
||||
goto out;
|
||||
|
||||
scst_set_rdy_to_xfer_time(cmd);
|
||||
|
||||
cmd->cmd_hw_pending = 0;
|
||||
|
||||
/* Restore the previous state */
|
||||
cmd->state = SCST_CMD_STATE_RDY_TO_XFER;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_RDY_TO_XFER);
|
||||
|
||||
switch (rc) {
|
||||
case SCST_TGT_RES_QUEUE_FULL:
|
||||
@@ -1965,8 +1920,6 @@ void scst_rx_data(struct scst_cmd *cmd, int status,
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
scst_set_rdy_to_xfer_time(cmd);
|
||||
|
||||
TRACE_DBG("Preferred context: %d", pref_context);
|
||||
|
||||
cmd->cmd_hw_pending = 0;
|
||||
@@ -1985,7 +1938,7 @@ void scst_rx_data(struct scst_cmd *cmd, int status,
|
||||
|
||||
switch (status) {
|
||||
case SCST_RX_STATUS_SUCCESS:
|
||||
cmd->state = SCST_CMD_STATE_TGT_PRE_EXEC;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_TGT_PRE_EXEC);
|
||||
|
||||
#ifdef CONFIG_SCST_TEST_IO_IN_SIRQ
|
||||
if (cmd->op_flags & SCST_TEST_IO_IN_SIRQ_ALLOWED)
|
||||
@@ -2119,7 +2072,7 @@ static int scst_tgt_pre_exec(struct scst_cmd *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
cmd->state = SCST_CMD_STATE_EXEC_CHECK_SN;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_EXEC_CHECK_SN);
|
||||
|
||||
if (unlikely(cmd->internal)) {
|
||||
if (cmd->dh_data_buf_alloced && cmd->tgt_i_data_buf_alloced &&
|
||||
@@ -2135,9 +2088,7 @@ static int scst_tgt_pre_exec(struct scst_cmd *cmd)
|
||||
goto out_descr;
|
||||
|
||||
TRACE_DBG("Calling pre_exec(%p)", cmd);
|
||||
scst_set_cur_start(cmd);
|
||||
rc = cmd->tgtt->pre_exec(cmd);
|
||||
scst_set_pre_exec_time(cmd);
|
||||
TRACE_DBG("pre_exec() returned %d", rc);
|
||||
|
||||
if (unlikely(rc != SCST_PREPROCESS_STATUS_SUCCESS)) {
|
||||
@@ -2178,8 +2129,6 @@ static void scst_do_cmd_done(struct scst_cmd *cmd, int result,
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
scst_set_exec_time(cmd);
|
||||
|
||||
WARN_ON_ONCE(IS_ERR_VALUE((long)result));
|
||||
|
||||
cmd->status = result & 0xff;
|
||||
@@ -2249,7 +2198,7 @@ void scst_pass_through_cmd_done(void *data, char *sense, int result, int resid)
|
||||
|
||||
scst_do_cmd_done(cmd, result, sense, SCSI_SENSE_BUFFERSIZE, resid);
|
||||
|
||||
cmd->state = SCST_CMD_STATE_PRE_DEV_DONE;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_PRE_DEV_DONE);
|
||||
|
||||
scst_process_redirect_cmd(cmd,
|
||||
scst_optimize_post_exec_context(cmd, scst_estimate_context()), 0);
|
||||
@@ -2265,8 +2214,6 @@ static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state,
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
scst_set_exec_time(cmd);
|
||||
|
||||
TRACE(TRACE_SCSI, "cmd %p, status %x, msg_status %x, host_status %x, "
|
||||
"driver_status %x, resp_data_len %d", cmd, cmd->status,
|
||||
cmd->msg_status, cmd->host_status, cmd->driver_status,
|
||||
@@ -2275,7 +2222,7 @@ static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state,
|
||||
if (next_state == SCST_CMD_STATE_DEFAULT)
|
||||
next_state = SCST_CMD_STATE_PRE_DEV_DONE;
|
||||
|
||||
cmd->state = next_state;
|
||||
scst_set_cmd_state(cmd, next_state);
|
||||
|
||||
#ifdef CONFIG_SCST_EXTRACHECKS
|
||||
if ((next_state != SCST_CMD_STATE_PRE_DEV_DONE) &&
|
||||
@@ -3465,12 +3412,11 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
|
||||
|
||||
ctx_changed = scst_set_io_context(cmd, &old_ctx);
|
||||
|
||||
cmd->state = SCST_CMD_STATE_EXEC_WAIT;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_EXEC_WAIT);
|
||||
|
||||
if (devt->exec) {
|
||||
TRACE_DBG("Calling dev handler %s exec(%p)",
|
||||
devt->name, cmd);
|
||||
scst_set_exec_start(cmd);
|
||||
res = devt->exec(cmd);
|
||||
TRACE_DBG("Dev handler %s exec() returned %d",
|
||||
devt->name, res);
|
||||
@@ -3478,8 +3424,6 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
|
||||
if (res == SCST_EXEC_COMPLETED)
|
||||
goto out_complete;
|
||||
|
||||
scst_set_exec_time(cmd);
|
||||
|
||||
sBUG_ON(res != SCST_EXEC_NOT_COMPLETED);
|
||||
}
|
||||
|
||||
@@ -3496,8 +3440,6 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
|
||||
scsi_dev->host->host_no, scsi_dev->channel, scsi_dev->id,
|
||||
(u64)scsi_dev->lun);
|
||||
|
||||
scst_set_exec_start(cmd);
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
|
||||
rc = scst_exec_req(scsi_dev, cmd->cdb, cmd->cdb_len,
|
||||
cmd->data_direction, cmd->sg, cmd->bufflen,
|
||||
@@ -3649,7 +3591,7 @@ static int scst_local_exec(struct scst_cmd *cmd)
|
||||
|
||||
res = scst_do_local_exec(cmd);
|
||||
if (likely(res == SCST_EXEC_NOT_COMPLETED))
|
||||
cmd->state = SCST_CMD_STATE_REAL_EXEC;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_REAL_EXEC);
|
||||
else if (res == SCST_EXEC_COMPLETED)
|
||||
scst_post_exec_sn(cmd, true);
|
||||
else
|
||||
@@ -3724,7 +3666,7 @@ static int scst_exec_check_blocking(struct scst_cmd **active_cmd)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
cmd->state = SCST_CMD_STATE_EXEC_CHECK_BLOCKING;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_EXEC_CHECK_BLOCKING);
|
||||
|
||||
if (unlikely(scst_check_alua(cmd, &res)))
|
||||
goto out;
|
||||
@@ -3769,7 +3711,7 @@ static int scst_exec_check_blocking(struct scst_cmd **active_cmd)
|
||||
goto done;
|
||||
}
|
||||
|
||||
cmd->state = SCST_CMD_STATE_LOCAL_EXEC;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_LOCAL_EXEC);
|
||||
|
||||
rc = scst_do_local_exec(cmd);
|
||||
if (likely(rc == SCST_EXEC_NOT_COMPLETED)) {
|
||||
@@ -3779,7 +3721,7 @@ static int scst_exec_check_blocking(struct scst_cmd **active_cmd)
|
||||
goto done;
|
||||
}
|
||||
|
||||
cmd->state = SCST_CMD_STATE_REAL_EXEC;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_REAL_EXEC);
|
||||
|
||||
rc = scst_do_real_exec(cmd);
|
||||
sBUG_ON(rc != SCST_EXEC_COMPLETED);
|
||||
@@ -3792,7 +3734,7 @@ done:
|
||||
EXTRACHECKS_BUG_ON(cmd->state != SCST_CMD_STATE_EXEC_CHECK_SN);
|
||||
EXTRACHECKS_BUG_ON(cmd->done);
|
||||
|
||||
cmd->state = SCST_CMD_STATE_EXEC_CHECK_BLOCKING;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_EXEC_CHECK_BLOCKING);
|
||||
|
||||
if (unlikely(scst_check_alua(cmd, &res)))
|
||||
goto out;
|
||||
@@ -4037,7 +3979,7 @@ static int scst_check_sense(struct scst_cmd *cmd)
|
||||
cmd->resp_data_len =
|
||||
cmd->dbl_ua_orig_resp_data_len;
|
||||
|
||||
cmd->state = SCST_CMD_STATE_LOCAL_EXEC;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_LOCAL_EXEC);
|
||||
cmd->retry = 1;
|
||||
res = 1;
|
||||
goto out;
|
||||
@@ -4206,7 +4148,7 @@ next:
|
||||
(cmd->cdb[0] == LOG_SELECT))) {
|
||||
TRACE(TRACE_SCSI, "MODE/LOG SELECT succeeded (LUN %lld)",
|
||||
(unsigned long long int)cmd->lun);
|
||||
cmd->state = SCST_CMD_STATE_MODE_SELECT_CHECKS;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_MODE_SELECT_CHECKS);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
@@ -4219,12 +4161,12 @@ next:
|
||||
0, 0x2a, 0x01)) {
|
||||
TRACE(TRACE_SCSI, "MODE PARAMETERS CHANGED UA (lun "
|
||||
"%lld)", (unsigned long long int)cmd->lun);
|
||||
cmd->state = SCST_CMD_STATE_MODE_SELECT_CHECKS;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_MODE_SELECT_CHECKS);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
cmd->state = SCST_CMD_STATE_DEV_DONE;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_DEV_DONE);
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
@@ -4309,7 +4251,7 @@ static int scst_mode_select_checks(struct scst_cmd *cmd)
|
||||
} else
|
||||
sBUG();
|
||||
|
||||
cmd->state = SCST_CMD_STATE_DEV_DONE;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_DEV_DONE);
|
||||
|
||||
out:
|
||||
TRACE_EXIT_HRES(res);
|
||||
@@ -4344,9 +4286,7 @@ static int scst_dev_done(struct scst_cmd *cmd)
|
||||
|
||||
TRACE_DBG("Calling dev handler %s dev_done(%p)",
|
||||
devt->name, cmd);
|
||||
scst_set_cur_start(cmd);
|
||||
rc = devt->dev_done(cmd);
|
||||
scst_set_dev_done_time(cmd);
|
||||
TRACE_DBG("Dev handler %s dev_done() returned %d",
|
||||
devt->name, rc);
|
||||
if (rc != SCST_CMD_STATE_DEFAULT)
|
||||
@@ -4374,7 +4314,7 @@ static int scst_dev_done(struct scst_cmd *cmd)
|
||||
#else
|
||||
default:
|
||||
#endif
|
||||
cmd->state = state;
|
||||
scst_set_cmd_state(cmd, state);
|
||||
break;
|
||||
case SCST_CMD_STATE_NEED_THREAD_CTX:
|
||||
TRACE_DBG("Dev handler %s dev_done() requested "
|
||||
@@ -4409,7 +4349,7 @@ static int scst_dev_done(struct scst_cmd *cmd)
|
||||
}
|
||||
|
||||
if (unlikely(cmd->internal))
|
||||
cmd->state = SCST_CMD_STATE_FINISHED_INTERNAL;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_FINISHED_INTERNAL);
|
||||
|
||||
#ifndef CONFIG_SCST_TEST_IO_IN_SIRQ
|
||||
#ifdef CONFIG_SCST_EXTRACHECKS
|
||||
@@ -4508,7 +4448,7 @@ again:
|
||||
EXTRACHECKS_BUG_ON(!test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags));
|
||||
TRACE_MGMT_DBG("Flag NO_RESP set for cmd %p (tag %llu), "
|
||||
"skipping", cmd, (unsigned long long int)cmd->tag);
|
||||
cmd->state = SCST_CMD_STATE_FINISHED;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_FINISHED);
|
||||
goto out_same;
|
||||
}
|
||||
|
||||
@@ -4517,7 +4457,7 @@ again:
|
||||
else
|
||||
cmd->adjusted_resp_data_len = cmd->resp_data_len;
|
||||
|
||||
cmd->state = SCST_CMD_STATE_XMIT_RESP;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_XMIT_RESP);
|
||||
|
||||
out_same:
|
||||
res = SCST_CMD_STATE_RES_CONT_SAME;
|
||||
@@ -4576,7 +4516,7 @@ static int scst_pre_xmit_response1(struct scst_cmd *cmd)
|
||||
cmd->done = 1;
|
||||
smp_mb(); /* to sync with scst_abort_cmd() */
|
||||
|
||||
cmd->state = SCST_CMD_STATE_PRE_XMIT_RESP2;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_PRE_XMIT_RESP2);
|
||||
res = scst_pre_xmit_response2(cmd);
|
||||
|
||||
TRACE_EXIT_RES(res);
|
||||
@@ -4605,7 +4545,7 @@ static int scst_xmit_response(struct scst_cmd *cmd)
|
||||
}
|
||||
|
||||
res = SCST_CMD_STATE_RES_CONT_NEXT;
|
||||
cmd->state = SCST_CMD_STATE_XMIT_WAIT;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_XMIT_WAIT);
|
||||
|
||||
TRACE_DBG("Calling xmit_response(%p)", cmd);
|
||||
|
||||
@@ -4653,8 +4593,6 @@ static int scst_xmit_response(struct scst_cmd *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
scst_set_cur_start(cmd);
|
||||
|
||||
#ifdef CONFIG_SCST_DEBUG_RETRY
|
||||
if (((scst_random() % 100) == 77))
|
||||
rc = SCST_TGT_RES_QUEUE_FULL;
|
||||
@@ -4666,12 +4604,10 @@ static int scst_xmit_response(struct scst_cmd *cmd)
|
||||
if (likely(rc == SCST_TGT_RES_SUCCESS))
|
||||
goto out;
|
||||
|
||||
scst_set_xmit_time(cmd);
|
||||
|
||||
cmd->cmd_hw_pending = 0;
|
||||
|
||||
/* Restore the previous state */
|
||||
cmd->state = SCST_CMD_STATE_XMIT_RESP;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_XMIT_RESP);
|
||||
|
||||
switch (rc) {
|
||||
case SCST_TGT_RES_QUEUE_FULL:
|
||||
@@ -4694,7 +4630,7 @@ static int scst_xmit_response(struct scst_cmd *cmd)
|
||||
"invalid value %d", tgtt->name, rc);
|
||||
}
|
||||
scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
|
||||
cmd->state = SCST_CMD_STATE_FINISHED;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_FINISHED);
|
||||
res = SCST_CMD_STATE_RES_CONT_SAME;
|
||||
goto out;
|
||||
}
|
||||
@@ -4724,14 +4660,12 @@ void scst_tgt_cmd_done(struct scst_cmd *cmd,
|
||||
|
||||
sBUG_ON(cmd->state != SCST_CMD_STATE_XMIT_WAIT);
|
||||
|
||||
scst_set_xmit_time(cmd);
|
||||
|
||||
cmd->cmd_hw_pending = 0;
|
||||
|
||||
if (unlikely(cmd->tgt_dev == NULL))
|
||||
pref_context = SCST_CONTEXT_THREAD;
|
||||
|
||||
cmd->state = SCST_CMD_STATE_FINISHED;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_FINISHED);
|
||||
|
||||
scst_process_redirect_cmd(cmd, pref_context, 1);
|
||||
|
||||
@@ -4750,8 +4684,6 @@ static int scst_finish_cmd(struct scst_cmd *cmd)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
scst_update_lat_stats(cmd);
|
||||
|
||||
if (unlikely(cmd->delivery_status != SCST_CMD_DELIVERY_SUCCESS)) {
|
||||
if ((cmd->tgt_dev != NULL) &&
|
||||
(cmd->status == SAM_STAT_CHECK_CONDITION) &&
|
||||
@@ -5117,7 +5049,7 @@ static int __scst_init_cmd(struct scst_cmd *cmd)
|
||||
|
||||
order_data = cmd->cur_order_data;
|
||||
|
||||
cmd->state = SCST_CMD_STATE_PARSE;
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_PARSE);
|
||||
|
||||
cnt = atomic_inc_return(&cmd->tgt_dev->tgt_dev_cmd_count);
|
||||
if (unlikely(cnt > cmd->dev->max_tgt_dev_commands)) {
|
||||
|
||||
Reference in New Issue
Block a user