scst: Add a new latency measurement infrastructure

An example of the data produced by this infrastructure:

$ echo 1 >/sys/kernel/scst_tgt/measure_latency
$ sleep 10 # Wait until an initiator has submitted multiple I/O requests
$ cat /sys/kernel/scst_tgt/targets/ib_srpt/fe80\:0000\:0000\:0000\:0002\:c903\:00fa\:b7f2/sessions/fe80\:0000\:0000\:0000\:0002\:c903\:00a3\:4272/latency/r512
state count min max avg stddev
PARSE 219 1.3 26.6 2.2 2.5 us
PREPARE_SPACE 219 0.9 10.3 1.1 0.6 us
RDY_TO_XFER 219 0.7 1.7 0.7 0.2 us
TGT_PRE_EXEC 219 0.7 11.0 0.8 0.9 us
EXEC_CHECK_SN 219 0.7 1.7 0.8 0.2 us
PRE_DEV_DONE 219 11.3 3445.7 39.6 276.4 us
DEV_DONE 219 0.7 11.0 0.9 0.7 us
PRE_XMIT_RESP1 219 1.2 58.4 1.6 3.8 us
CSW2 219 0.7 1.6 0.8 0.1 us
PRE_XMIT_RESP2 219 0.7 1.5 0.7 0.1 us
XMIT_RESP 219 0.7 1.5 0.7 0.1 us
INIT_WAIT 219 1.0 57.3 2.1 4.4 us
INIT 219 0.9 27.4 1.6 2.4 us
CSW1 219 15.0 3856.1 74.2 264.8 us
EXEC_CHECK_BLOCKING 219 1.3 10.8 1.7 0.9 us
LOCAL_EXEC 219 0.7 1.8 0.7 0.1 us
REAL_EXEC 219 0.6 1.5 0.7 0.1 us
EXEC_WAIT 219 40.6 1021.7 54.4 68.7 us
XMIT_WAIT 219 6.4 1682.0 50.6 228.1 us
total 219 - - 236.9 2012.1 us


