Skip to content

Commit af180c0

Browse files
bvanasschemartinkpetersen
authored andcommitted
scsi: scsi_debug: Maintain write statistics per group number
Track per GROUP NUMBER how many write commands have been processed. Make this information available in sysfs. Reset these statistics if any data is written into the sysfs attribute. Note: SCSI devices should only interpret the information in the GROUP NUMBER field as a stream identifier if the ST_ENBLE bit has been set to one. This patch follows a simpler approach: count the number of writes per GROUP NUMBER whether or not the group number represents a stream identifier. Cc: Martin K. Petersen <martin.petersen@oracle.com> Cc: Douglas Gilbert <dgilbert@interlog.com> Tested-by: Douglas Gilbert <dgilbert@interlog.com> Signed-off-by: Bart Van Assche <bvanassche@acm.org> Link: https://lore.kernel.org/r/20240130214911.1863909-20-bvanassche@acm.org Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent ad620be commit af180c0

File tree

1 file changed

+45
-4
lines changed

1 file changed

+45
-4
lines changed

drivers/scsi/scsi_debug.c

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,8 @@ static int sdeb_zbc_nr_conv = DEF_ZBC_NR_CONV_ZONES;
902902
static int submit_queues = DEF_SUBMIT_QUEUES; /* > 1 for multi-queue (mq) */
903903
static int poll_queues; /* iouring iopoll interface.*/
904904

905+
static atomic_long_t writes_by_group_number[64];
906+
905907
static char sdebug_proc_name[] = MY_NAME;
906908
static const char *my_name = MY_NAME;
907909

@@ -3377,7 +3379,8 @@ static inline struct sdeb_store_info *devip2sip(struct sdebug_dev_info *devip,
33773379

33783380
/* Returns number of bytes copied or -1 if error. */
33793381
static int do_device_access(struct sdeb_store_info *sip, struct scsi_cmnd *scp,
3380-
u32 sg_skip, u64 lba, u32 num, bool do_write)
3382+
u32 sg_skip, u64 lba, u32 num, bool do_write,
3383+
u8 group_number)
33813384
{
33823385
int ret;
33833386
u64 block, rest = 0;
@@ -3396,6 +3399,10 @@ static int do_device_access(struct sdeb_store_info *sip, struct scsi_cmnd *scp,
33963399
return 0;
33973400
if (scp->sc_data_direction != dir)
33983401
return -1;
3402+
3403+
if (do_write && group_number < ARRAY_SIZE(writes_by_group_number))
3404+
atomic_long_inc(&writes_by_group_number[group_number]);
3405+
33993406
fsp = sip->storep;
34003407

34013408
block = do_div(lba, sdebug_store_sectors);
@@ -3769,7 +3776,7 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
37693776
}
37703777
}
37713778

3772-
ret = do_device_access(sip, scp, 0, lba, num, false);
3779+
ret = do_device_access(sip, scp, 0, lba, num, false, 0);
37733780
sdeb_read_unlock(sip);
37743781
if (unlikely(ret == -1))
37753782
return DID_ERROR << 16;
@@ -3954,6 +3961,7 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
39543961
{
39553962
bool check_prot;
39563963
u32 num;
3964+
u8 group = 0;
39573965
u32 ei_lba;
39583966
int ret;
39593967
u64 lba;
@@ -3965,11 +3973,13 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
39653973
ei_lba = 0;
39663974
lba = get_unaligned_be64(cmd + 2);
39673975
num = get_unaligned_be32(cmd + 10);
3976+
group = cmd[14] & 0x3f;
39683977
check_prot = true;
39693978
break;
39703979
case WRITE_10:
39713980
ei_lba = 0;
39723981
lba = get_unaligned_be32(cmd + 2);
3982+
group = cmd[6] & 0x3f;
39733983
num = get_unaligned_be16(cmd + 7);
39743984
check_prot = true;
39753985
break;
@@ -3984,15 +3994,18 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
39843994
ei_lba = 0;
39853995
lba = get_unaligned_be32(cmd + 2);
39863996
num = get_unaligned_be32(cmd + 6);
3997+
group = cmd[6] & 0x3f;
39873998
check_prot = true;
39883999
break;
39894000
case 0x53: /* XDWRITEREAD(10) */
39904001
ei_lba = 0;
39914002
lba = get_unaligned_be32(cmd + 2);
4003+
group = cmd[6] & 0x1f;
39924004
num = get_unaligned_be16(cmd + 7);
39934005
check_prot = false;
39944006
break;
39954007
default: /* assume WRITE(32) */
4008+
group = cmd[6] & 0x3f;
39964009
lba = get_unaligned_be64(cmd + 12);
39974010
ei_lba = get_unaligned_be32(cmd + 20);
39984011
num = get_unaligned_be32(cmd + 28);
@@ -4047,7 +4060,7 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
40474060
}
40484061
}
40494062

