Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 344797
b: refs/heads/master
c: 6e5fb22
h: refs/heads/master
i:
  344795: f1e8cfc
v: v3
  • Loading branch information
Peter Zijlstra authored and Mel Gorman committed Dec 11, 2012
1 parent 34c593b commit e5c56d9
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cbee9f88ec1b8dd6b58f25f54e4f52c82ed77690
refs/heads/master: 6e5fb223e89dbe5cb5c563f8d4a4a0a7d62455a8
3 changes: 3 additions & 0 deletions trunk/include/linux/mm_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,9 @@ struct mm_struct {
*/
unsigned long numa_next_scan;

/* Restart point for scanning and setting pte_numa */
unsigned long numa_scan_offset;

/* numa_scan_seq prevents two threads setting pte_numa */
int numa_scan_seq;
#endif
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -2008,6 +2008,7 @@ extern enum sched_tunable_scaling sysctl_sched_tunable_scaling;

extern unsigned int sysctl_numa_balancing_scan_period_min;
extern unsigned int sysctl_numa_balancing_scan_period_max;
extern unsigned int sysctl_numa_balancing_scan_size;
extern unsigned int sysctl_numa_balancing_settle_count;

#ifdef CONFIG_SCHED_DEBUG
Expand Down
65 changes: 52 additions & 13 deletions trunk/kernel/sched/fair.c
Original file line number Diff line number Diff line change
Expand Up @@ -780,10 +780,13 @@ update_stats_curr_start(struct cfs_rq *cfs_rq, struct sched_entity *se)

#ifdef CONFIG_NUMA_BALANCING
/*
* numa task sample period in ms: 5s
* numa task sample period in ms
*/
unsigned int sysctl_numa_balancing_scan_period_min = 5000;
unsigned int sysctl_numa_balancing_scan_period_max = 5000*16;
unsigned int sysctl_numa_balancing_scan_period_min = 100;
unsigned int sysctl_numa_balancing_scan_period_max = 100*16;

/* Portion of address space to scan in MB */
unsigned int sysctl_numa_balancing_scan_size = 256;

static void task_numa_placement(struct task_struct *p)
{
Expand All @@ -808,6 +811,12 @@ void task_numa_fault(int node, int pages)
task_numa_placement(p);
}

static void reset_ptenuma_scan(struct task_struct *p)
{
ACCESS_ONCE(p->mm->numa_scan_seq)++;
p->mm->numa_scan_offset = 0;
}

/*
* The expensive part of numa migration is done from task_work context.
* Triggered from task_tick_numa().
Expand All @@ -817,6 +826,9 @@ void task_numa_work(struct callback_head *work)
unsigned long migrate, next_scan, now = jiffies;
struct task_struct *p = current;
struct mm_struct *mm = p->mm;
struct vm_area_struct *vma;
unsigned long offset, end;
long length;

WARN_ON_ONCE(p != container_of(work, struct task_struct, numa_work));

Expand Down Expand Up @@ -846,18 +858,45 @@ void task_numa_work(struct callback_head *work)
if (cmpxchg(&mm->numa_next_scan, migrate, next_scan) != migrate)
return;

ACCESS_ONCE(mm->numa_scan_seq)++;
{
struct vm_area_struct *vma;
offset = mm->numa_scan_offset;
length = sysctl_numa_balancing_scan_size;
length <<= 20;

down_read(&mm->mmap_sem);
for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (!vma_migratable(vma))
continue;
change_prot_numa(vma, vma->vm_start, vma->vm_end);
}
up_read(&mm->mmap_sem);
down_read(&mm->mmap_sem);
vma = find_vma(mm, offset);
if (!vma) {
reset_ptenuma_scan(p);
offset = 0;
vma = mm->mmap;
}
for (; vma && length > 0; vma = vma->vm_next) {
if (!vma_migratable(vma))
continue;

/* Skip small VMAs. They are not likely to be of relevance */
if (((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) < HPAGE_PMD_NR)
continue;

offset = max(offset, vma->vm_start);
end = min(ALIGN(offset + length, HPAGE_SIZE), vma->vm_end);
length -= end - offset;

change_prot_numa(vma, offset, end);

offset = end;
}

/*
* It is possible to reach the end of the VMA list but the last few VMAs are
* not guaranteed to the vma_migratable. If they are not, we would find the
* !migratable VMA on the next scan but not reset the scanner to the start
* so check it now.
*/
if (vma)
mm->numa_scan_offset = offset;
else
reset_ptenuma_scan(p);
up_read(&mm->mmap_sem);
}

/*
Expand Down
7 changes: 7 additions & 0 deletions trunk/kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,13 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
{
.procname = "numa_balancing_scan_size_mb",
.data = &sysctl_numa_balancing_scan_size,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
#endif /* CONFIG_NUMA_BALANCING */
#endif /* CONFIG_SCHED_DEBUG */
{
Expand Down

0 comments on commit e5c56d9

Please sign in to comment.