git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7484 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Bart Van Assche
2018-09-27 04:09:27 +00:00
parent 8e454788bd
commit 5f1cf8cf1d
7 changed files with 579 additions and 1 deletions
+50
View File
@@ -29,6 +29,7 @@
#include <linux/slab.h> /* kmalloc() */
#include <linux/timer.h>
#include <linux/version.h>
#include <linux/vmalloc.h>
#include <linux/writeback.h> /* sync_page_range() */
#include <rdma/ib_verbs.h>
#include <scsi/scsi_cmnd.h> /* struct scsi_cmnd */
@@ -63,6 +64,24 @@
#endif
#endif
/* <asm/msr.h> */
#ifdef CONFIG_X86
#include <asm/msr.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
static __always_inline unsigned long long rdtsc(void)
{
return native_read_tsc();
}
#endif
#else
static __always_inline unsigned long long rdtsc(void)
{
return 0;
}
#define tsc_khz 1000
#endif
/* <linux/bio.h> */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)
@@ -378,6 +397,23 @@ static inline int __must_check kstrtol(const char *s, unsigned int base,
}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0)
/* Suboptimal algorithm for computing the square root of a 64-bit number */
static inline u32 int_sqrt64(u64 x)
{
u32 r = 0, s;
int i;
for (i = 8 * sizeof(r) - 2; i >= 0;i --) {
s = r + (1 << i);
if (1ll * s * s <= x)
r = s;
}
return r;
}
#endif
/* <linux/kmod.h> */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
@@ -811,6 +847,20 @@ static inline void put_unaligned_be64(uint64_t i, void *p)
}
#endif
/* <linux/vmalloc.h> */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
static inline void *vzalloc(size_t size)
{
void *p;
p = vmalloc(size);
if (p)
memset(p, 0, size);
return p;
}
#endif
/* <scsi/scsi_cmnd.h> */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
+69
View File
@@ -149,6 +149,8 @@ enum scst_cmd_state {
/* Checks 1 before target driver's xmit_response() is called */
SCST_CMD_STATE_PRE_XMIT_RESP1,
SCST_CMD_STATE_CSW2,
/* Checks 2 before target driver's xmit_response() is called */
SCST_CMD_STATE_PRE_XMIT_RESP2,
@@ -172,6 +174,8 @@ enum scst_cmd_state {
/* LUN translation (cmd->tgt_dev assignment) */
SCST_CMD_STATE_INIT,
SCST_CMD_STATE_CSW1,
/* Waiting for scst_restart_cmd() */
SCST_CMD_STATE_PREPROCESSING_DONE_CALLED,
@@ -197,6 +201,10 @@ enum scst_cmd_state {
SCST_CMD_STATE_XMIT_WAIT,
};
enum {
SCST_CMD_STATE_COUNT = SCST_CMD_STATE_XMIT_WAIT + 1
};
/*************************************************************
* Can be returned instead of cmd's state by dev handlers'
* functions, if the command's state should be set by default
@@ -1844,6 +1852,57 @@ struct scst_tgt {
#endif
};
/**
* struct scst_lat_stat_entry - SCST command processing latency data
* @last_update: Time of last update of this data structure in 100 ns.
* @count: Number of samples for which statistics have been gathered.
* @last_update_tsc: Time of the last update of this data structure in 100
* clock cycles.
* @min: Minimum processing time in nanoseconds.
* @max: Maximum processing time.
* @sum: Processing time sum.
* @sumsq: Sum of the squares of the processing times.
* @minc, @maxc, @sumc, @sumsqc: Similar to the above but in hundred clock
* cycles instead of nanoseconds.
*
* Time unit for the uint64_t numbers: 100 ns.
*
* Size: 96 bytes.
*/
struct scst_lat_stat_entry {
ktime_t last_update;
uint32_t count;
uint32_t padding;
#ifdef SCST_MEASURE_CLOCK_CYCLES
uint64_t last_update_tsc;
#endif
uint64_t min;
uint64_t max;
uint64_t sum;
uint64_t sumsq;
#ifdef SCST_MEASURE_CLOCK_CYCLES
uint64_t minc;
uint64_t maxc;
uint64_t sumc;
uint64_t sumsqc;
#endif
};
/*
* lat_stats is an array with three indices:
* - Logarithm base 2 of the data length minus 9.
* - Data direction (SCST_DATA_*).
* - SCST command state.
*
* Size: 11 * 4 * 25 * 96 = 105600 bytes.
*/
#define SCST_STATS_LOG2_SZ_OFFSET 9
#define SCST_STATS_MAX_LOG2_SZ 11
struct scst_lat_stats {
struct scst_lat_stat_entry
ls[SCST_STATS_MAX_LOG2_SZ][4][SCST_CMD_STATE_COUNT];
};
struct scst_io_stat_entry {
uint64_t cmd_count;
uint64_t io_byte_count;
@@ -1971,6 +2030,7 @@ struct scst_session {
unsigned int sess_kobj_ready:1;
struct kobject sess_kobj; /* session sysfs entry */
struct kobject *lat_kobj;
#endif
/*
@@ -1981,6 +2041,12 @@ struct scst_session {
void (*init_result_fn)(struct scst_session *sess, void *data,
int result);
void (*unreg_done_fn)(struct scst_session *sess);
/*
* Latency measurement data.
*/
spinlock_t lat_stats_lock;
struct scst_lat_stats *lat_stats;
};
/*
@@ -2318,6 +2384,9 @@ struct scst_cmd {
unsigned long start_time;
ktime_t init_wait_time;
uint64_t init_wait_tsc;
/* List entry for tgt_dev's deferred (SN, ACA, etc.) lists */
struct list_head deferred_cmd_list_entry;