|
@@ -2317,9 +2317,37 @@ int mpol_misplaced(struct page *page, struct vm_area_struct *vma, unsigned long
|
|
|
}
|
|
|
|
|
|
/* Migrate the page towards the node whose CPU is referencing it */
|
|
|
- if (pol->flags & MPOL_F_MORON)
|
|
|
+ if (pol->flags & MPOL_F_MORON) {
|
|
|
+ int last_nid;
|
|
|
+
|
|
|
polnid = numa_node_id();
|
|
|
|
|
|
+ /*
|
|
|
+ * Multi-stage node selection is used in conjunction
|
|
|
+ * with a periodic migration fault to build a temporal
|
|
|
+ * task<->page relation. By using a two-stage filter we
|
|
|
+ * remove short/unlikely relations.
|
|
|
+ *
|
|
|
+ * Using P(p) ~ n_p / n_t as per frequentist
|
|
|
+ * probability, we can equate a task's usage of a
|
|
|
+ * particular page (n_p) per total usage of this
|
|
|
+ * page (n_t) (in a given time-span) to a probability.
|
|
|
+ *
|
|
|
+ * Our periodic faults will sample this probability and
|
|
|
+ * getting the same result twice in a row, given these
|
|
|
+ * samples are fully independent, is then given by
|
|
|
+ * P(n)^2, provided our sample period is sufficiently
|
|
|
+ * short compared to the usage pattern.
|
|
|
+ *
|
|
|
+ * This quadric squishes small probabilities, making
|
|
|
+ * it less likely we act on an unlikely task<->page
|
|
|
+ * relation.
|
|
|
+ */
|
|
|
+ last_nid = page_xchg_last_nid(page, polnid);
|
|
|
+ if (last_nid != polnid)
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
if (curnid != polnid)
|
|
|
ret = polnid;
|
|
|
out:
|