Fix uninitialized nstime reading / updating on the stack in hpa.

In order for nstime_update to handle non-monotonic clocks, it requires the input
nstime to be initialized -- when reading for the first time, zero init has to be
done.  Otherwise random stack value may be seen as clocks and returned.
This commit is contained in:
Qi Wang 2021-11-16 12:40:34 -08:00 committed by Qi Wang
parent 8b81d3f214
commit 400c59895a
4 changed files with 15 additions and 9 deletions

View File

@ -8,7 +8,7 @@ struct hpa_hooks_s {
void (*purge)(void *ptr, size_t size); void (*purge)(void *ptr, size_t size);
void (*hugify)(void *ptr, size_t size); void (*hugify)(void *ptr, size_t size);
void (*dehugify)(void *ptr, size_t size); void (*dehugify)(void *ptr, size_t size);
void (*curtime)(nstime_t *r_time); void (*curtime)(nstime_t *r_time, bool first_reading);
}; };
extern hpa_hooks_t hpa_hooks_default; extern hpa_hooks_t hpa_hooks_default;

View File

@ -347,7 +347,7 @@ hpa_update_purge_hugify_eligibility(tsdn_t *tsdn, hpa_shard_t *shard,
if (hpa_good_hugification_candidate(shard, ps) if (hpa_good_hugification_candidate(shard, ps)
&& !hpdata_huge_get(ps)) { && !hpdata_huge_get(ps)) {
nstime_t now; nstime_t now;
shard->central->hooks.curtime(&now); shard->central->hooks.curtime(&now, /* first_reading */ true);
hpdata_allow_hugify(ps, now); hpdata_allow_hugify(ps, now);
} }
/* /*
@ -437,7 +437,8 @@ hpa_try_purge(tsdn_t *tsdn, hpa_shard_t *shard) {
shard->npending_purge -= num_to_purge; shard->npending_purge -= num_to_purge;
shard->stats.npurge_passes++; shard->stats.npurge_passes++;
shard->stats.npurges += purges_this_pass; shard->stats.npurges += purges_this_pass;
shard->central->hooks.curtime(&shard->last_purge); shard->central->hooks.curtime(&shard->last_purge,
/* first_reading */ false);
if (dehugify) { if (dehugify) {
shard->stats.ndehugifies++; shard->stats.ndehugifies++;
} }
@ -477,7 +478,7 @@ hpa_try_hugify(tsdn_t *tsdn, hpa_shard_t *shard) {
/* Make sure that it's been hugifiable for long enough. */ /* Make sure that it's been hugifiable for long enough. */
nstime_t time_hugify_allowed = hpdata_time_hugify_allowed(to_hugify); nstime_t time_hugify_allowed = hpdata_time_hugify_allowed(to_hugify);
nstime_t nstime; nstime_t nstime;
shard->central->hooks.curtime(&nstime); shard->central->hooks.curtime(&nstime, /* first_reading */ true);
nstime_subtract(&nstime, &time_hugify_allowed); nstime_subtract(&nstime, &time_hugify_allowed);
uint64_t millis = nstime_msec(&nstime); uint64_t millis = nstime_msec(&nstime);
if (millis < shard->opts.hugify_delay_ms) { if (millis < shard->opts.hugify_delay_ms) {
@ -895,7 +896,8 @@ hpa_time_until_deferred_work(tsdn_t *tsdn, pai_t *self) {
nstime_t time_hugify_allowed = nstime_t time_hugify_allowed =
hpdata_time_hugify_allowed(to_hugify); hpdata_time_hugify_allowed(to_hugify);
nstime_t nstime; nstime_t nstime;
shard->central->hooks.curtime(&nstime); shard->central->hooks.curtime(&nstime,
/* first_reading */ true);
nstime_subtract(&nstime, &time_hugify_allowed); nstime_subtract(&nstime, &time_hugify_allowed);
uint64_t since_hugify_allowed_ms = nstime_msec(&nstime); uint64_t since_hugify_allowed_ms = nstime_msec(&nstime);
/* /*
@ -921,7 +923,8 @@ hpa_time_until_deferred_work(tsdn_t *tsdn, pai_t *self) {
return BACKGROUND_THREAD_DEFERRED_MIN; return BACKGROUND_THREAD_DEFERRED_MIN;
} }
nstime_t nstime; nstime_t nstime;
shard->central->hooks.curtime(&nstime); shard->central->hooks.curtime(&nstime,
/* first_reading */ true);
nstime_subtract(&nstime, &shard->last_purge); nstime_subtract(&nstime, &shard->last_purge);
uint64_t since_last_purge_ms = nstime_msec(&nstime); uint64_t since_last_purge_ms = nstime_msec(&nstime);

View File

@ -8,7 +8,7 @@ static void hpa_hooks_unmap(void *ptr, size_t size);
static void hpa_hooks_purge(void *ptr, size_t size); static void hpa_hooks_purge(void *ptr, size_t size);
static void hpa_hooks_hugify(void *ptr, size_t size); static void hpa_hooks_hugify(void *ptr, size_t size);
static void hpa_hooks_dehugify(void *ptr, size_t size); static void hpa_hooks_dehugify(void *ptr, size_t size);
static void hpa_hooks_curtime(nstime_t *r_nstime); static void hpa_hooks_curtime(nstime_t *r_nstime, bool first_reading);
hpa_hooks_t hpa_hooks_default = { hpa_hooks_t hpa_hooks_default = {
&hpa_hooks_map, &hpa_hooks_map,
@ -48,6 +48,9 @@ hpa_hooks_dehugify(void *ptr, size_t size) {
} }
static void static void
hpa_hooks_curtime(nstime_t *r_nstime) { hpa_hooks_curtime(nstime_t *r_nstime, bool first_reading) {
if (first_reading) {
nstime_init_zero(r_nstime);
}
nstime_update(r_nstime); nstime_update(r_nstime);
} }

View File

@ -349,7 +349,7 @@ defer_test_dehugify(void *ptr, size_t size) {
static nstime_t defer_curtime; static nstime_t defer_curtime;
static void static void
defer_test_curtime(nstime_t *r_time) { defer_test_curtime(nstime_t *r_time, bool first_reading) {
*r_time = defer_curtime; *r_time = defer_curtime;
} }