mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-20 12:11:26 +00:00
Patch from Smadar Gonen <smadar.gn@gmail.com> implementing extended latency statistics.
Intermediate commit, don't use it! git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1156 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1029,6 +1029,31 @@ struct scst_tgt {
|
||||
#define TGT_DEV_HASH_SIZE (1 << TGT_DEV_HASH_SHIFT)
|
||||
#define HASH_VAL(_val) (_val & (TGT_DEV_HASH_SIZE - 1))
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY_EXT
|
||||
/*define the structure for extended latency statistics*/
|
||||
struct scst_latency_stat {
|
||||
uint64_t scst_time_wr;
|
||||
uint64_t scst_time_rd;
|
||||
uint64_t processing_time_wr;
|
||||
uint64_t processing_time_rd;
|
||||
unsigned int processed_cmds_wr;
|
||||
unsigned int processed_cmds_rd;
|
||||
};
|
||||
|
||||
#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_NUM_OF_THRESHOLDS 5
|
||||
|
||||
#endif
|
||||
|
||||
struct scst_session {
|
||||
/*
|
||||
* Initialization phase, one of SCST_SESS_IPH_* constants, protected by
|
||||
@@ -1128,6 +1153,9 @@ struct scst_session {
|
||||
spinlock_t meas_lock;
|
||||
uint64_t scst_time, processing_time;
|
||||
unsigned int processed_cmds;
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY_EXT
|
||||
struct scst_latency_stat latency_stat[SCST_LATENCY_NUM_OF_THRESHOLDS];
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG_SN
|
||||
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_MEASURE_LATENCY
|
||||
#EXTRA_CFLAGS += -DCONFIG_SCST_MEASURE_LATENCY_EXT
|
||||
|
||||
# If defined, makes SCST zero allocated data buffers.
|
||||
# Undefining it considerably improves performance and eases CPU load,
|
||||
|
||||
@@ -412,6 +412,14 @@ out:
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY_EXT
|
||||
static char *scst_io_size_names[] = { "<=8K ",
|
||||
"<=32K ",
|
||||
"<=128K",
|
||||
"<=512K",
|
||||
">512K " };
|
||||
#endif
|
||||
|
||||
static int lat_info_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
int res = 0;
|
||||
@@ -425,10 +433,10 @@ static int lat_info_show(struct seq_file *seq, void *v)
|
||||
goto out;
|
||||
}
|
||||
|
||||
seq_printf(seq, "%-20s %-45s %-15s %15s\n",
|
||||
"Target name",
|
||||
"Initiator name",
|
||||
"SCST latency",
|
||||
seq_printf(seq, "%-30s %-15s %-15s %-15s\n",
|
||||
"T-L names",
|
||||
"Total commands",
|
||||
"SCST latenct",
|
||||
"Processing latency (ns)");
|
||||
|
||||
list_for_each_entry(acg, &scst_acg_list, scst_acg_list_entry) {
|
||||
@@ -437,8 +445,51 @@ static int lat_info_show(struct seq_file *seq, void *v)
|
||||
unsigned long proc_lat = 0, scst_lat = 0;
|
||||
uint64_t proc_time, scst_time;
|
||||
unsigned int processed_cmds;
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY_EXT
|
||||
uint64_t proc_time_rd, scst_time_rd;
|
||||
unsigned int processed_cmds_rd;
|
||||
unsigned int i;
|
||||
struct scst_latency_stat *latency_stat;
|
||||
#endif
|
||||
|
||||
seq_printf(seq,
|
||||
"Target name: %s \nInitiator name: %s\n",
|
||||
sess->tgt->tgtt->name,
|
||||
sess->initiator_name);
|
||||
|
||||
spin_lock_bh(&sess->meas_lock);
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY_EXT
|
||||
for (i = 0; i <= SCST_LATENCY_STAT_INDEX_OTHER ; i++) {
|
||||
latency_stat = &sess->latency_stat[i];
|
||||
proc_time =
|
||||
latency_stat->processing_time_wr;
|
||||
proc_time_rd =
|
||||
latency_stat->processing_time_rd;
|
||||
scst_time =
|
||||
latency_stat->scst_time_wr;
|
||||
scst_time_rd =
|
||||
latency_stat->scst_time_rd;
|
||||
processed_cmds =
|
||||
latency_stat->processed_cmds_wr;
|
||||
processed_cmds_rd =
|
||||
latency_stat->processed_cmds_rd;
|
||||
|
||||
seq_printf(seq,
|
||||
"%-5s %-24s %-15ld %-15ld %-15ld\n",
|
||||
"Write",
|
||||
scst_io_size_names[i],
|
||||
(unsigned long)processed_cmds,
|
||||
(unsigned long)scst_time,
|
||||
(unsigned long)proc_time);
|
||||
seq_printf(seq,
|
||||
"%-5s %-24s %-15ld %-15ld %-15ld\n",
|
||||
"Read",
|
||||
scst_io_size_names[i],
|
||||
(unsigned long)processed_cmds_rd,
|
||||
(unsigned long)scst_time_rd,
|
||||
(unsigned long)proc_time_rd);
|
||||
}
|
||||
#endif
|
||||
proc_time = sess->processing_time;
|
||||
scst_time = sess->scst_time;
|
||||
processed_cmds = sess->processed_cmds;
|
||||
@@ -459,17 +510,19 @@ static int lat_info_show(struct seq_file *seq, void *v)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sess->processed_cmds != 0) {
|
||||
if (processed_cmds != 0) {
|
||||
proc_lat = (unsigned long)proc_time /
|
||||
processed_cmds;
|
||||
scst_lat = (unsigned long)scst_time /
|
||||
processed_cmds;
|
||||
}
|
||||
|
||||
seq_printf(seq, "%-20s %-45s %-15ld %-15ld\n",
|
||||
sess->tgt->tgtt->name,
|
||||
sess->initiator_name,
|
||||
scst_lat, proc_lat);
|
||||
seq_printf(seq,
|
||||
"%-30s %-15d %-15ld %-15ld\n\n",
|
||||
"Average",
|
||||
processed_cmds,
|
||||
scst_lat,
|
||||
proc_lat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,6 +558,11 @@ static ssize_t scst_proc_scsi_tgt_gen_write_lat(struct file *file,
|
||||
sess->processing_time = 0;
|
||||
sess->scst_time = 0;
|
||||
sess->processed_cmds = 0;
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY_EXT
|
||||
memset(sess->latency_stat,
|
||||
0,
|
||||
sizeof(sess->latency_stat));
|
||||
#endif
|
||||
spin_unlock_bh(&sess->meas_lock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2938,20 +2938,65 @@ out:
|
||||
{
|
||||
struct timespec ts;
|
||||
uint64_t finish, scst_time, proc_time;
|
||||
struct scst_session *sess = cmd->sess;
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY_EXT
|
||||
int data_len;
|
||||
int i;
|
||||
struct scst_latency_stat *latency_stat;
|
||||
#endif
|
||||
ktime_get_ts(&ts);
|
||||
finish = scst_sec_to_nsec(ts.tv_sec) + ts.tv_nsec;
|
||||
|
||||
spin_lock_bh(&sess->meas_lock);
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY_EXT
|
||||
/* Determine the IO size for extended latency statistics*/
|
||||
data_len = cmd->data_len;
|
||||
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->latency_stat[i];
|
||||
#endif
|
||||
|
||||
spin_lock_bh(&sess->meas_lock);
|
||||
/* Calculate the latencies */
|
||||
scst_time = cmd->pre_exec_finish - cmd->start;
|
||||
scst_time += finish - cmd->post_exec_start;
|
||||
proc_time = finish - cmd->start;
|
||||
|
||||
/* Save the basic latency information */
|
||||
sess->scst_time += scst_time;
|
||||
sess->processing_time += proc_time;
|
||||
sess->processed_cmds++;
|
||||
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY_EXT
|
||||
/* Save the extended latency information */
|
||||
switch (cmd->cdb[0]) {
|
||||
case READ_6:
|
||||
case READ_10:
|
||||
case READ_12:
|
||||
latency_stat->scst_time_rd += scst_time;
|
||||
latency_stat->processing_time_rd += proc_time;
|
||||
latency_stat->processed_cmds_rd++;
|
||||
break;
|
||||
case WRITE_6:
|
||||
case WRITE_10:
|
||||
case WRITE_12:
|
||||
case WRITE_VERIFY:
|
||||
case WRITE_VERIFY_12:
|
||||
latency_stat->scst_time_wr += scst_time;
|
||||
latency_stat->processing_time_wr += proc_time;
|
||||
latency_stat->processed_cmds_wr++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
spin_unlock_bh(&sess->meas_lock);
|
||||
|
||||
TRACE_DBG("cmd %p (sess %p): finish %lld (tv_sec %ld, "
|
||||
|
||||
Reference in New Issue
Block a user