diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2017-09-08 21:01:38 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2017-09-28 07:29:42 +0200 |
commit | cb09b356cd43fb079ea85128dcd17e5b65585fe8 (patch) | |
tree | 06e57e540762016ae5686a474024a942c610ced2 /drivers/s390 | |
parent | d4d287e81ff1924f0791fad0638551daec7742b5 (diff) | |
download | linux-cb09b356cd43fb079ea85128dcd17e5b65585fe8.tar.gz linux-cb09b356cd43fb079ea85128dcd17e5b65585fe8.tar.bz2 linux-cb09b356cd43fb079ea85128dcd17e5b65585fe8.zip |
s390/cmf: avg_utilization
All (but one) cmf related sysfs attributes have been converted to read
directly from the measurement block using cmf_read. This is not
possible for the avg_utilization attribute since this is an aggregation
of several values for which cmf_read only returns average values.
Move the computation of the utilization value to the cmf_read interface
such that it can use the raw data.
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/cio/cmf.c | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 78fb492d9881..0b10221c4661 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c @@ -58,8 +58,9 @@ /* indices for READCMB */ enum cmb_index { + avg_utilization = -1, /* basic and exended format: */ - cmb_ssch_rsch_count, + cmb_ssch_rsch_count = 0, cmb_sample_count, cmb_device_connect_time, cmb_function_pending_time, @@ -587,12 +588,29 @@ static int set_cmb(struct ccw_device *cdev, u32 mme) return set_schib_wait(cdev, mme, 0, offset); } +/* calculate utilization in 0.1 percent units */ +static u64 __cmb_utilization(u64 device_connect_time, u64 function_pending_time, + u64 device_disconnect_time, u64 start_time) +{ + u64 utilization, elapsed_time; + + utilization = time_to_nsec(device_connect_time + + function_pending_time + + device_disconnect_time); + + elapsed_time = get_tod_clock() - start_time; + elapsed_time = tod_to_ns(elapsed_time); + elapsed_time /= 1000; + + return elapsed_time ? (utilization / elapsed_time) : 0; +} + static u64 read_cmb(struct ccw_device *cdev, int index) { struct cmb_data *cmb_data; unsigned long flags; struct cmb *cmb; - int ret = 0; + u64 ret = 0; u32 val; spin_lock_irqsave(cdev->ccwlock, flags); @@ -602,6 +620,12 @@ static u64 read_cmb(struct ccw_device *cdev, int index) cmb = cmb_data->hw_block; switch (index) { + case avg_utilization: + ret = __cmb_utilization(cmb->device_connect_time, + cmb->function_pending_time, + cmb->device_disconnect_time, + cdev->private->cmb_start_time); + goto out; case cmb_ssch_rsch_count: ret = cmb->ssch_rsch_count; goto out; @@ -841,7 +865,7 @@ static u64 read_cmbe(struct ccw_device *cdev, int index) struct cmb_data *cmb_data; unsigned long flags; struct cmbe *cmb; - int ret = 0; + u64 ret = 0; u32 val; spin_lock_irqsave(cdev->ccwlock, flags); @@ -851,6 +875,12 @@ static u64 read_cmbe(struct ccw_device *cdev, int index) cmb = cmb_data->hw_block; switch (index) { + case avg_utilization: + ret = __cmb_utilization(cmb->device_connect_time, + cmb->function_pending_time, + cmb->device_disconnect_time, + cdev->private->cmb_start_time); + goto out; case cmb_ssch_rsch_count: ret = cmb->ssch_rsch_count; goto out; @@ -989,27 +1019,9 @@ static ssize_t cmb_show_avg_utilization(struct device *dev, struct device_attribute *attr, char *buf) { - struct cmbdata data; - u64 utilization; - unsigned long t, u; - int ret; - - ret = cmf_readall(to_ccwdev(dev), &data); - if (ret == -EAGAIN || ret == -ENODEV) - /* No data (yet/currently) available to use for calculation. */ - return sprintf(buf, "n/a\n"); - else if (ret) - return ret; - - utilization = data.device_connect_time + - data.function_pending_time + - data.device_disconnect_time; - - /* calculate value in 0.1 percent units */ - t = data.elapsed_time / 1000; - u = utilization / t; + unsigned long u = cmf_read(to_ccwdev(dev), avg_utilization); - return sprintf(buf, "%02ld.%01ld%%\n", u/ 10, u - (u/ 10) * 10); + return sprintf(buf, "%02lu.%01lu%%\n", u / 10, u % 10); } #define cmf_attr(name) \ |