4050-
ret = do_device_access(sip, scp, 0, lba, num, true);
4063+
ret = do_device_access(sip, scp, 0, lba, num, true, group);
40514064
if (unlikely(scsi_debug_lbp()))
40524065
map_region(sip, lba, num);
40534066
/* If ZBC zone then bump its write pointer */
@@ -4099,12 +4112,14 @@ static int resp_write_scat(struct scsi_cmnd *scp,
40994112
u32 lb_size = sdebug_sector_size;
41004113
u32 ei_lba;
41014114
u64 lba;
4115+
u8 group;
41024116
int ret, res;
41034117
bool is_16;
41044118
static const u32 lrd_size = 32; /* + parameter list header size */
41054119

41064120
if (cmd[0] == VARIABLE_LENGTH_CMD) {
41074121
is_16 = false;
4122+
group = cmd[6] & 0x3f;
41084123
wrprotect = (cmd[10] >> 5) & 0x7;
41094124
lbdof = get_unaligned_be16(cmd + 12);
41104125
num_lrd = get_unaligned_be16(cmd + 16);
@@ -4115,6 +4130,7 @@ static int resp_write_scat(struct scsi_cmnd *scp,
41154130
lbdof = get_unaligned_be16(cmd + 4);
41164131
num_lrd = get_unaligned_be16(cmd + 8);
41174132
bt_len = get_unaligned_be32(cmd + 10);
4133+
group = cmd[14] & 0x3f;
41184134
if (unlikely(have_dif_prot)) {
41194135
if (sdebug_dif == T10_PI_TYPE2_PROTECTION &&
41204136
wrprotect) {
@@ -4203,7 +4219,7 @@ static int resp_write_scat(struct scsi_cmnd *scp,
42034219
}
42044220
}
42054221

4206-
ret = do_device_access(sip, scp, sg_off, lba, num, true);
4222+
ret = do_device_access(sip, scp, sg_off, lba, num, true, group);
42074223
/* If ZBC zone then bump its write pointer */
42084224
if (sdebug_dev_is_zoned(devip))
42094225
zbc_inc_wp(devip, lba, num);
@@ -7298,6 +7314,30 @@ static ssize_t tur_ms_to_ready_show(struct device_driver *ddp, char *buf)
72987314
}
72997315
static DRIVER_ATTR_RO(tur_ms_to_ready);
73007316

7317+
static ssize_t group_number_stats_show(struct device_driver *ddp, char *buf)
7318+
{
7319+
char *p = buf, *end = buf + PAGE_SIZE;
7320+
int i;
7321+
7322+
for (i = 0; i < ARRAY_SIZE(writes_by_group_number); i++)
7323+
p += scnprintf(p, end - p, "%d %ld\n", i,
7324+
atomic_long_read(&writes_by_group_number[i]));
7325+
7326+
return p - buf;
7327+
}
7328+
7329+
static ssize_t group_number_stats_store(struct device_driver *ddp,
7330+
const char *buf, size_t count)
7331+
{
7332+
int i;
7333+
7334+
for (i = 0; i < ARRAY_SIZE(writes_by_group_number); i++)
7335+
atomic_long_set(&writes_by_group_number[i], 0);
7336+
7337+
return count;
7338+
}
7339+
static DRIVER_ATTR_RW(group_number_stats);
7340+
73017341
/* Note: The following array creates attribute files in the
73027342
/sys/bus/pseudo/drivers/scsi_debug directory. The advantage of these
73037343
files (over those found in the /sys/module/scsi_debug/parameters
@@ -7344,6 +7384,7 @@ static struct attribute *sdebug_drv_attrs[] = {
73447384
&driver_attr_cdb_len.attr,
73457385
&driver_attr_tur_ms_to_ready.attr,
73467386
&driver_attr_zbc.attr,
7387+
&driver_attr_group_number_stats.attr,
73477388
NULL,
73487389
};
73497390
ATTRIBUTE_GROUPS(sdebug_drv);

0 commit comments

Comments
 (0)