summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeymour, Shane M <shane.seymour@hp.com>2015-05-05 21:37:20 -0400
committerJames Bottomley <JBottomley@Odin.com>2015-06-02 11:03:25 -0400
commit05545c92db9637318a98d3d59d400beb819decc7 (patch)
tree56c911568dd7dd6507aac24f7c8c90b657f7bda0
parentba929992522b6d1f866b7021bc50da66f8fdd743 (diff)
st: implement tape statistics
This patch implements tape statistics in the st module via sysfs. Current no statistics are available for tape I/O and there is no easy way to reuse the block layer statistics for tape as tape is a character device and does not have perform I/O in sector sized chunks (the size of the data written to tape can change). For tapes we also need extra stats related to things like tape movement (via other I/O). There have been multiple end users requesting statistics including AT&T (and some HP customers who have not given permission to be named). It is impossible for them to investigate any issues related to tape performance in a non-invasive way. [jejb: eliminate PRId64] Signed-off-by: Shane Seymour <shane.seymour@hp.com> Tested-by: Shane Seymour <shane.seymour@hp.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Bottomley <JBottomley@Odin.com>
-rw-r--r--Documentation/ABI/testing/sysfs-class-scsi_tape109
-rw-r--r--Documentation/scsi/st.txt59
-rw-r--r--drivers/scsi/st.c272
-rw-r--r--drivers/scsi/st.h22
4 files changed, 461 insertions, 1 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-scsi_tape b/Documentation/ABI/testing/sysfs-class-scsi_tape
new file mode 100644
index 000000000000..9be398b87ee9
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-scsi_tape
@@ -0,0 +1,109 @@
1What: /sys/class/scsi_tape/*/stats/in_flight
2Date: Apr 2015
3KernelVersion: 4.2
4Contact: Shane Seymour <shane.seymour@hp.com>
5Description:
6 Show the number of I/Os currently in-flight between the st
7 module and the SCSI mid-layer.
8Users:
9
10
11What: /sys/class/scsi_tape/*/stats/io_ns
12Date: Apr 2015
13KernelVersion: 4.2
14Contact: Shane Seymour <shane.seymour@hp.com>
15Description:
16 Shows the total amount of time spent waiting for all I/O
17 to and from the tape drive to complete. This includes all
18 reads, writes, and other SCSI commands issued to the tape
19 drive. An example of other SCSI commands would be tape
20 movement such as a rewind when a rewind tape device is
21 closed. This item is measured in nanoseconds.
22
23 To determine the amount of time spent waiting for other I/O
24 to complete subtract read_ns and write_ns from this value.
25Users:
26
27
28What: /sys/class/scsi_tape/*/stats/other_cnt
29Date: Apr 2015
30KernelVersion: 4.2
31Contact: Shane Seymour <shane.seymour@hp.com>
32Description:
33 The number of I/O requests issued to the tape drive other
34 than SCSI read/write requests.
35Users:
36
37
38What: /sys/class/scsi_tape/*/stats/read_byte_cnt
39Date: Apr 2015
40KernelVersion: 4.2
41Contact: Shane Seymour <shane.seymour@hp.com>
42Description:
43 Shows the total number of bytes requested from the tape drive.
44 This value is presented in bytes because tape drives support
45 variable length block sizes.
46Users:
47
48
49What: /sys/class/scsi_tape/*/stats/read_cnt
50Date: Apr 2015
51KernelVersion: 4.2
52Contact: Shane Seymour <shane.seymour@hp.com>
53Description:
54 Shows the total number of read requests issued to the tape
55 drive.
56Users:
57
58
59What: /sys/class/scsi_tape/*/stats/read_ns
60Date: Apr 2015
61KernelVersion: 4.2
62Contact: Shane Seymour <shane.seymour@hp.com>
63Description:
64 Shows the total amount of time in nanoseconds waiting for
65 read I/O requests to complete.
66Users:
67
68
69What: /sys/class/scsi_tape/*/stats/write_byte_cnt
70Date: Apr 2015
71KernelVersion: 4.2
72Contact: Shane Seymour <shane.seymour@hp.com>
73Description:
74 Shows the total number of bytes written to the tape drive.
75 This value is presented in bytes because tape drives support
76 variable length block sizes.
77Users:
78
79
80What: /sys/class/scsi_tape/*/stats/write_cnt
81Date: Apr 2015
82KernelVersion: 4.2
83Contact: Shane Seymour <shane.seymour@hp.com>
84Description:
85 Shows the total number of write requests issued to the tape
86 drive.
87Users:
88
89
90What: /sys/class/scsi_tape/*/stats/write_ms
91Date: Apr 2015
92KernelVersion: 4.2
93Contact: Shane Seymour <shane.seymour@hp.com>
94Description:
95 Shows the total amount of time in nanoseconds waiting for
96 write I/O requests to complete.
97Users:
98
99
100What: /sys/class/scsi_tape/*/stats/resid_cnt
101Date: Apr 2015
102KernelVersion: 4.2
103Contact: Shane Seymour <shane.seymour@hp.com>
104Description:
105 Shows the number of times we found that a residual >0
106 was found when the SCSI midlayer indicated that there was
107 an error. For reads this may be a case of someone issuing
108 reads greater than the block size.
109Users:
diff --git a/Documentation/scsi/st.txt b/Documentation/scsi/st.txt
index 0d5bdb153d3b..f29fa550665a 100644
--- a/Documentation/scsi/st.txt
+++ b/Documentation/scsi/st.txt
@@ -151,6 +151,65 @@ A link named 'tape' is made from the SCSI device directory to the class
151directory corresponding to the mode 0 auto-rewind device (e.g., st0). 151directory corresponding to the mode 0 auto-rewind device (e.g., st0).
152 152
153 153
154SYSFS AND STATISTICS FOR TAPE DEVICES
155
156The st driver maintains statistics for tape drives inside the sysfs filesystem.
157The following method can be used to locate the statistics that are
158available (assuming that sysfs is mounted at /sys):
159
1601. Use opendir(3) on the directory /sys/class/scsi_tape
1612. Use readdir(3) to read the directory contents
1623. Use regcomp(3)/regexec(3) to match directory entries to the extended
163 regular expression "^st[0-9]+$"
1644. Access the statistics from the /sys/class/scsi_tape/<match>/stats
165 directory (where <match> is a directory entry from /sys/class/scsi_tape
166 that matched the extended regular expression)
167
168The reason for using this approach is that all the character devices
169pointing to the same tape drive use the same statistics. That means
170that st0 would have the same statistics as nst0.
171
172The directory contains the following statistics files:
173
1741. in_flight - The number of I/Os currently outstanding to this device.
1752. io_ns - The amount of time spent waiting (in nanoseconds) for all I/O
176 to complete (including read and write). This includes tape movement
177 commands such as seeking between file or set marks and implicit tape
178 movement such as when rewind on close tape devices are used.
1793. other_cnt - The number of I/Os issued to the tape drive other than read or
180 write commands. The time taken to complete these commands uses the
181 following calculation io_ms-read_ms-write_ms.
1824. read_byte_cnt - The number of bytes read from the tape drive.
1835. read_cnt - The number of read requests issued to the tape drive.
1846. read_ns - The amount of time (in nanoseconds) spent waiting for read
185 requests to complete.
1867. write_byte_cnt - The number of bytes written to the tape drive.
1878. write_cnt - The number of write requests issued to the tape drive.
1889. write_ns - The amount of time (in nanoseconds) spent waiting for write
189 requests to complete.
19010. resid_cnt - The number of times during a read or write we found
191 the residual amount to be non-zero. This should mean that a program
192 is issuing a read larger thean the block size on tape. For write
193 not all data made it to tape.
194
195Note: The in_flight value is incremented when an I/O starts the I/O
196itself is not added to the statistics until it completes.
197
198The total of read_cnt, write_cnt, and other_cnt may not total to the same
199value as iodone_cnt at the device level. The tape statistics only count
200I/O issued via the st module.
201
202When read the statistics may not be temporally consistent while I/O is in
203progress. The individual values are read and written to atomically however
204when reading them back via sysfs they may be in the process of being
205updated when starting an I/O or when it is completed.
206
207The value shown in in_flight is incremented before any statstics are
208updated and decremented when an I/O completes after updating statistics.
209The value of in_flight is 0 when there are no I/Os outstanding that are
210issued by the st driver. Tape statistics do not take into account any
211I/O performed via the sg device.
212
154BSD AND SYS V SEMANTICS 213BSD AND SYS V SEMANTICS
155 214
156The user can choose between these two behaviours of the tape driver by 215The user can choose between these two behaviours of the tape driver by
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 9a1c34205254..3f25b8fa921d 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -471,6 +471,47 @@ static void st_release_request(struct st_request *streq)
471 kfree(streq); 471 kfree(streq);
472} 472}
473 473
474static void st_do_stats(struct scsi_tape *STp, struct request *req)
475{
476 ktime_t now;
477
478 now = ktime_get();
479 if (req->cmd[0] == WRITE_6) {
480 now = ktime_sub(now, STp->stats->write_time);
481 atomic64_add(ktime_to_ns(now), &STp->stats->tot_write_time);
482 atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_time);
483 atomic64_inc(&STp->stats->write_cnt);
484 if (req->errors) {
485 atomic64_add(atomic_read(&STp->stats->last_write_size)
486 - STp->buffer->cmdstat.residual,
487 &STp->stats->write_byte_cnt);
488 if (STp->buffer->cmdstat.residual > 0)
489 atomic64_inc(&STp->stats->resid_cnt);
490 } else
491 atomic64_add(atomic_read(&STp->stats->last_write_size),
492 &STp->stats->write_byte_cnt);
493 } else if (req->cmd[0] == READ_6) {
494 now = ktime_sub(now, STp->stats->read_time);
495 atomic64_add(ktime_to_ns(now), &STp->stats->tot_read_time);
496 atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_time);
497 atomic64_inc(&STp->stats->read_cnt);
498 if (req->errors) {
499 atomic64_add(atomic_read(&STp->stats->last_read_size)
500 - STp->buffer->cmdstat.residual,
501 &STp->stats->read_byte_cnt);
502 if (STp->buffer->cmdstat.residual > 0)
503 atomic64_inc(&STp->stats->resid_cnt);
504 } else
505 atomic64_add(atomic_read(&STp->stats->last_read_size),
506 &STp->stats->read_byte_cnt);
507 } else {
508 now = ktime_sub(now, STp->stats->other_time);
509 atomic64_add(ktime_to_ns(now), &STp->stats->tot_io_time);
510 atomic64_inc(&STp->stats->other_cnt);
511 }
512 atomic64_dec(&STp->stats->in_flight);
513}
514
474static void st_scsi_execute_end(struct request *req, int uptodate) 515static void st_scsi_execute_end(struct request *req, int uptodate)
475{ 516{
476 struct st_request *SRpnt = req->end_io_data; 517 struct st_request *SRpnt = req->end_io_data;
@@ -480,6 +521,8 @@ static void st_scsi_execute_end(struct request *req, int uptodate)
480 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors; 521 STp->buffer->cmdstat.midlevel_result = SRpnt->result = req->errors;
481 STp->buffer->cmdstat.residual = req->resid_len; 522 STp->buffer->cmdstat.residual = req->resid_len;
482 523
524 st_do_stats(STp, req);
525
483 tmp = SRpnt->bio; 526 tmp = SRpnt->bio;
484 if (SRpnt->waiting) 527 if (SRpnt->waiting)
485 complete(SRpnt->waiting); 528 complete(SRpnt->waiting);
@@ -496,6 +539,7 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
496 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data; 539 struct rq_map_data *mdata = &SRpnt->stp->buffer->map_data;
497 int err = 0; 540 int err = 0;
498 int write = (data_direction == DMA_TO_DEVICE); 541 int write = (data_direction == DMA_TO_DEVICE);
542 struct scsi_tape *STp = SRpnt->stp;
499 543
500 req = blk_get_request(SRpnt->stp->device->request_queue, write, 544 req = blk_get_request(SRpnt->stp->device->request_queue, write,
501 GFP_KERNEL); 545 GFP_KERNEL);
@@ -516,6 +560,17 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
516 } 560 }
517 } 561 }
518 562
563 atomic64_inc(&STp->stats->in_flight);
564 if (cmd[0] == WRITE_6) {
565 atomic_set(&STp->stats->last_write_size, bufflen);
566 STp->stats->write_time = ktime_get();
567 } else if (cmd[0] == READ_6) {
568 atomic_set(&STp->stats->last_read_size, bufflen);
569 STp->stats->read_time = ktime_get();
570 } else {
571 STp->stats->other_time = ktime_get();
572 }
573
519 SRpnt->bio = req->bio; 574 SRpnt->bio = req->bio;
520 req->cmd_len = COMMAND_SIZE(cmd[0]); 575 req->cmd_len = COMMAND_SIZE(cmd[0]);
521 memset(req->cmd, 0, BLK_MAX_CDB); 576 memset(req->cmd, 0, BLK_MAX_CDB);
@@ -4222,6 +4277,12 @@ static int st_probe(struct device *dev)
4222 } 4277 }
4223 tpnt->index = error; 4278 tpnt->index = error;
4224 sprintf(disk->disk_name, "st%d", tpnt->index); 4279 sprintf(disk->disk_name, "st%d", tpnt->index);
4280 tpnt->stats = kzalloc(sizeof(struct scsi_tape_stats), GFP_KERNEL);
4281 if (tpnt->stats == NULL) {
4282 sdev_printk(KERN_ERR, SDp,
4283 "st: Can't allocate statistics.\n");
4284 goto out_idr_remove;
4285 }
4225 4286
4226 dev_set_drvdata(dev, tpnt); 4287 dev_set_drvdata(dev, tpnt);
4227 4288
@@ -4241,6 +4302,8 @@ static int st_probe(struct device *dev)
4241 4302
4242out_remove_devs: 4303out_remove_devs:
4243 remove_cdevs(tpnt); 4304 remove_cdevs(tpnt);
4305 kfree(tpnt->stats);
4306out_idr_remove:
4244 spin_lock(&st_index_lock); 4307 spin_lock(&st_index_lock);
4245 idr_remove(&st_index_idr, tpnt->index); 4308 idr_remove(&st_index_idr, tpnt->index);
4246 spin_unlock(&st_index_lock); 4309 spin_unlock(&st_index_lock);
@@ -4298,6 +4361,7 @@ static void scsi_tape_release(struct kref *kref)
4298 4361
4299 disk->private_data = NULL; 4362 disk->private_data = NULL;
4300 put_disk(disk); 4363 put_disk(disk);
4364 kfree(tpnt->stats);
4301 kfree(tpnt); 4365 kfree(tpnt);
4302 return; 4366 return;
4303} 4367}
@@ -4513,6 +4577,184 @@ options_show(struct device *dev, struct device_attribute *attr, char *buf)
4513} 4577}
4514static DEVICE_ATTR_RO(options); 4578static DEVICE_ATTR_RO(options);
4515 4579
4580/* Support for tape stats */
4581
4582/**
4583 * read_cnt_show - return read count - count of reads made from tape drive
4584 * @dev: struct device
4585 * @attr: attribute structure
4586 * @buf: buffer to return formatted data in
4587 */
4588static ssize_t read_cnt_show(struct device *dev,
4589 struct device_attribute *attr, char *buf)
4590{
4591 struct st_modedef *STm = dev_get_drvdata(dev);
4592
4593 return sprintf(buf, "%lld",
4594 (long long)atomic64_read(&STm->tape->stats->read_cnt));
4595}
4596static DEVICE_ATTR_RO(read_cnt);
4597
4598/**
4599 * read_byte_cnt_show - return read byte count - tape drives
4600 * may use blocks less than 512 bytes this gives the raw byte count of
4601 * of data read from the tape drive.
4602 * @dev: struct device
4603 * @attr: attribute structure
4604 * @buf: buffer to return formatted data in
4605 */
4606static ssize_t read_byte_cnt_show(struct device *dev,
4607 struct device_attribute *attr, char *buf)
4608{
4609 struct st_modedef *STm = dev_get_drvdata(dev);
4610
4611 return sprintf(buf, "%lld",
4612 (long long)atomic64_read(&STm->tape->stats->read_byte_cnt));
4613}
4614static DEVICE_ATTR_RO(read_byte_cnt);
4615
4616/**
4617 * read_us_show - return read us - overall time spent waiting on reads in ns.
4618 * @dev: struct device
4619 * @attr: attribute structure
4620 * @buf: buffer to return formatted data in
4621 */
4622static ssize_t read_ns_show(struct device *dev,
4623 struct device_attribute *attr, char *buf)
4624{
4625 struct st_modedef *STm = dev_get_drvdata(dev);
4626
4627 return sprintf(buf, "%lld",
4628 (long long)atomic64_read(&STm->tape->stats->tot_read_time));
4629}
4630static DEVICE_ATTR_RO(read_ns);
4631
4632/**
4633 * write_cnt_show - write count - number of user calls
4634 * to write(2) that have written data to tape.
4635 * @dev: struct device
4636 * @attr: attribute structure
4637 * @buf: buffer to return formatted data in
4638 */
4639static ssize_t write_cnt_show(struct device *dev,
4640 struct device_attribute *attr, char *buf)
4641{
4642 struct st_modedef *STm = dev_get_drvdata(dev);
4643
4644 return sprintf(buf, "%lld",
4645 (long long)atomic64_read(&STm->tape->stats->write_cnt));
4646}
4647static DEVICE_ATTR_RO(write_cnt);
4648
4649/**
4650 * write_byte_cnt_show - write byte count - raw count of
4651 * bytes written to tape.
4652 * @dev: struct device
4653 * @attr: attribute structure
4654 * @buf: buffer to return formatted data in
4655 */
4656static ssize_t write_byte_cnt_show(struct device *dev,
4657 struct device_attribute *attr, char *buf)
4658{
4659 struct st_modedef *STm = dev_get_drvdata(dev);
4660
4661 return sprintf(buf, "%lld",
4662 (long long)atomic64_read(&STm->tape->stats->write_byte_cnt));
4663}
4664static DEVICE_ATTR_RO(write_byte_cnt);
4665
4666/**
4667 * write_ns_show - write ns - number of nanoseconds waiting on write
4668 * requests to complete.
4669 * @dev: struct device
4670 * @attr: attribute structure
4671 * @buf: buffer to return formatted data in
4672 */
4673static ssize_t write_ns_show(struct device *dev,
4674 struct device_attribute *attr, char *buf)
4675{
4676 struct st_modedef *STm = dev_get_drvdata(dev);
4677
4678 return sprintf(buf, "%lld",
4679 (long long)atomic64_read(&STm->tape->stats->tot_write_time));
4680}
4681static DEVICE_ATTR_RO(write_ns);
4682
4683/**
4684 * in_flight_show - number of I/Os currently in flight -
4685 * in most cases this will be either 0 or 1. It may be higher if someone
4686 * has also issued other SCSI commands such as via an ioctl.
4687 * @dev: struct device
4688 * @attr: attribute structure
4689 * @buf: buffer to return formatted data in
4690 */
4691static ssize_t in_flight_show(struct device *dev,
4692 struct device_attribute *attr, char *buf)
4693{
4694 struct st_modedef *STm = dev_get_drvdata(dev);
4695
4696 return sprintf(buf, "%lld",
4697 (long long)atomic64_read(&STm->tape->stats->in_flight));
4698}
4699static DEVICE_ATTR_RO(in_flight);
4700
4701/**
4702 * io_ns_show - io wait ns - this is the number of ns spent
4703 * waiting on all I/O to complete. This includes tape movement commands
4704 * such as rewinding, seeking to end of file or tape, it also includes
4705 * read and write. To determine the time spent on tape movement
4706 * subtract the read and write ns from this value.
4707 * @dev: struct device
4708 * @attr: attribute structure
4709 * @buf: buffer to return formatted data in
4710 */
4711static ssize_t io_ns_show(struct device *dev,
4712 struct device_attribute *attr, char *buf)
4713{
4714 struct st_modedef *STm = dev_get_drvdata(dev);
4715
4716 return sprintf(buf, "%lld",
4717 (long long)atomic64_read(&STm->tape->stats->tot_io_time));
4718}
4719static DEVICE_ATTR_RO(io_ns);
4720
4721/**
4722 * other_cnt_show - other io count - this is the number of
4723 * I/O requests other than read and write requests.
4724 * Typically these are tape movement requests but will include driver
4725 * tape movement. This includes only requests issued by the st driver.
4726 * @dev: struct device
4727 * @attr: attribute structure
4728 * @buf: buffer to return formatted data in
4729 */
4730static ssize_t other_cnt_show(struct device *dev,
4731 struct device_attribute *attr, char *buf)
4732{
4733 struct st_modedef *STm = dev_get_drvdata(dev);
4734
4735 return sprintf(buf, "%lld",
4736 (long long)atomic64_read(&STm->tape->stats->other_cnt));
4737}
4738static DEVICE_ATTR_RO(other_cnt);
4739
4740/**
4741 * resid_cnt_show - A count of the number of times we get a residual
4742 * count - this should indicate someone issuing reads larger than the
4743 * block size on tape.
4744 * @dev: struct device
4745 * @attr: attribute structure
4746 * @buf: buffer to return formatted data in
4747 */
4748static ssize_t resid_cnt_show(struct device *dev,
4749 struct device_attribute *attr, char *buf)
4750{
4751 struct st_modedef *STm = dev_get_drvdata(dev);
4752
4753 return sprintf(buf, "%lld",
4754 (long long)atomic64_read(&STm->tape->stats->resid_cnt));
4755}
4756static DEVICE_ATTR_RO(resid_cnt);
4757
4516static struct attribute *st_dev_attrs[] = { 4758static struct attribute *st_dev_attrs[] = {
4517 &dev_attr_defined.attr, 4759 &dev_attr_defined.attr,
4518 &dev_attr_default_blksize.attr, 4760 &dev_attr_default_blksize.attr,
@@ -4521,7 +4763,35 @@ static struct attribute *st_dev_attrs[] = {
4521 &dev_attr_options.attr, 4763 &dev_attr_options.attr,
4522 NULL, 4764 NULL,
4523}; 4765};
4524ATTRIBUTE_GROUPS(st_dev); 4766
4767static struct attribute *st_stats_attrs[] = {
4768 &dev_attr_read_cnt.attr,
4769 &dev_attr_read_byte_cnt.attr,
4770 &dev_attr_read_ns.attr,
4771 &dev_attr_write_cnt.attr,
4772 &dev_attr_write_byte_cnt.attr,
4773 &dev_attr_write_ns.attr,
4774 &dev_attr_in_flight.attr,
4775 &dev_attr_io_ns.attr,
4776 &dev_attr_other_cnt.attr,
4777 &dev_attr_resid_cnt.attr,
4778 NULL,
4779};
4780
4781static struct attribute_group stats_group = {
4782 .name = "stats",
4783 .attrs = st_stats_attrs,
4784};
4785
4786static struct attribute_group st_group = {
4787 .attrs = st_dev_attrs,
4788};
4789
4790static const struct attribute_group *st_dev_groups[] = {
4791 &st_group,
4792 &stats_group,
4793 NULL,
4794};
4525 4795
4526/* The following functions may be useful for a larger audience. */ 4796/* The following functions may be useful for a larger audience. */
4527static int sgl_map_user_pages(struct st_buffer *STbp, 4797static int sgl_map_user_pages(struct st_buffer *STbp,
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h
index f3eee0f9f40c..b6486b5d8681 100644
--- a/drivers/scsi/st.h
+++ b/drivers/scsi/st.h
@@ -92,6 +92,27 @@ struct st_partstat {
92 int drv_file; 92 int drv_file;
93}; 93};
94 94
95/* Tape statistics */
96struct scsi_tape_stats {
97 atomic64_t read_byte_cnt; /* bytes read */
98 atomic64_t write_byte_cnt; /* bytes written */
99 atomic64_t in_flight; /* Number of I/Os in flight */
100 atomic64_t read_cnt; /* Count of read requests */
101 atomic64_t write_cnt; /* Count of write requests */
102 atomic64_t other_cnt; /* Count of other requests either
103 * implicit or from user space
104 * ioctl. */
105 atomic64_t resid_cnt; /* Count of resid_len > 0 */
106 atomic64_t tot_read_time; /* ktime spent completing reads */
107 atomic64_t tot_write_time; /* ktime spent completing writes */
108 atomic64_t tot_io_time; /* ktime spent doing any I/O */
109 ktime_t read_time; /* holds ktime request was queued */
110 ktime_t write_time; /* holds ktime request was queued */
111 ktime_t other_time; /* holds ktime request was queued */
112 atomic_t last_read_size; /* Number of bytes issued for last read */
113 atomic_t last_write_size; /* Number of bytes issued for last write */
114};
115
95#define ST_NBR_PARTITIONS 4 116#define ST_NBR_PARTITIONS 4
96 117
97/* The tape drive descriptor */ 118/* The tape drive descriptor */
@@ -171,6 +192,7 @@ struct scsi_tape {
171#endif 192#endif
172 struct gendisk *disk; 193 struct gendisk *disk;
173 struct kref kref; 194 struct kref kref;
195 struct scsi_tape_stats *stats;
174}; 196};
175 197
176/* Bit masks for use_pf */ 198/* Bit masks for use_pf */