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:
Bart Van Assche
2018-09-27 02:25:43 +00:00
parent 2231b598c6
commit f1357f410e
13 changed files with 3 additions and 1242 deletions

View File

@@ -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 \

View File

@@ -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:

View File

@@ -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:

View File

@@ -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);
/**

View File

@@ -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"

View File

@@ -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);

View File

@@ -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:

View File

@@ -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 */

View File

@@ -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))

View File

@@ -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 */

View File

@@ -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;
}

View File

@@ -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,
};

View File

@@ -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) &&