AIX Open Source

 View Only
Expand all | Collapse all

libperfstat and gcc

  • 1.  libperfstat and gcc

    Posted Fri August 28, 2020 06:40 AM
    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
    ------------------------------


  • 2.  RE: libperfstat and gcc

    Posted Fri August 28, 2020 06:43 AM
    Is it possible to share your simpleadapterstat.c code and what compilation flags you used to compile ? 

    ------------------------------
    SANKET RATHI
    ------------------------------



  • 3.  RE: libperfstat and gcc

    Posted Fri August 28, 2020 07:49 AM
    Sure, see attached files.

    ------------------------------
    Roman Aleksic
    ------------------------------

    Attachment(s)

    c
    simpleadapterstat.c   9 KB 1 version
    txt
    Makefile.txt   3 KB 1 version


  • 4.  RE: libperfstat and gcc

    Posted Tue October 20, 2020 05:59 AM
    Hi Sanket. Do you have any news? Could you try to compile the simpleadapterstat.c?

    ------------------------------
    Roman Aleksic
    ------------------------------



  • 5.  RE: libperfstat and gcc

    Posted Tue October 20, 2020 06:45 AM
    Hi Roman, As Nigel mentioned in the post that this is not a problem with gcc because divide by zero is an undefined behavior. The real problem in the simpleadapterstat.c code where the calculation is wrong and perfstat_diskadapter() is always returning zero. I would recommend to open a case for AIX.
    Another option is to use the code provided by Nigel. 


    ------------------------------
    SANKET RATHI
    ------------------------------



  • 6.  RE: libperfstat and gcc

    Posted Tue October 27, 2020 01:28 PM
    Hi Sanket,

    Thank you for your reply. 

    • simpleadapterstat.c code where the calculation is wrong -> not an issue for us
    • perfstat_diskadapter() is always returning zero -> according to PMR TS003801866 this is not the case
    @Nigel Griffiths did you find any solution for the zero-reads in njmon?

    ------------------------------
    Roman Aleksic
    ------------------------------



  • 7.  RE: libperfstat and gcc

    Posted Wed October 28, 2020 01:02 PM
    Hi Roman,

    Are you saying that when you compile simpleadapter.c with xlc you are seeing perfstat_diskadapter() is not returning zero ? 
    If I remember correctly with xlc also it returns zero. 


    ------------------------------
    SANKET RATHI
    ------------------------------



  • 8.  RE: libperfstat and gcc

    Posted Fri November 06, 2020 03:39 AM
    Hi Sanket,

    Yes exactly. When compiling with xlC adapter reads are shown (don't know if the values accurate though), but compiling with gcc always shows zero adapter reads.

    ------------------------------
    Roman Aleksic
    ------------------------------



  • 9.  RE: libperfstat and gcc

    Posted Mon November 09, 2020 12:27 PM
    Edited by SANKET RATHI Tue November 10, 2020 06:18 AM
    Hi Roman,

    The issue is, perfstat_diskadapter() always returning xrate as zero and this is used for division. Division by zero is unspecified behavior and it is handled by different compilers differently. Hence this is not an issue with compiler (gcc). To verify you can do simple test. Add the following line in simpleadapterstat.c after line 219 then compile with both xlc and gcc. You will see that xrate is always zero in both the compilers. 
    printf("xfers=%llu, xrate=%llu\n", statp[i].xfers, statp[i].xrate);

    At line 218 this expression  (u_longlong_t)(delta_read / (statp[i].xrate - statq[i].xrate)) is division by zero hence it is returning different results for gcc and xlc.

    You new simpleadaterstat.c will look like following around line 218

    +210 /* print statistics for each of the diskadapter */
    +211 for (int i = 0; i < rc; i++) {
    +212 delta_write = statp[i].wblks - statq[i].wblks;
    +213 delta_read = statp[i].rblks - statq[i].rblks;
    +214 delta_xfers = statp[i].xfers - statq[i].xfers;
    +215 delta_xrate = statp[i].xrate - statq[i].xrate;
    +216
    +217 printf("%-8s %7d %8llu %8llu %8llu %8llu\n", statp[i].name, statp[i].number,
    +218 statp[i].size, statp[i].free, (u_longlong_t)(delta_read / (statp[i].xrate - statq[i].xrate)),
    +219 (u_longlong_t)(delta_write / (delta_xfers - delta_xrate)));
    +220 printf("xfers=%llu, xrate=%llu\n", statp[i].xfers,statp[i].xrate);
    +221 }

    ------------------------------
    SANKET RATHI
    ------------------------------



  • 10.  RE: libperfstat and gcc

    Posted Tue November 10, 2020 05:09 AM
    Hi Sanket,

    Thank you for taking the time to explain it in such detail and providing the example. I've opened another PMR and referenced this thread.



    ------------------------------
    Roman Aleksic
    ------------------------------



  • 11.  RE: libperfstat and gcc

    Posted Fri August 28, 2020 10:57 AM
    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
    ------------------------------



  • 12.  RE: libperfstat and gcc

    Posted Thu September 03, 2020 06:49 AM
    Thanks nigel,
    Yes. divide by zero is an undefined behavior and program shouldn't depend on it's result.
    May be program needs to be modified to check for zero.

    ------------------------------
    SANGAMESH
    ------------------------------