mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-23 13:41:27 +00:00
[PATCH 2/2] scst_sysfs: Add I/O statistics per target
Although it is possible to obtain these statistics by iterating over all sessions and by computing the sum of the per-target statistics, make per-target statistics directly available such that these can be retrieved easily. Signed-off-by: Bart Van Assche <bvanassche@acm.org> git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@5249 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -2400,12 +2400,88 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL(scst_create_tgt_attr);
|
||||
|
||||
#define SCST_TGT_SYSFS_STAT_ATTR(member_name, attr, dir, result_op) \
|
||||
static int scst_tgt_sysfs_##attr##_show_work_fn( \
|
||||
struct scst_sysfs_work_item *work) \
|
||||
{ \
|
||||
struct scst_tgt *tgt = work->tgt; \
|
||||
struct scst_session *sess; \
|
||||
int res; \
|
||||
uint64_t c = 0; \
|
||||
\
|
||||
BUILD_BUG_ON((unsigned)(dir) >= ARRAY_SIZE(sess->io_stats)); \
|
||||
\
|
||||
res = mutex_lock_interruptible(&scst_mutex); \
|
||||
if (res) \
|
||||
goto out; \
|
||||
list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) \
|
||||
c += sess->io_stats[(dir)].member_name; \
|
||||
mutex_unlock(&scst_mutex); \
|
||||
\
|
||||
work->res_buf = kasprintf(GFP_KERNEL, "%llu\n", c result_op); \
|
||||
res = work->res_buf ? 0 : -ENOMEM; \
|
||||
\
|
||||
out: \
|
||||
kobject_put(&tgt->tgt_kobj); \
|
||||
return res; \
|
||||
} \
|
||||
\
|
||||
static ssize_t scst_tgt_sysfs_##attr##_show(struct kobject *kobj, \
|
||||
struct kobj_attribute *attr, \
|
||||
char *buf) \
|
||||
{ \
|
||||
struct scst_tgt *tgt = \
|
||||
container_of(kobj, struct scst_tgt, tgt_kobj); \
|
||||
struct scst_sysfs_work_item *work; \
|
||||
int res; \
|
||||
\
|
||||
res = scst_alloc_sysfs_work(scst_tgt_sysfs_##attr##_show_work_fn, \
|
||||
true, &work); \
|
||||
if (res) \
|
||||
goto out; \
|
||||
\
|
||||
work->tgt = tgt; \
|
||||
SCST_SET_DEP_MAP(work, &scst_tgt_dep_map); \
|
||||
kobject_get(&tgt->tgt_kobj); \
|
||||
scst_sysfs_work_get(work); \
|
||||
res = scst_sysfs_queue_wait_work(work); \
|
||||
if (res == 0) \
|
||||
res = scnprintf(buf, PAGE_SIZE, "%s", work->res_buf); \
|
||||
scst_sysfs_work_put(work); \
|
||||
\
|
||||
out: \
|
||||
return res; \
|
||||
} \
|
||||
\
|
||||
static struct kobj_attribute scst_tgt_##attr##_attr = \
|
||||
__ATTR(attr, S_IRUGO, scst_tgt_sysfs_##attr##_show, NULL);
|
||||
|
||||
SCST_TGT_SYSFS_STAT_ATTR(cmd_count, unknown_cmd_count, SCST_DATA_UNKNOWN, >> 0);
|
||||
SCST_TGT_SYSFS_STAT_ATTR(cmd_count, write_cmd_count, SCST_DATA_WRITE, >> 0);
|
||||
SCST_TGT_SYSFS_STAT_ATTR(io_byte_count, write_io_count_kb, SCST_DATA_WRITE,
|
||||
>> 10);
|
||||
SCST_TGT_SYSFS_STAT_ATTR(cmd_count, read_cmd_count, SCST_DATA_READ, >> 0);
|
||||
SCST_TGT_SYSFS_STAT_ATTR(io_byte_count, read_io_count_kb, SCST_DATA_READ,
|
||||
>> 10);
|
||||
SCST_TGT_SYSFS_STAT_ATTR(cmd_count, bidi_cmd_count, SCST_DATA_BIDI, >> 0);
|
||||
SCST_TGT_SYSFS_STAT_ATTR(io_byte_count, bidi_io_count_kb, SCST_DATA_BIDI,
|
||||
>> 10);
|
||||
SCST_TGT_SYSFS_STAT_ATTR(cmd_count, none_cmd_count, SCST_DATA_NONE, >> 0);
|
||||
|
||||
static struct attribute *scst_tgt_attrs[] = {
|
||||
&scst_rel_tgt_id.attr,
|
||||
&scst_tgt_comment.attr,
|
||||
&scst_tgt_addr_method.attr,
|
||||
&scst_tgt_io_grouping_type.attr,
|
||||
&scst_tgt_cpu_mask.attr,
|
||||
&scst_tgt_unknown_cmd_count_attr.attr,
|
||||
&scst_tgt_write_cmd_count_attr.attr,
|
||||
&scst_tgt_write_io_count_kb_attr.attr,
|
||||
&scst_tgt_read_cmd_count_attr.attr,
|
||||
&scst_tgt_read_io_count_kb_attr.attr,
|
||||
&scst_tgt_bidi_cmd_count_attr.attr,
|
||||
&scst_tgt_bidi_io_count_kb_attr.attr,
|
||||
&scst_tgt_none_cmd_count_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user