Skip to content

Commit

Permalink
DiskIOMeter: draw normalized utilization; show utilization above 100%
Browse files Browse the repository at this point in the history
The utilization percentage of DiskIOMeter is an accumulated total of
all disks, and for multiple disks, utilization above 100% is possible.
The maximum utilization should be "100% * number of disks". Set the bar
and graph of the meter to draw with that maximum.

Thanks to Nathan Scott for providing the PCP portion of the patch.

Resolves #1374.

Co-authored-by: Nathan Scott <nathans@redhat.com>
Signed-off-by: Kang-Che Sung <explorer09@gmail.com>
  • Loading branch information
Explorer09 and natoscott committed Sep 20, 2024
1 parent 49bb3c4 commit 03a8e22
Show file tree
Hide file tree
Showing 9 changed files with 31 additions and 5 deletions.
14 changes: 9 additions & 5 deletions DiskIOMeter.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ static MeterRateStatus status = RATESTATUS_INIT;
static char cached_read_diff_str[6];
static char cached_write_diff_str[6];
static double cached_utilisation_diff;
static double cached_utilisation_norm;

static void DiskIOMeter_updateValues(Meter* this) {
const Machine* host = this->host;
Expand Down Expand Up @@ -82,12 +83,15 @@ static void DiskIOMeter_updateValues(Meter* this) {
}
Meter_humanUnit(cached_write_diff_str, diff, sizeof(cached_write_diff_str));

cached_utilisation_diff = 0.0;
cached_utilisation_norm = 0.0;
if (data.totalMsTimeSpend > cached_msTimeSpend_total) {
diff = data.totalMsTimeSpend - cached_msTimeSpend_total;
cached_utilisation_diff = 100.0 * (double)diff / passedTimeInMs;
cached_utilisation_diff = MINIMUM(cached_utilisation_diff, 100.0);
} else {
cached_utilisation_diff = 0.0;
if (data.numDisks > 0) {
cached_utilisation_norm = (double)diff / (passedTimeInMs * data.numDisks);
cached_utilisation_norm = MINIMUM(cached_utilisation_norm, 1.0);
}
}
}

Expand All @@ -96,7 +100,7 @@ static void DiskIOMeter_updateValues(Meter* this) {
cached_msTimeSpend_total = data.totalMsTimeSpend;
}

this->values[0] = cached_utilisation_diff;
this->values[0] = cached_utilisation_norm;

if (status == RATESTATUS_NODATA) {
xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "no data");
Expand Down Expand Up @@ -154,7 +158,7 @@ const MeterClass DiskIOMeter_class = {
.defaultMode = TEXT_METERMODE,
.supportedModes = METERMODE_DEFAULT_SUPPORTED,
.maxItems = 1,
.total = 100.0,
.total = 1.0,
.attributes = DiskIOMeter_attributes,
.name = "DiskIO",
.uiName = "Disk IO",
Expand Down
1 change: 1 addition & 0 deletions DiskIOMeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ typedef struct DiskIOData_ {
uint64_t totalBytesRead;
uint64_t totalBytesWritten;
uint64_t totalMsTimeSpend;
uint64_t numDisks;
} DiskIOData;

extern const MeterClass DiskIOMeter_class;
Expand Down
4 changes: 4 additions & 0 deletions darwin/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ bool Platform_getDiskIO(DiskIOData* data) {
return false;

unsigned long long int read_sum = 0, write_sum = 0, timeSpend_sum = 0;
unsigned long long int numDisks = 0;

io_registry_entry_t drive;
while ((drive = IOIteratorNext(drive_list)) != 0) {
Expand Down Expand Up @@ -433,6 +434,8 @@ bool Platform_getDiskIO(DiskIOData* data) {
continue;
}

numDisks++;

CFNumberRef number;
unsigned long long int value;

Expand Down Expand Up @@ -471,6 +474,7 @@ bool Platform_getDiskIO(DiskIOData* data) {
data->totalBytesRead = read_sum;
data->totalBytesWritten = write_sum;
data->totalMsTimeSpend = timeSpend_sum / 1e6; /* Convert from ns to ms */
data->numDisks = numDisks;

if (drive_list)
IOObjectRelease(drive_list);
Expand Down
3 changes: 3 additions & 0 deletions dragonflybsd/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ bool Platform_getDiskIO(DiskIOData* data) {
uint64_t bytesReadSum = 0;
uint64_t bytesWriteSum = 0;
uint64_t busyMsTimeSum = 0;
uint64_t numDisks = 0;

for (int i = 0; i < dev_stats.dinfo->numdevs; i++) {
const struct devstat* device = &dev_stats.dinfo->devices[dev_sel[i].position];
Expand All @@ -301,11 +302,13 @@ bool Platform_getDiskIO(DiskIOData* data) {
bytesReadSum += device->bytes_read;
bytesWriteSum += device->bytes_written;
busyMsTimeSum += (device->busy_time.tv_sec * 1000 + device->busy_time.tv_usec / 1000);
numDisks++;
}

data->totalBytesRead = bytesReadSum;
data->totalBytesWritten = bytesWriteSum;
data->totalMsTimeSpend = busyMsTimeSum;
data->numDisks = numDisks;

free(dev_stats.dinfo);
return true;
Expand Down
3 changes: 3 additions & 0 deletions freebsd/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ bool Platform_getDiskIO(DiskIOData* data) {
int count = current.dinfo->numdevs;

unsigned long long int bytesReadSum = 0, bytesWriteSum = 0, timeSpendSum = 0;
unsigned long long int numDisks = 0;

// get data
for (int i = 0; i < count; i++) {
Expand All @@ -330,11 +331,13 @@ bool Platform_getDiskIO(DiskIOData* data) {
bytesReadSum += bytes_read;
bytesWriteSum += bytes_write;
timeSpendSum += 1000 * busy_time;
numDisks++;
}

data->totalBytesRead = bytesReadSum;
data->totalBytesWritten = bytesWriteSum;
data->totalMsTimeSpend = timeSpendSum;
data->numDisks = numDisks;
return true;
}

Expand Down
3 changes: 3 additions & 0 deletions linux/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,7 @@ bool Platform_getDiskIO(DiskIOData* data) {
char lastTopDisk[32] = { '\0' };

unsigned long long int read_sum = 0, write_sum = 0, timeSpend_sum = 0;
unsigned long long int numDisks = 0;
char lineBuffer[256];
while (fgets(lineBuffer, sizeof(lineBuffer), fp)) {
char diskname[32];
Expand All @@ -635,13 +636,15 @@ bool Platform_getDiskIO(DiskIOData* data) {
read_sum += read_tmp;
write_sum += write_tmp;
timeSpend_sum += timeSpend_tmp;
numDisks++;
}
}
fclose(fp);
/* multiply with sector size */
data->totalBytesRead = 512 * read_sum;
data->totalBytesWritten = 512 * write_sum;
data->totalMsTimeSpend = timeSpend_sum;
data->numDisks = numDisks;
return true;
}

Expand Down
3 changes: 3 additions & 0 deletions netbsd/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ bool Platform_getDiskIO(DiskIOData* data) {
uint64_t bytesReadSum = 0;
uint64_t bytesWriteSum = 0;
uint64_t busyTimeSum = 0;
uint64_t numDisks = 0;

for (size_t i = 0, count = size / sizeof(struct io_sysctl); i < count; i++) {
/* ignore NFS activity */
Expand All @@ -393,11 +394,13 @@ bool Platform_getDiskIO(DiskIOData* data) {
bytesReadSum += iostats[i].rbytes;
bytesWriteSum += iostats[i].wbytes;
busyTimeSum += iostats[i].busysum_usec;
numDisks++;
}

data->totalBytesRead = bytesReadSum;
data->totalBytesWritten = bytesWriteSum;
data->totalMsTimeSpend = busyTimeSum / 1000;
data->numDisks = numDisks;

free(iostats);
return true;
Expand Down
1 change: 1 addition & 0 deletions pcp/Metric.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ typedef enum Metric_ {
PCP_CONTROL_THREADS, /* proc.control.perclient.threads */

PCP_HINV_NCPU, /* hinv.ncpu */
PCP_HINV_NDISK, /* hinv.ndisk */
PCP_HINV_CPUCLOCK, /* hinv.cpu.clock */
PCP_UNAME_SYSNAME, /* kernel.uname.sysname */
PCP_UNAME_RELEASE, /* kernel.uname.release */
Expand Down
4 changes: 4 additions & 0 deletions pcp/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ static const char* Platform_metricNames[] = {
[PCP_CONTROL_THREADS] = "proc.control.perclient.threads",

[PCP_HINV_NCPU] = "hinv.ncpu",
[PCP_HINV_NDISK] = "hinv.ndisk",
[PCP_HINV_CPUCLOCK] = "hinv.cpu.clock",
[PCP_UNAME_SYSNAME] = "kernel.uname.sysname",
[PCP_UNAME_RELEASE] = "kernel.uname.release",
Expand Down Expand Up @@ -385,6 +386,7 @@ bool Platform_init(void) {
Metric_enable(PCP_PID_MAX, true);
Metric_enable(PCP_BOOTTIME, true);
Metric_enable(PCP_HINV_NCPU, true);
Metric_enable(PCP_HINV_NDISK, true);
Metric_enable(PCP_PERCPU_SYSTEM, true);
Metric_enable(PCP_UNAME_SYSNAME, true);
Metric_enable(PCP_UNAME_RELEASE, true);
Expand Down Expand Up @@ -753,6 +755,8 @@ bool Platform_getDiskIO(DiskIOData* data) {
data->totalBytesWritten = value.ull;
if (Metric_values(PCP_DISK_ACTIVE, &value, 1, PM_TYPE_U64) != NULL)
data->totalMsTimeSpend = value.ull;
if (Metric_values(PCP_HINV_NDISK, &value, 1, PM_TYPE_U64) != NULL)
data->numDisks = value.ull;
return true;
}

Expand Down

0 comments on commit 03a8e22

Please sign in to comment.