mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
sched/numa: Skip some page migrations after a shared fault
Shared faults can lead to lots of unnecessary page migrations, slowing down the system, and causing private faults to hit the per-pgdat migration ratelimit. This patch adds sysctl numa_balancing_migrate_deferred, which specifies how many shared page migrations to skip unconditionally, after each page migration that is skipped because it is a shared fault. This reduces the number of page migrations back and forth in shared fault situations. It also gives a strong preference to the tasks that are already running where most of the memory is, and to moving the other tasks to near the memory. Testing this with a much higher scan rate than the default still seems to result in fewer page migrations than before. Memory seems to be somewhat better consolidated than previously, with multi-instance specjbb runs on a 4 node system. Signed-off-by: Rik van Riel <[email protected]> Signed-off-by: Mel Gorman <[email protected]> Cc: Andrea Arcangeli <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: Srikar Dronamraju <[email protected]> Signed-off-by: Peter Zijlstra <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
This commit is contained in:
parent
1e3646ffc6
commit
de1c9ce6f0
5 changed files with 75 additions and 3 deletions
|
|
@ -2301,6 +2301,35 @@ static void sp_free(struct sp_node *n)
|
|||
kmem_cache_free(sn_cache, n);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NUMA_BALANCING
|
||||
static bool numa_migrate_deferred(struct task_struct *p, int last_cpupid)
|
||||
{
|
||||
/* Never defer a private fault */
|
||||
if (cpupid_match_pid(p, last_cpupid))
|
||||
return false;
|
||||
|
||||
if (p->numa_migrate_deferred) {
|
||||
p->numa_migrate_deferred--;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void defer_numa_migrate(struct task_struct *p)
|
||||
{
|
||||
p->numa_migrate_deferred = sysctl_numa_balancing_migrate_deferred;
|
||||
}
|
||||
#else
|
||||
static inline bool numa_migrate_deferred(struct task_struct *p, int last_cpupid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void defer_numa_migrate(struct task_struct *p)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_NUMA_BALANCING */
|
||||
|
||||
/**
|
||||
* mpol_misplaced - check whether current page node is valid in policy
|
||||
*
|
||||
|
|
@ -2402,7 +2431,24 @@ int mpol_misplaced(struct page *page, struct vm_area_struct *vma, unsigned long
|
|||
* relation.
|
||||
*/
|
||||
last_cpupid = page_cpupid_xchg_last(page, this_cpupid);
|
||||
if (!cpupid_pid_unset(last_cpupid) && cpupid_to_nid(last_cpupid) != thisnid)
|
||||
if (!cpupid_pid_unset(last_cpupid) && cpupid_to_nid(last_cpupid) != thisnid) {
|
||||
|
||||
/* See sysctl_numa_balancing_migrate_deferred comment */
|
||||
if (!cpupid_match_pid(current, last_cpupid))
|
||||
defer_numa_migrate(current);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* The quadratic filter above reduces extraneous migration
|
||||
* of shared pages somewhat. This code reduces it even more,
|
||||
* reducing the overhead of page migrations of shared pages.
|
||||
* This makes workloads with shared pages rely more on
|
||||
* "move task near its memory", and less on "move memory
|
||||
* towards its task", which is exactly what we want.
|
||||
*/
|
||||
if (numa_migrate_deferred(current, last_cpupid))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue