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 <hjelmn@lanl.gov>
Этот коммит содержится в:
родитель
269e5e3e87
Коммит
45c05880aa
@ -12,7 +12,7 @@
|
|||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
* Copyright (c) 2015 Research Organization for Information Science
|
* Copyright (c) 2015 Research Organization for Information Science
|
||||||
* and Technology (RIST). All rights reserved.
|
* and Technology (RIST). All rights reserved.
|
||||||
* Copyright (c) 2015-2016 Los Alamos National Security, LLC. All rights
|
* Copyright (c) 2015-2017 Los Alamos National Security, LLC. All rights
|
||||||
* reserved.
|
* reserved.
|
||||||
* Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
|
* Copyright (c) 2015 Cisco Systems, Inc. All rights reserved.
|
||||||
* Copyright (c) 2016 Broadcom Limited. All rights reserved.
|
* Copyright (c) 2016 Broadcom Limited. All rights reserved.
|
||||||
@ -155,6 +155,10 @@ static int opal_timer_linux_find_freq(void)
|
|||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
/* convert the timer frequency to MHz to avoid an extra operation when
|
||||||
|
* converting from cycles to usec */
|
||||||
|
opal_timer_linux_freq /= 1000000;
|
||||||
|
|
||||||
return OPAL_SUCCESS;
|
return OPAL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +170,7 @@ int opal_timer_linux_open(void)
|
|||||||
#if OPAL_HAVE_CLOCK_GETTIME && (0 == OPAL_TIMER_MONOTONIC)
|
#if OPAL_HAVE_CLOCK_GETTIME && (0 == OPAL_TIMER_MONOTONIC)
|
||||||
struct timespec res;
|
struct timespec res;
|
||||||
if( 0 == clock_getres(CLOCK_MONOTONIC, &res)) {
|
if( 0 == clock_getres(CLOCK_MONOTONIC, &res)) {
|
||||||
opal_timer_linux_freq = 1.e9;
|
opal_timer_linux_freq = 1.e3;
|
||||||
opal_timer_base_get_cycles = opal_timer_base_get_cycles_clock_gettime;
|
opal_timer_base_get_cycles = opal_timer_base_get_cycles_clock_gettime;
|
||||||
opal_timer_base_get_usec = opal_timer_base_get_usec_clock_gettime;
|
opal_timer_base_get_usec = opal_timer_base_get_usec_clock_gettime;
|
||||||
return ret;
|
return ret;
|
||||||
@ -215,8 +219,8 @@ opal_timer_t opal_timer_base_get_cycles_sys_timer(void)
|
|||||||
opal_timer_t opal_timer_base_get_usec_sys_timer(void)
|
opal_timer_t opal_timer_base_get_usec_sys_timer(void)
|
||||||
{
|
{
|
||||||
#if OPAL_HAVE_SYS_TIMER_GET_CYCLES
|
#if OPAL_HAVE_SYS_TIMER_GET_CYCLES
|
||||||
/* freq is in Hz, so this gives usec */
|
/* freq is in MHz, so this gives usec */
|
||||||
return opal_sys_timer_get_cycles() * 1000000 / opal_timer_linux_freq;
|
return opal_sys_timer_get_cycles() / opal_timer_linux_freq;
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
@ -224,7 +228,7 @@ opal_timer_t opal_timer_base_get_usec_sys_timer(void)
|
|||||||
|
|
||||||
opal_timer_t opal_timer_base_get_freq(void)
|
opal_timer_t opal_timer_base_get_freq(void)
|
||||||
{
|
{
|
||||||
return opal_timer_linux_freq;
|
return opal_timer_linux_freq * 1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user