diff --git a/include/jemalloc/internal/hpa_opts.h b/include/jemalloc/internal/hpa_opts.h index bce0de2c..0ed1c417 100644 --- a/include/jemalloc/internal/hpa_opts.h +++ b/include/jemalloc/internal/hpa_opts.h @@ -20,6 +20,11 @@ struct hpa_shard_opts_s { * hugification_threshold, we force hugify it. */ size_t hugification_threshold; + /* + * When the number of dirty bytes in a hugepage is >= + * dehugification_threshold, we force dehugify it. + */ + size_t dehugification_threshold; }; #define HPA_SHARD_OPTS_DEFAULT { \ @@ -27,6 +32,8 @@ struct hpa_shard_opts_s { 64 * 1024, \ /* hugification_threshold */ \ HUGEPAGE * 95 / 100, \ + /* dehugification_threshold */ \ + HUGEPAGE * 20 / 100 \ } #endif /* JEMALLOC_INTERNAL_HPA_OPTS_H */ diff --git a/src/ctl.c b/src/ctl.c index 5096162c..ba667b5b 100644 --- a/src/ctl.c +++ b/src/ctl.c @@ -95,6 +95,7 @@ CTL_PROTO(opt_confirm_conf) CTL_PROTO(opt_hpa) CTL_PROTO(opt_hpa_slab_max_alloc) CTL_PROTO(opt_hpa_hugification_threshold) +CTL_PROTO(opt_hpa_dehugification_threshold) CTL_PROTO(opt_hpa_sec_max_alloc) CTL_PROTO(opt_hpa_sec_max_bytes) CTL_PROTO(opt_hpa_sec_nshards) @@ -399,6 +400,8 @@ static const ctl_named_node_t opt_node[] = { {NAME("hpa_slab_max_alloc"), CTL(opt_hpa_slab_max_alloc)}, {NAME("hpa_hugification_threshold"), CTL(opt_hpa_hugification_threshold)}, + {NAME("hpa_dehugification_threshold"), + CTL(opt_hpa_dehugification_threshold)}, {NAME("hpa_sec_max_alloc"), CTL(opt_hpa_sec_max_alloc)}, {NAME("hpa_sec_max_bytes"), CTL(opt_hpa_sec_max_bytes)}, {NAME("hpa_sec_nshards"), CTL(opt_hpa_sec_nshards)}, @@ -2096,6 +2099,8 @@ CTL_RO_NL_GEN(opt_hpa, opt_hpa, bool) CTL_RO_NL_GEN(opt_hpa_slab_max_alloc, opt_hpa_opts.slab_max_alloc, size_t) CTL_RO_NL_GEN(opt_hpa_hugification_threshold, opt_hpa_opts.hugification_threshold, size_t) +CTL_RO_NL_GEN(opt_hpa_dehugification_threshold, + opt_hpa_opts.dehugification_threshold, size_t) CTL_RO_NL_GEN(opt_hpa_sec_max_alloc, opt_hpa_sec_max_alloc, size_t) CTL_RO_NL_GEN(opt_hpa_sec_max_bytes, opt_hpa_sec_max_bytes, size_t) CTL_RO_NL_GEN(opt_hpa_sec_nshards, opt_hpa_sec_nshards, size_t) diff --git a/src/hpa.c b/src/hpa.c index 00fb279d..0e704b8c 100644 --- a/src/hpa.c +++ b/src/hpa.c @@ -191,7 +191,9 @@ hpa_update_purge_hugify_eligibility(hpa_shard_t *shard, hpdata_t *ps) { * active pages; i.e. 4/5s of hugepage pages must be active. */ if ((!hpdata_huge_get(ps) && hpdata_ndirty_get(ps) > 0) - || hpdata_ndirty_get(ps) > HUGEPAGE_PAGES / 5) { + || (hpdata_ndirty_get(ps) != 0 + && hpdata_ndirty_get(ps) * PAGE + >= shard->opts.dehugification_threshold)) { hpdata_purge_allowed_set(ps, true); } if (hpa_good_hugification_candidate(shard, ps) diff --git a/src/jemalloc.c b/src/jemalloc.c index cd402621..fe8e09e6 100644 --- a/src/jemalloc.c +++ b/src/jemalloc.c @@ -1437,6 +1437,27 @@ malloc_conf_init_helper(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS], CONF_CONTINUE; } + /* And the same for the dehugification_threhsold. */ + CONF_HANDLE_SIZE_T( + opt_hpa_opts.dehugification_threshold, + "hpa_dehugification_threshold", PAGE, HUGEPAGE, + CONF_CHECK_MIN, CONF_CHECK_MAX, true); + if (CONF_MATCH("hpa_dehugification_threshold_ratio")) { + fxp_t ratio; + char *end; + bool err = fxp_parse(&ratio, v, + &end); + if (err || (size_t)(end - v) != vlen + || ratio > FXP_INIT_INT(1)) { + CONF_ERROR("Invalid conf value", + k, klen, v, vlen); + } else { + opt_hpa_opts.dehugification_threshold = + fxp_mul_frac(HUGEPAGE, ratio); + } + CONF_CONTINUE; + } + CONF_HANDLE_SIZE_T(opt_hpa_sec_max_alloc, "hpa_sec_max_alloc", PAGE, 0, CONF_CHECK_MIN, CONF_DONT_CHECK_MAX, true); CONF_HANDLE_SIZE_T(opt_hpa_sec_max_bytes, "hpa_sec_max_bytes", diff --git a/src/stats.c b/src/stats.c index 27fe5b76..7a0f20bf 100644 --- a/src/stats.c +++ b/src/stats.c @@ -1465,6 +1465,7 @@ stats_general_print(emitter_t *emitter) { OPT_WRITE_BOOL("hpa") OPT_WRITE_SIZE_T("hpa_slab_max_alloc") OPT_WRITE_SIZE_T("hpa_hugification_threshold") + OPT_WRITE_SIZE_T("hpa_dehugification_threshold") OPT_WRITE_SIZE_T("hpa_sec_max_alloc") OPT_WRITE_SIZE_T("hpa_sec_max_bytes") OPT_WRITE_SIZE_T("hpa_sec_nshards")