mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-23 21:51:27 +00:00
Per sessions commands stats implemented based on patch from Steven Umbehocker <steven.umbehocker@osnexus.com>
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3218 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1522,6 +1522,11 @@ struct scst_ext_latency_stat {
|
||||
|
||||
#endif /* CONFIG_SCST_MEASURE_LATENCY */
|
||||
|
||||
struct scst_io_stat_entry {
|
||||
uint64_t cmd_count;
|
||||
uint64_t io_byte_count;
|
||||
};
|
||||
|
||||
/*
|
||||
* SCST session, analog of SCSI I_T nexus
|
||||
*/
|
||||
@@ -1568,6 +1573,9 @@ struct scst_session {
|
||||
*/
|
||||
atomic_t sess_cmd_count;
|
||||
|
||||
/* Some statistics. Protected by sess_list_lock. */
|
||||
struct scst_io_stat_entry io_stats[SCST_DATA_DIR_MAX];
|
||||
|
||||
/* Access control for this session and list entry there */
|
||||
struct scst_acg *acg;
|
||||
|
||||
|
||||
@@ -186,7 +186,7 @@ enum scst_cdb_flags {
|
||||
|
||||
/*************************************************************
|
||||
** Data direction aliases. Changing it don't forget to change
|
||||
** scst_to_tgt_dma_dir as well!!
|
||||
** scst_to_tgt_dma_dir and SCST_DATA_DIR_MAX as well!!
|
||||
*************************************************************/
|
||||
#define SCST_DATA_UNKNOWN 0
|
||||
#define SCST_DATA_WRITE 1
|
||||
@@ -194,6 +194,8 @@ enum scst_cdb_flags {
|
||||
#define SCST_DATA_BIDI (SCST_DATA_WRITE | SCST_DATA_READ)
|
||||
#define SCST_DATA_NONE 4
|
||||
|
||||
#define SCST_DATA_DIR_MAX (SCST_DATA_NONE+1)
|
||||
|
||||
#ifdef CONFIG_SCST_PROC
|
||||
|
||||
/*************************************************************
|
||||
|
||||
@@ -3400,10 +3400,69 @@ static struct kobj_attribute session_initiator_name_attr =
|
||||
__ATTR(initiator_name, S_IRUGO, scst_sess_sysfs_initiator_name_show,
|
||||
NULL);
|
||||
|
||||
#define SCST_SESS_SYSFS_STAT_ATTR(name, exported_name, dir, kb) \
|
||||
static ssize_t scst_sess_sysfs_##exported_name##_show(struct kobject *kobj, \
|
||||
struct kobj_attribute *attr, char *buf) \
|
||||
{ \
|
||||
struct scst_session *sess; \
|
||||
int res; \
|
||||
uint64_t v; \
|
||||
\
|
||||
BUILD_BUG_ON(SCST_DATA_UNKNOWN != 0); \
|
||||
BUILD_BUG_ON(SCST_DATA_WRITE != 1); \
|
||||
BUILD_BUG_ON(SCST_DATA_READ != 2); \
|
||||
BUILD_BUG_ON(SCST_DATA_BIDI != 3); \
|
||||
BUILD_BUG_ON(SCST_DATA_NONE != 4); \
|
||||
\
|
||||
BUILD_BUG_ON(dir >= SCST_DATA_DIR_MAX); \
|
||||
\
|
||||
sess = container_of(kobj, struct scst_session, sess_kobj); \
|
||||
v = sess->io_stats[dir].name; \
|
||||
if (kb) \
|
||||
v >>= 10; \
|
||||
res = sprintf(buf, "%llu\n", (unsigned long long)v); \
|
||||
return res; \
|
||||
} \
|
||||
\
|
||||
static ssize_t scst_sess_sysfs_##exported_name##_store(struct kobject *kobj, \
|
||||
struct kobj_attribute *attr, const char *buf, size_t count) \
|
||||
{ \
|
||||
struct scst_session *sess; \
|
||||
sess = container_of(kobj, struct scst_session, sess_kobj); \
|
||||
spin_lock_irq(&sess->sess_list_lock); \
|
||||
BUILD_BUG_ON(dir >= SCST_DATA_DIR_MAX); \
|
||||
sess->io_stats[dir].cmd_count = 0; \
|
||||
sess->io_stats[dir].io_byte_count = 0; \
|
||||
spin_unlock_irq(&sess->sess_list_lock); \
|
||||
return count; \
|
||||
} \
|
||||
\
|
||||
static struct kobj_attribute session_##exported_name##_attr = \
|
||||
__ATTR(exported_name, S_IRUGO | S_IWUSR, \
|
||||
scst_sess_sysfs_##exported_name##_show, \
|
||||
scst_sess_sysfs_##exported_name##_store);
|
||||
|
||||
SCST_SESS_SYSFS_STAT_ATTR(cmd_count, unknown_cmd_count, SCST_DATA_UNKNOWN, 0);
|
||||
SCST_SESS_SYSFS_STAT_ATTR(cmd_count, write_cmd_count, SCST_DATA_WRITE, 0);
|
||||
SCST_SESS_SYSFS_STAT_ATTR(io_byte_count, write_io_count_kb, SCST_DATA_WRITE, 1);
|
||||
SCST_SESS_SYSFS_STAT_ATTR(cmd_count, read_cmd_count, SCST_DATA_READ, 0);
|
||||
SCST_SESS_SYSFS_STAT_ATTR(io_byte_count, read_io_count_kb, SCST_DATA_READ, 1);
|
||||
SCST_SESS_SYSFS_STAT_ATTR(cmd_count, bidi_cmd_count, SCST_DATA_BIDI, 0);
|
||||
SCST_SESS_SYSFS_STAT_ATTR(io_byte_count, bidi_io_count_kb, SCST_DATA_BIDI, 1);
|
||||
SCST_SESS_SYSFS_STAT_ATTR(cmd_count, none_cmd_count, SCST_DATA_NONE, 0);
|
||||
|
||||
static struct attribute *scst_session_attrs[] = {
|
||||
&session_commands_attr.attr,
|
||||
&session_active_commands_attr.attr,
|
||||
&session_initiator_name_attr.attr,
|
||||
&session_unknown_cmd_count_attr.attr,
|
||||
&session_write_cmd_count_attr.attr,
|
||||
&session_write_io_count_kb_attr.attr,
|
||||
&session_read_cmd_count_attr.attr,
|
||||
&session_read_io_count_kb_attr.attr,
|
||||
&session_bidi_cmd_count_attr.attr,
|
||||
&session_bidi_io_count_kb_attr.attr,
|
||||
&session_none_cmd_count_attr.attr,
|
||||
#ifdef CONFIG_SCST_MEASURE_LATENCY
|
||||
&session_latency_attr.attr,
|
||||
#endif /* CONFIG_SCST_MEASURE_LATENCY */
|
||||
|
||||
@@ -3565,6 +3565,7 @@ static int scst_finish_cmd(struct scst_cmd *cmd)
|
||||
{
|
||||
int res;
|
||||
struct scst_session *sess = cmd->sess;
|
||||
struct scst_io_stat_entry *stat;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -3588,7 +3589,13 @@ static int scst_finish_cmd(struct scst_cmd *cmd)
|
||||
atomic_dec(&sess->sess_cmd_count);
|
||||
|
||||
spin_lock_irq(&sess->sess_list_lock);
|
||||
|
||||
stat = &sess->io_stats[cmd->data_direction];
|
||||
stat->cmd_count++;
|
||||
stat->io_byte_count += cmd->bufflen + cmd->out_bufflen;
|
||||
|
||||
list_del(&cmd->sess_cmd_list_entry);
|
||||
|
||||
spin_unlock_irq(&sess->sess_list_lock);
|
||||
|
||||
cmd->finished = 1;
|
||||
|
||||
Reference in New Issue
Block a user