mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-14 09:11:27 +00:00
scst: Remove the existing latency measurement infrastructure
Remove the existing latency measurement infrastructure since it will be replaced by a new and more powerful latency measurement infrastructure. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7481 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -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 \
|
||||
|
||||
10
scst/README
10
scst/README
@@ -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:
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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 */
|
||||
@@ -1848,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;
|
||||
@@ -2030,15 +1981,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
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -2592,16 +2534,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;
|
||||
@@ -3267,15 +3199,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
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -5270,9 +5193,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:
|
||||
|
||||
@@ -5692,8 +5692,6 @@ 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));
|
||||
|
||||
@@ -6395,8 +6393,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;
|
||||
@@ -6967,10 +6963,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");
|
||||
@@ -15675,299 +15667,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 */
|
||||
|
||||
@@ -2595,26 +2595,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))
|
||||
|
||||
@@ -1020,38 +1020,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 */
|
||||
|
||||
@@ -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,339 +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);
|
||||
}
|
||||
|
||||
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(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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(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));
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -818,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;
|
||||
}
|
||||
@@ -844,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;
|
||||
}
|
||||
|
||||
@@ -4128,117 +4128,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)
|
||||
@@ -4337,9 +4226,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,
|
||||
};
|
||||
|
||||
@@ -4427,241 +4313,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();
|
||||
|
||||
res = mutex_lock_interruptible(&scst_mutex);
|
||||
if (res != 0)
|
||||
goto out_put;
|
||||
|
||||
PRINT_INFO("Zeroing latency statistics for initiator "
|
||||
"%s", sess->initiator_name);
|
||||
|
||||
spin_lock_bh(&sess->lat_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(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));
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_bh(&sess->lat_lock);
|
||||
|
||||
mutex_unlock(&scst_mutex);
|
||||
|
||||
out_put:
|
||||
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)
|
||||
{
|
||||
@@ -5005,9 +4656,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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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)",
|
||||
@@ -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);
|
||||
|
||||
@@ -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,8 +1497,6 @@ 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;
|
||||
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) {
|
||||
@@ -1658,7 +1620,6 @@ static int scst_preprocessing_done(struct scst_cmd *cmd)
|
||||
cmd->state = 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),
|
||||
@@ -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,8 +1792,6 @@ 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 */
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
cmd->status = result & 0xff;
|
||||
cmd->msg_status = msg_byte(result);
|
||||
cmd->host_status = host_byte(result);
|
||||
@@ -2263,8 +2212,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,
|
||||
@@ -3480,7 +3427,6 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
|
||||
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);
|
||||
@@ -3488,8 +3434,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);
|
||||
}
|
||||
|
||||
@@ -3506,8 +3450,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,
|
||||
@@ -4354,9 +4296,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)
|
||||
@@ -4662,8 +4602,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;
|
||||
@@ -4675,8 +4613,6 @@ 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 */
|
||||
@@ -4733,8 +4669,6 @@ 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))
|
||||
@@ -4759,8 +4693,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) &&
|
||||
|
||||
Reference in New Issue
Block a user