mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-08-06 02:16:14 +03:00
HPA: Generalize purging.
Previously, we would purge a hugepage only when it's completely empty. With this change, we can purge even when only partially empty. Although the heuristic here is still fairly primitive, this infrastructure can scale to become more advanced.
This commit is contained in:
parent
70692cfb13
commit
30b9e8162b
5 changed files with 208 additions and 64 deletions
35
src/hpdata.c
35
src/hpdata.c
|
|
@ -24,6 +24,7 @@ hpdata_init(hpdata_t *hpdata, void *addr, uint64_t age) {
|
|||
hpdata->h_huge = false;
|
||||
hpdata->h_mid_purge = false;
|
||||
hpdata->h_mid_hugify = false;
|
||||
hpdata->h_in_psset = false;
|
||||
hpdata_longest_free_range_set(hpdata, HUGEPAGE_PAGES);
|
||||
hpdata->h_nactive = 0;
|
||||
fb_init(hpdata->active_pages, HUGEPAGE_PAGES);
|
||||
|
|
@ -36,6 +37,7 @@ hpdata_init(hpdata_t *hpdata, void *addr, uint64_t age) {
|
|||
void *
|
||||
hpdata_reserve_alloc(hpdata_t *hpdata, size_t sz) {
|
||||
hpdata_assert_consistent(hpdata);
|
||||
assert(!hpdata_in_psset_get(hpdata));
|
||||
assert((sz & PAGE_MASK) == 0);
|
||||
size_t npages = sz >> LG_PAGE;
|
||||
assert(npages <= hpdata_longest_free_range_get(hpdata));
|
||||
|
|
@ -116,6 +118,7 @@ hpdata_reserve_alloc(hpdata_t *hpdata, size_t sz) {
|
|||
void
|
||||
hpdata_unreserve(hpdata_t *hpdata, void *addr, size_t sz) {
|
||||
hpdata_assert_consistent(hpdata);
|
||||
assert(!hpdata->h_in_psset);
|
||||
assert(((uintptr_t)addr & PAGE_MASK) == 0);
|
||||
assert((sz & PAGE_MASK) == 0);
|
||||
size_t begin = ((uintptr_t)addr - (uintptr_t)hpdata_addr_get(hpdata))
|
||||
|
|
@ -144,6 +147,7 @@ hpdata_unreserve(hpdata_t *hpdata, void *addr, size_t sz) {
|
|||
void
|
||||
hpdata_purge_begin(hpdata_t *hpdata, hpdata_purge_state_t *purge_state) {
|
||||
hpdata_assert_consistent(hpdata);
|
||||
assert(!hpdata->h_in_psset);
|
||||
assert(!hpdata->h_mid_purge);
|
||||
assert(!hpdata->h_mid_hugify);
|
||||
hpdata->h_mid_purge = true;
|
||||
|
|
@ -181,6 +185,7 @@ hpdata_purge_next(hpdata_t *hpdata, hpdata_purge_state_t *purge_state,
|
|||
* a consistent state.
|
||||
*/
|
||||
assert(hpdata->h_mid_purge);
|
||||
assert(!hpdata->h_in_psset);
|
||||
/* Should have dehugified already (if necessary). */
|
||||
assert(!hpdata->h_huge);
|
||||
assert(!hpdata->h_mid_hugify);
|
||||
|
|
@ -210,6 +215,7 @@ hpdata_purge_next(hpdata_t *hpdata, hpdata_purge_state_t *purge_state,
|
|||
void
|
||||
hpdata_purge_end(hpdata_t *hpdata, hpdata_purge_state_t *purge_state) {
|
||||
hpdata_assert_consistent(hpdata);
|
||||
assert(!hpdata->h_in_psset);
|
||||
assert(hpdata->h_mid_purge);
|
||||
assert(!hpdata->h_mid_hugify);
|
||||
hpdata->h_mid_purge = false;
|
||||
|
|
@ -230,6 +236,7 @@ hpdata_purge_end(hpdata_t *hpdata, hpdata_purge_state_t *purge_state) {
|
|||
void
|
||||
hpdata_hugify_begin(hpdata_t *hpdata) {
|
||||
hpdata_assert_consistent(hpdata);
|
||||
assert(!hpdata_in_psset_get(hpdata));
|
||||
assert(!hpdata->h_mid_purge);
|
||||
assert(!hpdata->h_mid_hugify);
|
||||
hpdata->h_mid_hugify = true;
|
||||
|
|
@ -242,6 +249,11 @@ hpdata_hugify_begin(hpdata_t *hpdata) {
|
|||
void
|
||||
hpdata_hugify_end(hpdata_t *hpdata) {
|
||||
hpdata_assert_consistent(hpdata);
|
||||
/*
|
||||
* This is the exception to the "no metadata tweaks while in the psset"
|
||||
* rule.
|
||||
*/
|
||||
/* assert(!hpdata_in_psset_get(hpdata)); */
|
||||
assert(!hpdata->h_mid_purge);
|
||||
assert(hpdata->h_mid_hugify);
|
||||
hpdata->h_mid_hugify = false;
|
||||
|
|
@ -251,30 +263,9 @@ hpdata_hugify_end(hpdata_t *hpdata) {
|
|||
void
|
||||
hpdata_dehugify(hpdata_t *hpdata) {
|
||||
hpdata_assert_consistent(hpdata);
|
||||
/*
|
||||
* These asserts are morally right; for now, though, we have the "purge a
|
||||
* hugepage only in its entirety, when it becomes empty", path sharing
|
||||
* hpdata_dehugify with the new purge pathway coming in the next
|
||||
* commit.
|
||||
*/
|
||||
/*
|
||||
assert(!hpdata_in_psset_get(hpdata));
|
||||
assert(hpdata->h_mid_purge);
|
||||
assert(!hpdata->h_mid_hugify);
|
||||
*/
|
||||
hpdata->h_huge = false;
|
||||
hpdata_assert_consistent(hpdata);
|
||||
}
|
||||
|
||||
void
|
||||
hpdata_purge(hpdata_t *hpdata) {
|
||||
hpdata_assert_consistent(hpdata);
|
||||
/*
|
||||
* The hpdata must be empty; we don't (yet) support partial purges of
|
||||
* hugepages.
|
||||
*/
|
||||
assert(hpdata->h_nactive == 0);
|
||||
fb_unset_range(hpdata->dirty_pages, HUGEPAGE_PAGES, 0, HUGEPAGE_PAGES);
|
||||
fb_init(hpdata->dirty_pages, HUGEPAGE_PAGES);
|
||||
hpdata->h_ndirty = 0;
|
||||
hpdata_assert_consistent(hpdata);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue