mirror of
https://github.com/SCST-project/scst.git
synced 2026-09-28 10:45:39 +00:00
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:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user