HPA: Hugification hysteresis.

We wait a while after deciding a huge extent should get hugified to see if it
gets purged before long.  This avoids hugifying extents that might shortly get
dehugified for purging.

Rename and use the hpa_dehugification_threshold option support code for this,
since it's now ignored.
This commit is contained in:
David Goldblatt
2021-06-14 14:53:23 -07:00
committed by David Goldblatt
parent 113938b6f4
commit 6630c59896
9 changed files with 234 additions and 60 deletions

View File

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

View File

@@ -17,16 +17,13 @@ struct hpa_shard_opts_s {
* any allocation request.
*/
size_t slab_max_alloc;
/*
* When the number of active bytes in a hugepage is >=
* 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;
/*
* The HPA purges whenever the number of pages exceeds dirty_mult *
* active_pages. This may be set to (fxp_t)-1 to disable purging.
@@ -40,6 +37,12 @@ struct hpa_shard_opts_s {
* ourselves for encapsulation purposes.
*/
bool deferral_allowed;
/*
* How long a hugepage has to be a hugification candidate before it will
* actually get hugified.
*/
uint64_t hugify_delay_ms;
};
#define HPA_SHARD_OPTS_DEFAULT { \
@@ -47,8 +50,6 @@ struct hpa_shard_opts_s {
64 * 1024, \
/* hugification_threshold */ \
HUGEPAGE * 95 / 100, \
/* dehugification_threshold */ \
HUGEPAGE * 20 / 100, \
/* dirty_mult */ \
FXP_INIT_PERCENT(25), \
/* \
@@ -58,7 +59,9 @@ struct hpa_shard_opts_s {
* or by an hpa_shard_set_deferral_allowed call, so the value \
* we put here doesn't matter. \
*/ \
false \
false, \
/* hugify_delay_ms */ \
10 * 1000 \
}
#endif /* JEMALLOC_INTERNAL_HPA_OPTS_H */

View File

@@ -61,6 +61,8 @@ struct hpdata_s {
/* And with hugifying. */
bool h_hugify_allowed;
/* When we became a hugification candidate. */
nstime_t h_time_hugify_allowed;
bool h_in_psset_hugify_container;
/* Whether or not a purge or hugify is currently happening. */
@@ -175,8 +177,8 @@ hpdata_purge_allowed_get(const hpdata_t *hpdata) {
static inline void
hpdata_purge_allowed_set(hpdata_t *hpdata, bool purge_allowed) {
assert(purge_allowed == false || !hpdata->h_mid_purge);
hpdata->h_purge_allowed = purge_allowed;
assert(purge_allowed == false || !hpdata->h_mid_purge);
hpdata->h_purge_allowed = purge_allowed;
}
static inline bool
@@ -185,9 +187,20 @@ hpdata_hugify_allowed_get(const hpdata_t *hpdata) {
}
static inline void
hpdata_hugify_allowed_set(hpdata_t *hpdata, bool hugify_allowed) {
assert(hugify_allowed == false || !hpdata->h_mid_hugify);
hpdata->h_hugify_allowed = hugify_allowed;
hpdata_allow_hugify(hpdata_t *hpdata, nstime_t now) {
assert(!hpdata->h_mid_hugify);
hpdata->h_hugify_allowed = true;
hpdata->h_time_hugify_allowed = now;
}
static inline nstime_t
hpdata_time_hugify_allowed(hpdata_t *hpdata) {
return hpdata->h_time_hugify_allowed;
}
static inline void
hpdata_disallow_hugify(hpdata_t *hpdata) {
hpdata->h_hugify_allowed = false;
}
static inline bool