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:
Vladislav Bolkhovitin
2009-09-29 20:30:17 +00:00
parent 7a0239179d
commit 21aeb806ff
4 changed files with 142 additions and 10 deletions

View File

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

View File

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

View File

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

View File

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