[PATCH] sched,numa cap pte scanning overhead to 3% of run time
From: Rik van Riel
Date: Wed Nov 04 2015 - 13:45:25 EST
There is a fundamental mismatch between the runtime based NUMA scanning
at the task level, and the wall clock time NUMA scanning at the mm level.
On a severely overloaded system, with very large processes, this mismatch
can cause the system to spend all of its time in change_prot_numa().
This can happen if the task spends at least two ticks in change_prot_numa(),
and only gets two ticks of CPU time in the real time between two scan
intervals of the mm.
This patch ensures that if the system is so busy that the task got
rescheduled during change_prot_numa(), we never spend more than 3% of run
time scanning PTEs.
This patch does nothing if the CPU is not overloaded at all, and the
task is not rescheduled during change_prot_numa().
All of the above only works if we fix the math underflow issue in
task_numa_tick, so do that as well (Jan Stancek).
Signed-off-by: Rik van Riel <riel@xxxxxxxxxx>
Reported-and-tested-by: Jan Stancek <jstancek@xxxxxxxxxx>
---
kernel/sched/fair.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 824aa9f501a3..e9b9ac424a76 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -2155,6 +2155,7 @@ 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;
+ u64 runtime = p->se.sum_exec_runtime;
struct vm_area_struct *vma;
unsigned long start, end;
unsigned long nr_pte_updates = 0;
@@ -2277,6 +2278,20 @@ void task_numa_work(struct callback_head *work)
else
reset_ptenuma_scan(p);
up_read(&mm->mmap_sem);
+
+ /*
+ * There is a fundamental mismatch between the runtime based
+ * NUMA scanning at the task level, and the wall clock time
+ * NUMA scanning at the mm level. On a severely overloaded
+ * system, with very large processes, this mismatch can cause
+ * the system to spend all of its time in change_prot_numa().
+ * Limit NUMA PTE scanning to 3% of the task's run time, if
+ * we spent so much time scanning we got rescheduled.
+ */
+ if (unlikely(p->se.sum_exec_runtime != runtime)) {
+ u64 diff = p->se.sum_exec_runtime - runtime;
+ p->node_stamp += 32 * diff;
+ }
}
/*
@@ -2302,7 +2317,7 @@ void task_tick_numa(struct rq *rq, struct task_struct *curr)
now = curr->se.sum_exec_runtime;
period = (u64)curr->numa_scan_period * NSEC_PER_MSEC;
- if (now - curr->node_stamp > period) {
+ if (now > curr->node_stamp + period) {
if (!curr->node_stamp)
curr->numa_scan_period = task_scan_min(curr);
curr->node_stamp += period;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/