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>
This commit is contained in:
parent
d4d287e81f
commit
cb09b356cd
@ -58,8 +58,9 @@
|
|||||||
|
|
||||||
/* indices for READCMB */
|
/* indices for READCMB */
|
||||||
enum cmb_index {
|
enum cmb_index {
|
||||||
|
avg_utilization = -1,
|
||||||
/* basic and exended format: */
|
/* basic and exended format: */
|
||||||
cmb_ssch_rsch_count,
|
cmb_ssch_rsch_count = 0,
|
||||||
cmb_sample_count,
|
cmb_sample_count,
|
||||||
cmb_device_connect_time,
|
cmb_device_connect_time,
|
||||||
cmb_function_pending_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);
|
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)
|
static u64 read_cmb(struct ccw_device *cdev, int index)
|
||||||
{
|
{
|
||||||
struct cmb_data *cmb_data;
|
struct cmb_data *cmb_data;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct cmb *cmb;
|
struct cmb *cmb;
|
||||||
int ret = 0;
|
u64 ret = 0;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
spin_lock_irqsave(cdev->ccwlock, flags);
|
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;
|
cmb = cmb_data->hw_block;
|
||||||
switch (index) {
|
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:
|
case cmb_ssch_rsch_count:
|
||||||
ret = cmb->ssch_rsch_count;
|
ret = cmb->ssch_rsch_count;
|
||||||
goto out;
|
goto out;
|
||||||
@ -841,7 +865,7 @@ static u64 read_cmbe(struct ccw_device *cdev, int index)
|
|||||||
struct cmb_data *cmb_data;
|
struct cmb_data *cmb_data;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct cmbe *cmb;
|
struct cmbe *cmb;
|
||||||
int ret = 0;
|
u64 ret = 0;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
spin_lock_irqsave(cdev->ccwlock, flags);
|
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;
|
cmb = cmb_data->hw_block;
|
||||||
switch (index) {
|
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:
|
case cmb_ssch_rsch_count:
|
||||||
ret = cmb->ssch_rsch_count;
|
ret = cmb->ssch_rsch_count;
|
||||||
goto out;
|
goto out;
|
||||||
@ -989,27 +1019,9 @@ static ssize_t cmb_show_avg_utilization(struct device *dev,
|
|||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
char *buf)
|
char *buf)
|
||||||
{
|
{
|
||||||
struct cmbdata data;
|
unsigned long u = cmf_read(to_ccwdev(dev), avg_utilization);
|
||||||
u64 utilization;
|
|
||||||
unsigned long t, u;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = cmf_readall(to_ccwdev(dev), &data);
|
return sprintf(buf, "%02lu.%01lu%%\n", u / 10, u % 10);
|
||||||
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;
|
|
||||||
|
|
||||||
return sprintf(buf, "%02ld.%01ld%%\n", u/ 10, u - (u/ 10) * 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define cmf_attr(name) \
|
#define cmf_attr(name) \
|
||||||
|
Loading…
Reference in New Issue
Block a user