| From 99501b51efe66d435f7b1fa3b6fc52cd74f53462 Mon Sep 17 00:00:00 2001 |
| From: Yu Zhao <yuzhao@google.com> |
| Date: Wed, 5 May 2021 12:21:41 -0600 |
| Subject: [PATCH] FROMLIST: mm/workingset.c: refactor pack_shadow() and |
| unpack_shadow() |
| |
| This patches moves the bucket order and PageWorkingset() out of |
| pack_shadow() and unpack_shadow(). It has no merits on its own but |
| makes the upcoming changes to mm/workingset.c less diffy. |
| |
| Signed-off-by: Yu Zhao <yuzhao@google.com> |
| Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru> |
| (am from https://lore.kernel.org/patchwork/patch/1432181/) |
| |
| BUG=b:123039911 |
| TEST=Built |
| |
| Change-Id: I474378b573d2e1614a9798dca0949d1d6fba3e25 |
| Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2950547 |
| Reviewed-by: Yu Zhao <yuzhao@chromium.org> |
| Tested-by: Yu Zhao <yuzhao@chromium.org> |
| Commit-Queue: Yu Zhao <yuzhao@chromium.org> |
| --- |
| mm/workingset.c | 57 ++++++++++++++++++++----------------------------- |
| 1 file changed, 23 insertions(+), 34 deletions(-) |
| |
| diff --git a/mm/workingset.c b/mm/workingset.c |
| index 5ba3e42446fa..2286ddc809b1 100644 |
| --- a/mm/workingset.c |
| +++ b/mm/workingset.c |
| @@ -168,11 +168,9 @@ |
| * refault distance will immediately activate the refaulting page. |
| */ |
| |
| -#define WORKINGSET_SHIFT 1 |
| -#define EVICTION_SHIFT ((BITS_PER_LONG - BITS_PER_XA_VALUE) + \ |
| - WORKINGSET_SHIFT + NODES_SHIFT + \ |
| - MEM_CGROUP_ID_SHIFT) |
| -#define EVICTION_MASK (~0UL >> EVICTION_SHIFT) |
| +#define EVICTION_SHIFT (BITS_PER_XA_VALUE - MEM_CGROUP_ID_SHIFT - NODES_SHIFT) |
| +#define EVICTION_MASK (BIT(EVICTION_SHIFT) - 1) |
| +#define WORKINGSET_WIDTH 1 |
| |
| /* |
| * Eviction timestamps need to be able to cover the full range of |
| @@ -184,36 +182,23 @@ |
| */ |
| static unsigned int bucket_order __read_mostly; |
| |
| -static void *pack_shadow(int memcgid, pg_data_t *pgdat, unsigned long eviction, |
| - bool workingset) |
| +static void *pack_shadow(int memcg_id, struct pglist_data *pgdat, unsigned long val) |
| { |
| - eviction >>= bucket_order; |
| - eviction &= EVICTION_MASK; |
| - eviction = (eviction << MEM_CGROUP_ID_SHIFT) | memcgid; |
| - eviction = (eviction << NODES_SHIFT) | pgdat->node_id; |
| - eviction = (eviction << WORKINGSET_SHIFT) | workingset; |
| + val = (val << MEM_CGROUP_ID_SHIFT) | memcg_id; |
| + val = (val << NODES_SHIFT) | pgdat->node_id; |
| |
| - return xa_mk_value(eviction); |
| + return xa_mk_value(val); |
| } |
| |
| -static void unpack_shadow(void *shadow, int *memcgidp, pg_data_t **pgdat, |
| - unsigned long *evictionp, bool *workingsetp) |
| +static unsigned long unpack_shadow(void *shadow, int *memcg_id, struct pglist_data **pgdat) |
| { |
| - unsigned long entry = xa_to_value(shadow); |
| - int memcgid, nid; |
| - bool workingset; |
| + unsigned long val = xa_to_value(shadow); |
| |
| - workingset = entry & ((1UL << WORKINGSET_SHIFT) - 1); |
| - entry >>= WORKINGSET_SHIFT; |
| - nid = entry & ((1UL << NODES_SHIFT) - 1); |
| - entry >>= NODES_SHIFT; |
| - memcgid = entry & ((1UL << MEM_CGROUP_ID_SHIFT) - 1); |
| - entry >>= MEM_CGROUP_ID_SHIFT; |
| - |
| - *memcgidp = memcgid; |
| - *pgdat = NODE_DATA(nid); |
| - *evictionp = entry << bucket_order; |
| - *workingsetp = workingset; |
| + *pgdat = NODE_DATA(val & (BIT(NODES_SHIFT) - 1)); |
| + val >>= NODES_SHIFT; |
| + *memcg_id = val & (BIT(MEM_CGROUP_ID_SHIFT) - 1); |
| + |
| + return val >> MEM_CGROUP_ID_SHIFT; |
| } |
| |
| /** |
| @@ -269,7 +254,9 @@ void *workingset_eviction(struct page *page, struct mem_cgroup *target_memcg) |
| memcgid = mem_cgroup_id(lruvec_memcg(lruvec)); |
| eviction = atomic_long_read(&lruvec->nonresident_age); |
| workingset_age_nonresident(lruvec, thp_nr_pages(page)); |
| - return pack_shadow(memcgid, pgdat, eviction, PageWorkingset(page)); |
| + eviction >>= bucket_order; |
| + eviction = (eviction << WORKINGSET_WIDTH) | PageWorkingset(page); |
| + return pack_shadow(memcgid, pgdat, eviction); |
| } |
| |
| /** |
| @@ -296,7 +283,7 @@ void workingset_refault(struct page *page, void *shadow) |
| bool workingset; |
| int memcgid; |
| |
| - unpack_shadow(shadow, &memcgid, &pgdat, &eviction, &workingset); |
| + eviction = unpack_shadow(shadow, &memcgid, &pgdat); |
| |
| rcu_read_lock(); |
| /* |
| @@ -320,6 +307,8 @@ void workingset_refault(struct page *page, void *shadow) |
| goto out; |
| eviction_lruvec = mem_cgroup_lruvec(eviction_memcg, pgdat); |
| refault = atomic_long_read(&eviction_lruvec->nonresident_age); |
| + workingset = eviction & (BIT(WORKINGSET_WIDTH) - 1); |
| + eviction = (eviction >> WORKINGSET_WIDTH) << bucket_order; |
| |
| /* |
| * Calculate the refault distance |
| @@ -337,7 +326,7 @@ void workingset_refault(struct page *page, void *shadow) |
| * longest time, so the occasional inappropriate activation |
| * leading to pressure on the active list is not a problem. |
| */ |
| - refault_distance = (refault - eviction) & EVICTION_MASK; |
| + refault_distance = (refault - eviction) & (EVICTION_MASK >> WORKINGSET_WIDTH); |
| |
| /* |
| * The activation decision for this page is made at the level |
| @@ -595,7 +584,7 @@ static int __init workingset_init(void) |
| unsigned int max_order; |
| int ret; |
| |
| - BUILD_BUG_ON(BITS_PER_LONG < EVICTION_SHIFT); |
| + BUILD_BUG_ON(EVICTION_SHIFT < WORKINGSET_WIDTH); |
| /* |
| * Calculate the eviction bucket size to cover the longest |
| * actionable refault distance, which is currently half of |
| @@ -603,7 +592,7 @@ static int __init workingset_init(void) |
| * some more pages at runtime, so keep working with up to |
| * double the initial memory by using totalram_pages as-is. |
| */ |
| - timestamp_bits = BITS_PER_LONG - EVICTION_SHIFT; |
| + timestamp_bits = EVICTION_SHIFT - WORKINGSET_WIDTH; |
| max_order = fls_long(totalram_pages() - 1); |
| if (max_order > timestamp_bits) |
| bucket_order = max_order - timestamp_bits; |
| -- |
| 2.32.0.402.g57bb445576-goog |
| |