Bug 2158214

Summary: gettimeofday with 32bit compiled applications bypasses VDSO and does system calls
Product: Red Hat Enterprise Linux 7 Reporter: Konrad Rzeszutek Wilk <ketuzsezr>
Component: glibcAssignee: glibc team <glibc-bugzilla>
Status: CLOSED WONTFIX QA Contact: qe-baseos-tools-bugs
Severity: medium Docs Contact:
Priority: unspecified    
Version: 7.9CC: ashankar, codonell, dj, fweimer, mnewsome, pfrankli, sipoyare
Target Milestone: rcKeywords: FutureFeature, Triaged
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2023-01-27 14:16:21 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Konrad Rzeszutek Wilk 2023-01-04 17:03:41 UTC
Description of problem:

With this test-case:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>

#define ROUNDS 10000000LL
int main()
{
        struct timeval start, stop, data;
        unsigned long long round, delta;

        memset(&start, 0, sizeof(start));
        memset(&stop, 0, sizeof(start));
        memset(&data, 0, sizeof(start));

        gettimeofday(&start, NULL);
        for (round = 0; round < ROUNDS; round++)
                gettimeofday(&data, NULL);
        gettimeofday(&stop, NULL);

        delta= (stop.tv_sec - start.tv_sec)*1000*1000LL +
                (stop.tv_usec - start.tv_usec);
        printf("%lld us/%lld rounds = %lldns/call\n", delta, ROUNDS,
                (delta*1000)/ROUNDS);

        return 0;
}

We are observing that on RHEL7 compiled with -m32 that
the  performance is dreadfull:

[root@ca-dev79 tmp]# perf stat -e raw_syscalls:sys_enter ./b32
5094205 us/10000000 rounds = 509ns/call

 Performance counter stats for './b32':

        10,000,029      raw_syscalls:sys_enter

       5.094769829 seconds time elapsed

       2.648550000 seconds user
       2.438753000 seconds sys


[root@ca-dev79 tmp]# perf stat -e raw_syscalls:sys_enter ./b64
168858 us/10000000 rounds = 16ns/call

 Performance counter stats for './b64':

                28      raw_syscalls:sys_enter

       0.169371141 seconds time elapsed

       0.169144000 seconds user
       0.000000000 seconds sys



We have narrowed it down to this backport:

https://sourceware.org/git/?p=glibc.git;a=commit;h=ca677d3c3cd0eba7d1f03092517aea553a0e8569
Add x86 32 bit vDSO time function support

which is missing from glibc 2.17.

Version-Release number of selected component (if applicable):

glibc-2.17

How reproducible:

100%

Steps to Reproduce:
1. Use the test-case. Compile a 32-bit and 64-bit
2. See 32-bit using system calls while 64 bit is using VDSO
3.

Actual results:

32-bit on par-ish with 64-bit
Expected results:


Additional info:

Backport of 
https://sourceware.org/git/?p=glibc.git;a=commit;h=ca677d3c3cd0eba7d1f03092517aea553a0e8569
Add x86 32 bit vDSO time function support

should do the trick

Comment 7 Florian Weimer 2023-01-27 14:16:21 UTC
This kind of change is generally out of scope for the current life-cycle phase of Red Hat Enterprise Linux 7: <https://access.redhat.com/support/policy/updates/errata/>

Please file a support case under <https://access.redhat.com/support/cases/> if you are able to provide sufficient business justification for including this change. We expect the backport to have higher risk than usual, so an extraordinary justification will likely be needed.