diff --git a/scst/README b/scst/README index 5fd03b38a..889227b15 100644 --- a/scst/README +++ b/scst/README @@ -665,6 +665,20 @@ Every target should have at least the following entries: until rel_tgt_id becomes unique. This attribute initialized unique by SCST by default. + - *count*, e.g. read_io_count_kb, - statistics about executed + commands and transferred data. Those attributes have speaking names + built from parts: + + 1. Data transfer direction + + 2. Alignment type: not specified or unaligned (on 4K boundaries) + + 3. Type: IO (commands) count or amount of transferred data + + 4. For transferred data: measurement units + + For instance, read_unaligned_cmd_count means number of 4K unaligned IOs. + A target driver may have also the following entries: - "hw_target" - if the target driver supports both hardware and virtual @@ -726,6 +740,9 @@ following entries: - latency - if CONFIG_SCST_MEASURE_LATENCY enabled, contains latency statistics for this session. + - *count*, e.g. read_io_count_kb, - statistics about executed + commands and transferred data. See above for more details. + - luns - a link pointing out to the corresponding LUNs set (security group) where this session was attached to. diff --git a/scst/README_in-tree b/scst/README_in-tree index 2f1a0acf6..43efb16aa 100644 --- a/scst/README_in-tree +++ b/scst/README_in-tree @@ -541,6 +541,20 @@ Every target should have at least the following entries: until rel_tgt_id becomes unique. This attribute initialized unique by SCST by default. + - *count*, e.g. read_io_count_kb, - statistics about executed + commands and transferred data. Those attributes have speaking names + built from parts: + + 1. Data transfer direction + + 2. Alignment type: not specified or unaligned (on 4K boundaries) + + 3. Type: IO (commands) count or amount of transferred data + + 4. For transferred data: measurement units + + For instance, read_unaligned_cmd_count means number of 4K unaligned IOs. + A target driver may have also the following entries: - "hw_target" - if the target driver supports both hardware and virtual @@ -602,6 +616,9 @@ following entries: - latency - if CONFIG_SCST_MEASURE_LATENCY enabled, contains latency statistics for this session. + - *count*, e.g. read_io_count_kb, - statistics about executed + commands and transferred data. See above for more details. + - luns - a link pointing out to the corresponding LUNs set (security group) where this session was attached to. diff --git a/scst/include/scst.h b/scst/include/scst.h index 819a77564..688f6d074 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -2039,6 +2039,7 @@ struct scst_ext_latency_stat { struct scst_io_stat_entry { uint64_t cmd_count; uint64_t io_byte_count; + uint64_t unaligned_cmd_count; }; /* diff --git a/scst/src/scst_sysfs.c b/scst/src/scst_sysfs.c index 2619f711f..a1a267607 100644 --- a/scst/src/scst_sysfs.c +++ b/scst/src/scst_sysfs.c @@ -2757,14 +2757,14 @@ static struct kobj_attribute scst_tgt_##attr##_attr = \ 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(io_byte_count, write_io_count_kb, SCST_DATA_WRITE, >> 10); +SCST_TGT_SYSFS_STAT_ATTR(unaligned_cmd_count, write_unaligned_cmd_count, SCST_DATA_WRITE, >> 0); 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(io_byte_count, read_io_count_kb, SCST_DATA_READ, >> 10); +SCST_TGT_SYSFS_STAT_ATTR(unaligned_cmd_count, read_unaligned_cmd_count, SCST_DATA_READ, >> 0); 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(io_byte_count, bidi_io_count_kb, SCST_DATA_BIDI, >> 10); +SCST_TGT_SYSFS_STAT_ATTR(unaligned_cmd_count, bidi_unaligned_cmd_count, SCST_DATA_BIDI, >> 0); SCST_TGT_SYSFS_STAT_ATTR(cmd_count, none_cmd_count, SCST_DATA_NONE, >> 0); static struct attribute *scst_tgt_attrs[] = { @@ -2777,10 +2777,13 @@ static struct attribute *scst_tgt_attrs[] = { &scst_tgt_unknown_cmd_count_attr.attr, &scst_tgt_write_cmd_count_attr.attr, &scst_tgt_write_io_count_kb_attr.attr, + &scst_tgt_write_unaligned_cmd_count_attr.attr, &scst_tgt_read_cmd_count_attr.attr, &scst_tgt_read_io_count_kb_attr.attr, + &scst_tgt_read_unaligned_cmd_count_attr.attr, &scst_tgt_bidi_cmd_count_attr.attr, &scst_tgt_bidi_io_count_kb_attr.attr, + &scst_tgt_bidi_unaligned_cmd_count_attr.attr, &scst_tgt_none_cmd_count_attr.attr, NULL, }; @@ -4568,6 +4571,7 @@ static ssize_t scst_sess_sysfs_##exported_name##_store(struct kobject *kobj, \ BUILD_BUG_ON(dir >= SCST_DATA_DIR_MAX); \ sess->io_stats[dir].cmd_count = 0; \ sess->io_stats[dir].io_byte_count = 0; \ + sess->io_stats[dir].unaligned_cmd_count = 0; \ spin_unlock_irq(&sess->sess_list_lock); \ return count; \ } \ @@ -4580,13 +4584,15 @@ static struct kobj_attribute session_##exported_name##_attr = \ 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(unaligned_cmd_count, write_unaligned_cmd_count, SCST_DATA_WRITE, 0); 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(unaligned_cmd_count, read_unaligned_cmd_count, SCST_DATA_READ, 0); 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(unaligned_cmd_count, bidi_unaligned_cmd_count, SCST_DATA_BIDI, 0); SCST_SESS_SYSFS_STAT_ATTR(cmd_count, none_cmd_count, SCST_DATA_NONE, 0); - static ssize_t scst_sess_force_close_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) @@ -4615,10 +4621,13 @@ static struct attribute *scst_session_attrs[] = { &session_unknown_cmd_count_attr.attr, &session_write_cmd_count_attr.attr, &session_write_io_count_kb_attr.attr, + &session_write_unaligned_cmd_count_attr.attr, &session_read_cmd_count_attr.attr, &session_read_io_count_kb_attr.attr, + &session_read_unaligned_cmd_count_attr.attr, &session_bidi_cmd_count_attr.attr, &session_bidi_io_count_kb_attr.attr, + &session_bidi_unaligned_cmd_count_attr.attr, &session_none_cmd_count_attr.attr, #ifdef CONFIG_SCST_MEASURE_LATENCY &session_latency_attr.attr, diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 73dcc325f..62755aa13 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -4165,6 +4165,7 @@ static int scst_finish_cmd(struct scst_cmd *cmd) int res; struct scst_session *sess = cmd->sess; struct scst_io_stat_entry *stat; + int block_shift, align_len; TRACE_ENTRY(); @@ -4193,6 +4194,18 @@ static int scst_finish_cmd(struct scst_cmd *cmd) stat = &sess->io_stats[cmd->data_direction]; stat->cmd_count++; stat->io_byte_count += cmd->bufflen + cmd->out_bufflen; + if (likely(cmd->dev != NULL)) { + block_shift = cmd->dev->block_shift; + /* Let's track only 4K unaligned cmds at the moment */ + align_len = (block_shift != 0) ? 4095 : 0; + } else { + block_shift = 0; + align_len = 0; + } + + if (unlikely(((cmd->lba << block_shift) & align_len) != 0) || + unlikely(((cmd->bufflen + cmd->out_bufflen) & align_len) != 0)) + stat->unaligned_cmd_count++; list_del(&cmd->sess_cmd_list_entry);