mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-07-23 13:13:06 +00:00
Fix infinite purging loop in HPA
As reported in #2449, under certain circumstances it's possible to get stuck in an infinite loop attempting to purge from the HPA. We now handle this by validating the HPA settings at the end of configuration parsing and either normalizing them or aborting depending on if `abort_conf` is set.
This commit is contained in:
committed by
Qi Wang
parent
424dd61d57
commit
3aae792b10
@@ -144,6 +144,7 @@ static void default_junk_free(void *ptr, size_t usize) {
|
||||
|
||||
void (*JET_MUTABLE junk_alloc_callback)(void *ptr, size_t size) = &default_junk_alloc;
|
||||
void (*JET_MUTABLE junk_free_callback)(void *ptr, size_t size) = &default_junk_free;
|
||||
void (*JET_MUTABLE invalid_conf_abort)(void) = &abort;
|
||||
|
||||
bool opt_utrace = false;
|
||||
bool opt_xmalloc = false;
|
||||
@@ -959,7 +960,7 @@ malloc_abort_invalid_conf(void) {
|
||||
assert(opt_abort_conf);
|
||||
malloc_printf("<jemalloc>: Abort (abort_conf:true) on invalid conf "
|
||||
"value (see above).\n");
|
||||
abort();
|
||||
invalid_conf_abort();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1081,6 +1082,46 @@ obtain_malloc_conf(unsigned which_source, char buf[PATH_MAX + 1]) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
validate_hpa_settings(void) {
|
||||
if (!hpa_supported() || !opt_hpa || opt_hpa_opts.dirty_mult == (fxp_t)-1) {
|
||||
return;
|
||||
}
|
||||
size_t hpa_threshold = fxp_mul_frac(HUGEPAGE, opt_hpa_opts.dirty_mult) +
|
||||
opt_hpa_opts.hugification_threshold;
|
||||
if (hpa_threshold > HUGEPAGE) {
|
||||
return;
|
||||
}
|
||||
|
||||
had_conf_error = true;
|
||||
char hpa_dirty_mult[FXP_BUF_SIZE];
|
||||
char hugification_threshold[FXP_BUF_SIZE];
|
||||
char normalization_message[256] = {0};
|
||||
fxp_print(opt_hpa_opts.dirty_mult, hpa_dirty_mult);
|
||||
fxp_print(fxp_div(FXP_INIT_INT((unsigned)
|
||||
(opt_hpa_opts.hugification_threshold >> LG_PAGE)),
|
||||
FXP_INIT_INT(HUGEPAGE_PAGES)), hugification_threshold);
|
||||
if (!opt_abort_conf) {
|
||||
char normalized_hugification_threshold[FXP_BUF_SIZE];
|
||||
opt_hpa_opts.hugification_threshold +=
|
||||
HUGEPAGE - hpa_threshold;
|
||||
fxp_print(fxp_div(FXP_INIT_INT((unsigned)
|
||||
(opt_hpa_opts.hugification_threshold >> LG_PAGE)),
|
||||
FXP_INIT_INT(HUGEPAGE_PAGES)),
|
||||
normalized_hugification_threshold);
|
||||
malloc_snprintf(normalization_message,
|
||||
sizeof(normalization_message), "<jemalloc>: Normalizing "
|
||||
"HPA settings to avoid pathological behavior, setting "
|
||||
"hpa_hugification_threshold_ratio: to %s.\n",
|
||||
normalized_hugification_threshold);
|
||||
}
|
||||
malloc_printf(
|
||||
"<jemalloc>: Invalid combination of options "
|
||||
"hpa_hugification_threshold_ratio: %s and hpa_dirty_mult: %s. "
|
||||
"These values should sum to > 1.0.\n%s", hugification_threshold,
|
||||
hpa_dirty_mult, normalization_message);
|
||||
}
|
||||
|
||||
static void
|
||||
malloc_conf_init_helper(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS],
|
||||
bool initial_call, const char *opts_cache[MALLOC_CONF_NSOURCES],
|
||||
@@ -1749,6 +1790,7 @@ malloc_conf_init_helper(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS],
|
||||
/* Re-enable diagnostic "-Wtype-limits" */
|
||||
JEMALLOC_DIAGNOSTIC_POP
|
||||
}
|
||||
validate_hpa_settings();
|
||||
if (opt_abort_conf && had_conf_error) {
|
||||
malloc_abort_invalid_conf();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user