summaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2008-05-06 11:00:06 +0200
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-06-05 16:23:44 +0200
commit3a0d9e92356feb60ee4e978355f712366a93f4ef (patch)
treeecc4d53b2120713f80d9b6b664741f4ac7e3344b /drivers/s390/scsi
parent[SCSI] zfcp: Track fabric and channel latencies provided by FCP adapter (diff)
downloadlinux-3a0d9e92356feb60ee4e978355f712366a93f4ef.tar.xz
linux-3a0d9e92356feb60ee4e978355f712366a93f4ef.zip
[SCSI] zfcp: sysfs attributes for fabric and channel latencies
The latency information is provided on a SCSI device level (LUN) which can be found at the following location  /sys/class/scsi_device/<H:C:T:L>/device/cmd_latency  /sys/class/scsi_device/<H:C:T:L>/device/read_latency  /sys/class/scsi_device/<H:C:T:L>/device/write_latency Each sysfs attribute provides the available data: min, max and sum for fabric and channel latency and the number of requests processed. An overrun of the variables is neither detected nor treated. The file has to be read twice to make a meaningful statement, because only the differences of the values between the two reads can be used. A reset of the values can be achieved by writing to the attribute. Signed-off-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 01687559dc06..4b0c85acb0f0 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -778,6 +778,68 @@ struct fc_function_template zfcp_transport_functions = {
.disable_target_scan = 1,
};
+#define ZFCP_DEFINE_LATENCY_ATTR(_name) \
+static ssize_t \
+zfcp_sysfs_unit_##_name##_latency_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) { \
+ struct scsi_device *sdev = to_scsi_device(dev); \
+ struct zfcp_unit *unit = sdev->hostdata; \
+ struct zfcp_latencies *lat = &unit->latencies; \
+ struct zfcp_adapter *adapter = unit->port->adapter; \
+ unsigned long flags; \
+ unsigned long long fsum, fmin, fmax, csum, cmin, cmax, cc; \
+ \
+ spin_lock_irqsave(&lat->lock, flags); \
+ fsum = lat->_name.fabric.sum * adapter->timer_ticks; \
+ fmin = lat->_name.fabric.min * adapter->timer_ticks; \
+ fmax = lat->_name.fabric.max * adapter->timer_ticks; \
+ csum = lat->_name.channel.sum * adapter->timer_ticks; \
+ cmin = lat->_name.channel.min * adapter->timer_ticks; \
+ cmax = lat->_name.channel.max * adapter->timer_ticks; \
+ cc = lat->_name.counter; \
+ spin_unlock_irqrestore(&lat->lock, flags); \
+ \
+ do_div(fsum, 1000); \
+ do_div(fmin, 1000); \
+ do_div(fmax, 1000); \
+ do_div(csum, 1000); \
+ do_div(cmin, 1000); \
+ do_div(cmax, 1000); \
+ \
+ return sprintf(buf, "%llu %llu %llu %llu %llu %llu %llu\n", \
+ fmin, fmax, fsum, cmin, cmax, csum, cc); \
+} \
+static ssize_t \
+zfcp_sysfs_unit_##_name##_latency_store(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t count) \
+{ \
+ struct scsi_device *sdev = to_scsi_device(dev); \
+ struct zfcp_unit *unit = sdev->hostdata; \
+ struct zfcp_latencies *lat = &unit->latencies; \
+ unsigned long flags; \
+ \
+ spin_lock_irqsave(&lat->lock, flags); \
+ lat->_name.fabric.sum = 0; \
+ lat->_name.fabric.min = 0xFFFFFFFF; \
+ lat->_name.fabric.max = 0; \
+ lat->_name.channel.sum = 0; \
+ lat->_name.channel.min = 0xFFFFFFFF; \
+ lat->_name.channel.max = 0; \
+ lat->_name.counter = 0; \
+ spin_unlock_irqrestore(&lat->lock, flags); \
+ \
+ return (ssize_t) count; \
+} \
+static DEVICE_ATTR(_name##_latency, S_IWUSR | S_IRUGO, \
+ zfcp_sysfs_unit_##_name##_latency_show, \
+ zfcp_sysfs_unit_##_name##_latency_store);
+
+ZFCP_DEFINE_LATENCY_ATTR(read);
+ZFCP_DEFINE_LATENCY_ATTR(write);
+ZFCP_DEFINE_LATENCY_ATTR(cmd);
+
/**
* ZFCP_DEFINE_SCSI_ATTR
* @_name: name of show attribute
@@ -808,6 +870,9 @@ static struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
&dev_attr_fcp_lun,
&dev_attr_wwpn,
&dev_attr_hba_id,
+ &dev_attr_read_latency,
+ &dev_attr_write_latency,
+ &dev_attr_cmd_latency,
NULL
};