aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mempolicy.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/mempolicy.c')
-rw-r--r--mm/mempolicy.c82
1 files changed, 78 insertions, 4 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 04729647f359..71cb253368cb 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1679,6 +1679,30 @@ struct mempolicy *get_vma_policy(struct task_struct *task,
1679 return pol; 1679 return pol;
1680} 1680}
1681 1681
1682bool vma_policy_mof(struct task_struct *task, struct vm_area_struct *vma)
1683{
1684 struct mempolicy *pol = get_task_policy(task);
1685 if (vma) {
1686 if (vma->vm_ops && vma->vm_ops->get_policy) {
1687 bool ret = false;
1688
1689 pol = vma->vm_ops->get_policy(vma, vma->vm_start);
1690 if (pol && (pol->flags & MPOL_F_MOF))
1691 ret = true;
1692 mpol_cond_put(pol);
1693
1694 return ret;
1695 } else if (vma->vm_policy) {
1696 pol = vma->vm_policy;
1697 }
1698 }
1699
1700 if (!pol)
1701 return default_policy.flags & MPOL_F_MOF;
1702
1703 return pol->flags & MPOL_F_MOF;
1704}
1705
1682static int apply_policy_zone(struct mempolicy *policy, enum zone_type zone) 1706static int apply_policy_zone(struct mempolicy *policy, enum zone_type zone)
1683{ 1707{
1684 enum zone_type dynamic_policy_zone = policy_zone; 1708 enum zone_type dynamic_policy_zone = policy_zone;
@@ -2277,6 +2301,35 @@ static void sp_free(struct sp_node *n)
2277 kmem_cache_free(sn_cache, n); 2301 kmem_cache_free(sn_cache, n);
2278} 2302}
2279 2303
2304#ifdef CONFIG_NUMA_BALANCING
2305static bool numa_migrate_deferred(struct task_struct *p, int last_cpupid)
2306{
2307 /* Never defer a private fault */
2308 if (cpupid_match_pid(p, last_cpupid))
2309 return false;
2310
2311 if (p->numa_migrate_deferred) {
2312 p->numa_migrate_deferred--;
2313 return true;
2314 }
2315 return false;
2316}
2317
2318static inline void defer_numa_migrate(struct task_struct *p)
2319{
2320 p->numa_migrate_deferred = sysctl_numa_balancing_migrate_deferred;
2321}
2322#else
2323static inline bool numa_migrate_deferred(struct task_struct *p, int last_cpupid)
2324{
2325 return false;
2326}
2327
2328static inline void defer_numa_migrate(struct task_struct *p)
2329{
2330}
2331#endif /* CONFIG_NUMA_BALANCING */
2332
2280/** 2333/**
2281 * mpol_misplaced - check whether current page node is valid in policy 2334 * mpol_misplaced - check whether current page node is valid in policy
2282 * 2335 *
@@ -2300,6 +2353,8 @@ int mpol_misplaced(struct page *page, struct vm_area_struct *vma, unsigned long
2300 struct zone *zone; 2353 struct zone *zone;
2301 int curnid = page_to_nid(page); 2354 int curnid = page_to_nid(page);
2302 unsigned long pgoff; 2355 unsigned long pgoff;
2356 int thiscpu = raw_smp_processor_id();
2357 int thisnid = cpu_to_node(thiscpu);
2303 int polnid = -1; 2358 int polnid = -1;
2304 int ret = -1; 2359 int ret = -1;
2305 2360
@@ -2348,9 +2403,11 @@ int mpol_misplaced(struct page *page, struct vm_area_struct *vma, unsigned long
2348 2403
2349 /* Migrate the page towards the node whose CPU is referencing it */ 2404 /* Migrate the page towards the node whose CPU is referencing it */
2350 if (pol->flags & MPOL_F_MORON) { 2405 if (pol->flags & MPOL_F_MORON) {
2351 int last_nid; 2406 int last_cpupid;
2407 int this_cpupid;
2352 2408
2353 polnid = numa_node_id(); 2409 polnid = thisnid;
2410 this_cpupid = cpu_pid_to_cpupid(thiscpu, current->pid);
2354 2411
2355 /* 2412 /*
2356 * Multi-stage node selection is used in conjunction 2413 * Multi-stage node selection is used in conjunction
@@ -2373,8 +2430,25 @@ int mpol_misplaced(struct page *page, struct vm_area_struct *vma, unsigned long
2373 * it less likely we act on an unlikely task<->page 2430 * it less likely we act on an unlikely task<->page
2374 * relation. 2431 * relation.
2375 */ 2432 */
2376 last_nid = page_nid_xchg_last(page, polnid); 2433 last_cpupid = page_cpupid_xchg_last(page, this_cpupid);
2377 if (last_nid != polnid) 2434 if (!cpupid_pid_unset(last_cpupid) && cpupid_to_nid(last_cpupid) != thisnid) {
2435
2436 /* See sysctl_numa_balancing_migrate_deferred comment */
2437 if (!cpupid_match_pid(current, last_cpupid))
2438 defer_numa_migrate(current);
2439
2440 goto out;
2441 }
2442
2443 /*
2444 * The quadratic filter above reduces extraneous migration
2445 * of shared pages somewhat. This code reduces it even more,
2446 * reducing the overhead of page migrations of shared pages.
2447 * This makes workloads with shared pages rely more on
2448 * "move task near its memory", and less on "move memory
2449 * towards its task", which is exactly what we want.
2450 */
2451 if (numa_migrate_deferred(current, last_cpupid))
2378 goto out; 2452 goto out;
2379 } 2453 }
2380 2454