|
@@ -1892,7 +1892,7 @@ static void update_task_scan_period(struct task_struct *p,
|
|
|
unsigned long shared, unsigned long private)
|
|
|
{
|
|
|
unsigned int period_slot;
|
|
|
- int ratio;
|
|
|
+ int lr_ratio, ps_ratio;
|
|
|
int diff;
|
|
|
|
|
|
unsigned long remote = p->numa_faults_locality[0];
|
|
@@ -1922,25 +1922,36 @@ static void update_task_scan_period(struct task_struct *p,
|
|
|
* >= NUMA_PERIOD_THRESHOLD scan period increases (scan slower)
|
|
|
*/
|
|
|
period_slot = DIV_ROUND_UP(p->numa_scan_period, NUMA_PERIOD_SLOTS);
|
|
|
- ratio = (local * NUMA_PERIOD_SLOTS) / (local + remote);
|
|
|
- if (ratio >= NUMA_PERIOD_THRESHOLD) {
|
|
|
- int slot = ratio - NUMA_PERIOD_THRESHOLD;
|
|
|
+ lr_ratio = (local * NUMA_PERIOD_SLOTS) / (local + remote);
|
|
|
+ ps_ratio = (private * NUMA_PERIOD_SLOTS) / (private + shared);
|
|
|
+
|
|
|
+ if (ps_ratio >= NUMA_PERIOD_THRESHOLD) {
|
|
|
+ /*
|
|
|
+ * Most memory accesses are local. There is no need to
|
|
|
+ * do fast NUMA scanning, since memory is already local.
|
|
|
+ */
|
|
|
+ int slot = ps_ratio - NUMA_PERIOD_THRESHOLD;
|
|
|
+ if (!slot)
|
|
|
+ slot = 1;
|
|
|
+ diff = slot * period_slot;
|
|
|
+ } else if (lr_ratio >= NUMA_PERIOD_THRESHOLD) {
|
|
|
+ /*
|
|
|
+ * Most memory accesses are shared with other tasks.
|
|
|
+ * There is no point in continuing fast NUMA scanning,
|
|
|
+ * since other tasks may just move the memory elsewhere.
|
|
|
+ */
|
|
|
+ int slot = lr_ratio - NUMA_PERIOD_THRESHOLD;
|
|
|
if (!slot)
|
|
|
slot = 1;
|
|
|
diff = slot * period_slot;
|
|
|
} else {
|
|
|
- diff = -(NUMA_PERIOD_THRESHOLD - ratio) * period_slot;
|
|
|
-
|
|
|
/*
|
|
|
- * Scale scan rate increases based on sharing. There is an
|
|
|
- * inverse relationship between the degree of sharing and
|
|
|
- * the adjustment made to the scanning period. Broadly
|
|
|
- * speaking the intent is that there is little point
|
|
|
- * scanning faster if shared accesses dominate as it may
|
|
|
- * simply bounce migrations uselessly
|
|
|
+ * Private memory faults exceed (SLOTS-THRESHOLD)/SLOTS,
|
|
|
+ * yet they are not on the local NUMA node. Speed up
|
|
|
+ * NUMA scanning to get the memory moved over.
|
|
|
*/
|
|
|
- ratio = DIV_ROUND_UP(private * NUMA_PERIOD_SLOTS, (private + shared + 1));
|
|
|
- diff = (diff * ratio) / NUMA_PERIOD_SLOTS;
|
|
|
+ int ratio = max(lr_ratio, ps_ratio);
|
|
|
+ diff = -(NUMA_PERIOD_THRESHOLD - ratio) * period_slot;
|
|
|
}
|
|
|
|
|
|
p->numa_scan_period = clamp(p->numa_scan_period + diff,
|