LWN.net Logo

MidLayer updates - Add device io statistics

From:  James.Smart@Emulex.Com
To:  <linux-scsi@vger.kernel.org>
Subject:  [PATCH 2/3] MidLayer updates - Add device io statistics
Date:  Sat, 29 Jan 2005 09:03:04 -0500
Archive-link:  Article, Thread


Patch 2: 
  Adds io statistics (requests, completions, error count) as generic
  attributes for scsi devices.


-- James S



   Add io statistics (requests, completions, error count) as generic
   attributes for scsi devices.


  Signed-off-by: James Smart <james.smart@emulex.com>

---

 b/drivers/scsi/scsi.c        |    8 ++++++++
 b/drivers/scsi/scsi_sysfs.c  |   26 ++++++++++++++++++++++++++
 b/include/scsi/scsi_device.h |    4 ++++
 3 files changed, 38 insertions(+)

diff -puN a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c	2005-01-28 10:17:19.000000000 -0500
+++ b/drivers/scsi/scsi.c	2005-01-28 10:17:19.000000000 -0500
@@ -532,6 +532,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *
 		 * returns an immediate error upwards, and signals
 		 * that the device is no longer present */
 		cmd->result = DID_NO_CONNECT << 16;
+		atomic_inc(&cmd->device->iorequest_cnt);
 		scsi_done(cmd);
 		/* return 0 (because the command has been processed) */
 		goto out;
@@ -605,6 +606,8 @@ int scsi_dispatch_cmd(struct scsi_cmnd *
 	cmd->state = SCSI_STATE_QUEUED;
 	cmd->owner = SCSI_OWNER_LOWLEVEL;
 
+	atomic_inc(&cmd->device->iorequest_cnt);
+
 	/*
 	 * Before we queue this command, check if the command
 	 * length exceeds what the host adapter can handle.
@@ -627,6 +630,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *
 	}
 	spin_unlock_irqrestore(host->host_lock, flags);
 	if (rtn) {
+		atomic_inc(&cmd->device->iodone_cnt);
 		scsi_queue_insert(cmd,
 				(rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
 				 rtn : SCSI_MLQUEUE_HOST_BUSY);
@@ -758,6 +762,10 @@ void __scsi_done(struct scsi_cmnd *cmd)
 	cmd->state = SCSI_STATE_BHQUEUE;
 	cmd->owner = SCSI_OWNER_BH_HANDLER;
 
+	atomic_inc(&cmd->device->iodone_cnt);
+	if (cmd->result)
+		atomic_inc(&cmd->device->ioerr_cnt);
+
 	/*
 	 * Next, enqueue the command into the done queue.
 	 * It is a per-CPU queue, so we just disable local interrupts
diff -puN a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- a/drivers/scsi/scsi_sysfs.c	2005-01-28 10:17:19.000000000 -0500
+++ b/drivers/scsi/scsi_sysfs.c	2005-01-28 11:16:15.000000000 -0500
@@ -408,6 +408,28 @@ show_queue_type_field(struct device *dev
 
 static DEVICE_ATTR(queue_type, S_IRUGO, show_queue_type_field, NULL);
 
+static ssize_t
+show_iostat_counterbits(struct device *dev, char *buf)
+{
+	return snprintf(buf, 20, "%d\n", sizeof(atomic_t) * 8);
+}
+
+static DEVICE_ATTR(iocounterbits, S_IRUGO, show_iostat_counterbits, NULL);
+
+#define show_sdev_iostat(field)						\
+static ssize_t								\
+show_iostat_##field(struct device *dev, char *buf)			\
+{									\
+	struct scsi_device *sdev = to_scsi_device(dev);			\
+	u64 count = (u64)atomic_read(&sdev->field);			\
+	return snprintf(buf, 20, "0x%llx\n", count);			\
+}									\
+static DEVICE_ATTR(field, S_IRUGO, show_iostat_##field, NULL)
+
+show_sdev_iostat(iorequest_cnt);
+show_sdev_iostat(iodone_cnt);
+show_sdev_iostat(ioerr_cnt);
+
 
 /* Default template for device attributes.  May NOT be modified */
 static struct device_attribute *scsi_sysfs_sdev_attrs[] = {
@@ -423,6 +445,10 @@ static struct device_attribute *scsi_sys
 	&dev_attr_delete,
 	&dev_attr_state,
 	&dev_attr_timeout,
+	&dev_attr_iocounterbits,
+	&dev_attr_iorequest_cnt,
+	&dev_attr_iodone_cnt,
+	&dev_attr_ioerr_cnt,
 	NULL
 };
 
diff -puN a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
--- a/include/scsi/scsi_device.h	2005-01-28 10:17:19.000000000 -0500
+++ b/include/scsi/scsi_device.h	2005-01-28 11:15:56.000000000 -0500
@@ -118,6 +118,10 @@ struct scsi_device {
 	unsigned int max_device_blocked; /* what device_blocked counts down from  */
 #define SCSI_DEFAULT_DEVICE_BLOCKED	3
 
+	atomic_t iorequest_cnt;
+	atomic_t iodone_cnt;
+	atomic_t ioerr_cnt;
+
 	int timeout;
 
 	struct device		sdev_gendev;
_

Copyright © 2005, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds