Skip to content

Commit 87c87b9

Browse files
committed
timer/linux: prevent 64-bit overflow
The linux timer code was multiplying the result of the x86 time stamp counter by 1000000 before dividing by the cpu frequency. This can cause us to overflow 64 bits if the time stamp counter grows larger than ~ 1.8e13 (about 8400 seconds after boot). To fix the issue the units of opal_timer_linux_freq have been changed to MHz. Signed-off-by: Nathan Hjelm <[email protected]> (cherry picked from commit 45c0588) Signed-off-by: Nathan Hjelm <[email protected]>
1 parent b37a50d commit 87c87b9

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

opal/mca/timer/linux/timer_linux_component.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* All rights reserved.
1313
* Copyright (c) 2015 Research Organization for Information Science
1414
* and Technology (RIST). All rights reserved.
15-
* Copyright (c) 2015-2016 Los Alamos National Security, LLC. All rights
15+
* Copyright (c) 2015-2017 Los Alamos National Security, LLC. All rights
1616
* reserved.
1717
* Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
1818
* Copyright (c) 2017 IBM Corporation. All rights reserved.
@@ -148,6 +148,10 @@ static int opal_timer_linux_find_freq(void)
148148

149149
fclose(fp);
150150

151+
/* convert the timer frequency to MHz to avoid an extra operation when
152+
* converting from cycles to usec */
153+
opal_timer_linux_freq /= 1000000;
154+
151155
return OPAL_SUCCESS;
152156
}
153157

@@ -159,7 +163,7 @@ int opal_timer_linux_open(void)
159163
#if OPAL_HAVE_CLOCK_GETTIME && (0 == OPAL_TIMER_MONOTONIC)
160164
struct timespec res;
161165
if( 0 == clock_getres(CLOCK_MONOTONIC, &res)) {
162-
opal_timer_linux_freq = 1.e9;
166+
opal_timer_linux_freq = 1.e3;
163167
opal_timer_base_get_cycles = opal_timer_base_get_cycles_clock_gettime;
164168
opal_timer_base_get_usec = opal_timer_base_get_usec_clock_gettime;
165169
return ret;
@@ -208,16 +212,16 @@ opal_timer_t opal_timer_base_get_cycles_sys_timer(void)
208212
opal_timer_t opal_timer_base_get_usec_sys_timer(void)
209213
{
210214
#if OPAL_HAVE_SYS_TIMER_GET_CYCLES
211-
/* freq is in Hz, so this gives usec */
212-
return opal_sys_timer_get_cycles() * 1000000 / opal_timer_linux_freq;
215+
/* freq is in MHz, so this gives usec */
216+
return opal_sys_timer_get_cycles() / opal_timer_linux_freq;
213217
#else
214218
return 0;
215219
#endif
216220
}
217221

218222
opal_timer_t opal_timer_base_get_freq(void)
219223
{
220-
return opal_timer_linux_freq;
224+
return opal_timer_linux_freq * 1000000;
221225
}
222226

223227

0 commit comments

Comments
 (0)