mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
memcg: make mem_cgroup_split_huge_fixup() more efficient
In split_huge_page(), mem_cgroup_split_huge_fixup() is called to handle
page_cgroup modifcations. It takes move_lock_page_cgroup() and modifies
page_cgroup and LRU accounting jobs and called HPAGE_PMD_SIZE - 1 times.
But thinking again,
- compound_lock() is held at move_accout...then, it's not necessary
to take move_lock_page_cgroup().
- LRU is locked and all tail pages will go into the same LRU as
head is now on.
- page_cgroup is contiguous in huge page range.
This patch fixes mem_cgroup_split_huge_fixup() as to be called once per
hugepage and reduce costs for spliting.
[[email protected]: fix typo, per Michal]
Signed-off-by: KAMEZAWA Hiroyuki <[email protected]>
Cc: Johannes Weiner <[email protected]>
Cc: Andrea Arcangeli <[email protected]>
Reviewed-by: Michal Hocko <[email protected]>
Cc: Balbir Singh <[email protected]>
Cc: David Rientjes <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
6b208e3f6e
commit
e94c8a9cbc
3 changed files with 21 additions and 21 deletions
|
|
@ -2553,39 +2553,39 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *memcg,
|
|||
(1 << PCG_ACCT_LRU) | (1 << PCG_MIGRATION))
|
||||
/*
|
||||
* Because tail pages are not marked as "used", set it. We're under
|
||||
* zone->lru_lock, 'splitting on pmd' and compund_lock.
|
||||
* zone->lru_lock, 'splitting on pmd' and compound_lock.
|
||||
* charge/uncharge will be never happen and move_account() is done under
|
||||
* compound_lock(), so we don't have to take care of races.
|
||||
*/
|
||||
void mem_cgroup_split_huge_fixup(struct page *head, struct page *tail)
|
||||
void mem_cgroup_split_huge_fixup(struct page *head)
|
||||
{
|
||||
struct page_cgroup *head_pc = lookup_page_cgroup(head);
|
||||
struct page_cgroup *tail_pc = lookup_page_cgroup(tail);
|
||||
unsigned long flags;
|
||||
struct page_cgroup *pc;
|
||||
int i;
|
||||
|
||||
if (mem_cgroup_disabled())
|
||||
return;
|
||||
/*
|
||||
* We have no races with charge/uncharge but will have races with
|
||||
* page state accounting.
|
||||
*/
|
||||
move_lock_page_cgroup(head_pc, &flags);
|
||||
for (i = 1; i < HPAGE_PMD_NR; i++) {
|
||||
pc = head_pc + i;
|
||||
pc->mem_cgroup = head_pc->mem_cgroup;
|
||||
smp_wmb();/* see __commit_charge() */
|
||||
/*
|
||||
* LRU flags cannot be copied because we need to add tail
|
||||
* page to LRU by generic call and our hooks will be called.
|
||||
*/
|
||||
pc->flags = head_pc->flags & ~PCGF_NOCOPY_AT_SPLIT;
|
||||
}
|
||||
|
||||
tail_pc->mem_cgroup = head_pc->mem_cgroup;
|
||||
smp_wmb(); /* see __commit_charge() */
|
||||
if (PageCgroupAcctLRU(head_pc)) {
|
||||
enum lru_list lru;
|
||||
struct mem_cgroup_per_zone *mz;
|
||||
|
||||
/*
|
||||
* LRU flags cannot be copied because we need to add tail
|
||||
*.page to LRU by generic call and our hook will be called.
|
||||
* We hold lru_lock, then, reduce counter directly.
|
||||
*/
|
||||
lru = page_lru(head);
|
||||
mz = page_cgroup_zoneinfo(head_pc->mem_cgroup, head);
|
||||
MEM_CGROUP_ZSTAT(mz, lru) -= 1;
|
||||
MEM_CGROUP_ZSTAT(mz, lru) -= HPAGE_PMD_NR - 1;
|
||||
}
|
||||
tail_pc->flags = head_pc->flags & ~PCGF_NOCOPY_AT_SPLIT;
|
||||
move_unlock_page_cgroup(head_pc, &flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue