Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc314724 authored by Mel Gorman's avatar Mel Gorman Committed by Ingo Molnar
Browse files

mm: numa: Limit NUMA scanning to migrate-on-fault VMAs



There is a 90% regression observed with a large Oracle performance test
on a 4 node system. Profiles indicated that the overhead was due to
contention on sp_lock when looking up shared memory policies. These
policies do not have the appropriate flags to allow them to be
automatically balanced so trapping faults on them is pointless. This
patch skips VMAs that do not have MPOL_F_MOF set.

[riel@redhat.com: Initial patch]

Signed-off-by: default avatarMel Gorman <mgorman@suse.de>
Reported-and-tested-by: default avatarJoe Mario <jmario@redhat.com>
Reviewed-by: default avatarRik van Riel <riel@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Signed-off-by: default avatarPeter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1381141781-10992-32-git-send-email-mgorman@suse.de


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 6fe6b2d6
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -136,6 +136,7 @@ struct mempolicy *mpol_shared_policy_lookup(struct shared_policy *sp,


struct mempolicy *get_vma_policy(struct task_struct *tsk,
struct mempolicy *get_vma_policy(struct task_struct *tsk,
		struct vm_area_struct *vma, unsigned long addr);
		struct vm_area_struct *vma, unsigned long addr);
bool vma_policy_mof(struct task_struct *task, struct vm_area_struct *vma);


extern void numa_default_policy(void);
extern void numa_default_policy(void);
extern void numa_policy_init(void);
extern void numa_policy_init(void);
+1 −1
Original line number Original line Diff line number Diff line
@@ -1130,7 +1130,7 @@ void task_numa_work(struct callback_head *work)
		vma = mm->mmap;
		vma = mm->mmap;
	}
	}
	for (; vma; vma = vma->vm_next) {
	for (; vma; vma = vma->vm_next) {
		if (!vma_migratable(vma))
		if (!vma_migratable(vma) || !vma_policy_mof(p, vma))
			continue;
			continue;


		do {
		do {
+24 −0
Original line number Original line Diff line number Diff line
@@ -1679,6 +1679,30 @@ struct mempolicy *get_vma_policy(struct task_struct *task,
	return pol;
	return pol;
}
}


bool vma_policy_mof(struct task_struct *task, struct vm_area_struct *vma)
{
	struct mempolicy *pol = get_task_policy(task);
	if (vma) {
		if (vma->vm_ops && vma->vm_ops->get_policy) {
			bool ret = false;

			pol = vma->vm_ops->get_policy(vma, vma->vm_start);
			if (pol && (pol->flags & MPOL_F_MOF))
				ret = true;
			mpol_cond_put(pol);

			return ret;
		} else if (vma->vm_policy) {
			pol = vma->vm_policy;
		}
	}

	if (!pol)
		return default_policy.flags & MPOL_F_MOF;

	return pol->flags & MPOL_F_MOF;
}

static int apply_policy_zone(struct mempolicy *policy, enum zone_type zone)
static int apply_policy_zone(struct mempolicy *policy, enum zone_type zone)
{
{
	enum zone_type dynamic_policy_zone = policy_zone;
	enum zone_type dynamic_policy_zone = policy_zone;