@@ -2490,15 +2490,19 @@ int mpol_misplaced(struct page *page, struct vm_area_struct *vma, unsigned long
break;
case MPOL_BIND:
-
/*
- * allows binding to multiple nodes.
- * use current page if in policy nodemask,
- * else select nearest allowed node, if any.
- * If no allowed nodes, use current [!misplaced].
+ * Allows binding to multiple nodes. If both current and
+ * accessing nodes are in policy nodemask, migrate to
+ * accessing node to optimize page placement. Otherwise,
+ * use current page if in policy nodemask, else select
+ * nearest allowed node, if any. If no allowed nodes, use
+ * current [!misplaced].
*/
- if (node_isset(curnid, pol->v.nodes))
+ if (node_isset(curnid, pol->v.nodes)) {
+ if (node_isset(thisnid, pol->v.nodes))
+ goto mopron;
goto out;
+ }
z = first_zones_zonelist(
node_zonelist(numa_node_id(), GFP_HIGHUSER),
gfp_zone(GFP_HIGHUSER),
@@ -2512,6 +2516,7 @@ 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_MOPRON) {
+mopron:
polnid = thisnid;
if (!should_numa_migrate_memory(current, page, curnid, thiscpu))