hpdata: track per-page dirty state.
This commit is contained in:
committed by
David Goldblatt
parent
ff4086aa6b
commit
2ae966222f
@@ -146,7 +146,10 @@ hpa_dehugify(hpdata_t *ps) {
|
||||
/* Purge, then dehugify while unbacked. */
|
||||
pages_purge_forced(hpdata_addr_get(ps), HUGEPAGE);
|
||||
pages_nohuge(hpdata_addr_get(ps), HUGEPAGE);
|
||||
hpdata_huge_set(ps, false);
|
||||
|
||||
/* Update metadata. */
|
||||
hpdata_dehugify(ps);
|
||||
hpdata_purge(ps);
|
||||
}
|
||||
|
||||
static hpdata_t *
|
||||
@@ -297,7 +300,7 @@ hpa_try_alloc_no_grow(tsdn_t *tsdn, hpa_shard_t *shard, size_t size, bool *oom)
|
||||
|
||||
bool hugify = hpa_should_hugify(shard, ps);
|
||||
if (hugify) {
|
||||
hpdata_huge_set(ps, true);
|
||||
hpdata_hugify(ps);
|
||||
}
|
||||
psset_insert(&shard->psset, ps);
|
||||
|
||||
|
45
src/hpdata.c
45
src/hpdata.c
@@ -21,10 +21,12 @@ void
|
||||
hpdata_init(hpdata_t *hpdata, void *addr, uint64_t age) {
|
||||
hpdata_addr_set(hpdata, addr);
|
||||
hpdata_age_set(hpdata, age);
|
||||
hpdata_huge_set(hpdata, false);
|
||||
hpdata->h_nactive = 0;
|
||||
hpdata->h_huge = false;
|
||||
hpdata_longest_free_range_set(hpdata, HUGEPAGE_PAGES);
|
||||
hpdata->h_nactive = 0;
|
||||
fb_init(hpdata->active_pages, HUGEPAGE_PAGES);
|
||||
hpdata->h_ndirty = 0;
|
||||
fb_init(hpdata->dirty_pages, HUGEPAGE_PAGES);
|
||||
|
||||
hpdata_assert_consistent(hpdata);
|
||||
}
|
||||
@@ -74,6 +76,15 @@ hpdata_reserve_alloc(hpdata_t *hpdata, size_t sz) {
|
||||
fb_set_range(hpdata->active_pages, HUGEPAGE_PAGES, begin, npages);
|
||||
hpdata->h_nactive += npages;
|
||||
|
||||
/*
|
||||
* We might be about to dirty some memory for the first time; update our
|
||||
* count if so.
|
||||
*/
|
||||
size_t new_dirty = fb_ucount(hpdata->dirty_pages, HUGEPAGE_PAGES,
|
||||
result, npages);
|
||||
fb_set_range(hpdata->dirty_pages, HUGEPAGE_PAGES, result, npages);
|
||||
hpdata->h_ndirty += new_dirty;
|
||||
|
||||
/*
|
||||
* We might have shrunk the longest free range. We have to keep
|
||||
* scanning until the end of the hpdata to be sure.
|
||||
@@ -127,3 +138,33 @@ hpdata_unreserve(hpdata_t *hpdata, void *addr, size_t sz) {
|
||||
|
||||
hpdata_assert_consistent(hpdata);
|
||||
}
|
||||
|
||||
void
|
||||
hpdata_hugify(hpdata_t *hpdata) {
|
||||
hpdata_assert_consistent(hpdata);
|
||||
hpdata->h_huge = true;
|
||||
fb_set_range(hpdata->dirty_pages, HUGEPAGE_PAGES, 0, HUGEPAGE_PAGES);
|
||||
hpdata->h_ndirty = HUGEPAGE_PAGES;
|
||||
hpdata_assert_consistent(hpdata);
|
||||
}
|
||||
|
||||
void
|
||||
hpdata_dehugify(hpdata_t *hpdata) {
|
||||
hpdata_assert_consistent(hpdata);
|
||||
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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user