We have three problems:
1) libperfstat perfstat_diskadapter() always returns xrate = 0
2) xlc and gcc handle the resulting long long unsigned divide by zero differently
xlc returns 2147483647
gcc returns zero
3) The /usr/samples/libperfstat/simpleadapterstat.c code is also broken
a) for ( int i = 0; .... <- "int" inside a for loop!!! It compiles but GCC complains stating this only was valid in the 1999 C standard!
b) the Average Reads/write per second calculations are very wrong
should be the delta(xrate) / interval
and ( delta(xfer) - delta(xrate) ) / interval
I hope that helps, cheers Nigel
My sample program - in case it helps.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <libperfstat.h>
#include <errno.h>
int main(int argc, char* argv[])
{
int i;
int rc;
int num_adapt = 0;
perfstat_id_t first;
perfstat_diskadapter_t *statp;
num_adapt = perfstat_diskadapter(NULL, NULL, sizeof(perfstat_diskadapter_t), 0);
statp = malloc((sizeof(perfstat_diskadapter_t) * num_adapt));
strcpy(first.name, FIRST_DISKADAPTER);
rc = perfstat_diskadapter(&first ,statp, sizeof(perfstat_diskadapter_t),num_adapt);
printf("received %d structures\n",rc);
for(i=0;i<num_adapt;i++) {
printf("%d: name=%s disks=%d wblks=%llu rblks=%llu xfers=%llu xrate=%llu test=%llu\n",
i, statp[i].name, statp[i].number, statp[i].wblks, statp[i].rblks, statp[i].xfers, statp[i].xrate, statp[i].rblks / statp[i].xrate);
}
printf("---\n");
sleep(2);
strcpy(first.name, FIRST_DISKADAPTER);
rc = perfstat_diskadapter(&first ,statp, sizeof(perfstat_diskadapter_t),num_adapt);
printf("received %d structures\n",rc);
for(i=0;i<num_adapt;i++) {
printf("%d: name=%s disks=%d wblks=%llu rblks=%llu xfers=%llu xrate=%llu test=%llu\n",
i, statp[i].name, statp[i].number, statp[i].wblks, statp[i].rblks, statp[i].xfers, statp[i].xrate, statp[i].rblks / statp[i].xrate);
}
}
------------------------------
Nigel Griffiths
------------------------------
Original Message:
Sent: Fri August 28, 2020 05:58 AM
From: Roman Aleksic
Subject: libperfstat and gcc
We are collecting system performance data with njmon. The diskadapter (vscsiX, fcsX) reads are always reported as 0. Adapter writes on the other hand show expected values. Since njmon uses the libperfstat library to collect the performance data, we have compiled the sample program simpleadapterstat.c (/usr/samples/libperfstat/simpleadapterstat.c, part of bos.perf.libperfstat lpp) to verfiy the data source. simpleadapterstat also always reports adapter reads with a value of 0.
We've opened a PMR with IBM (TS003801866) and found that it seems a problem with the gcc compiler:
- gcc-8.1.0-2 -> reads (ARS) always 0
- gcc-8.3.0-2 -> reads (ARS) always 0
- xlCcmp.13.1.3.0 -> correct read (ARS) values
We could observe this on the following AIX Levels:
7200-04-02-2028 - bos.perf.libperfstat 7.2.4.1
7200-04-01-1939 - bos.perf.libperfstat 7.2.4.0
7200-03-03-1914 - bos.perf.libperfstat 7.2.3.16
------------------------------
Thanks,
Roman
------------------------------