mm/numa_balancing: allow migrate on protnone reference with MPOL_PREFERRED_MANY policy
[linux-2.6-block.git] / mm / mempolicy.c
index aa48376e2d341ed6b7f39ced101934f3ee8cd17f..13100a290918f1e2e13423797e2e292b6a7d4cdb 100644 (file)
@@ -1504,9 +1504,10 @@ static inline int sanitize_mpol_flags(int *mode, unsigned short *flags)
        if ((*flags & MPOL_F_STATIC_NODES) && (*flags & MPOL_F_RELATIVE_NODES))
                return -EINVAL;
        if (*flags & MPOL_F_NUMA_BALANCING) {
-               if (*mode != MPOL_BIND)
+               if (*mode == MPOL_BIND || *mode == MPOL_PREFERRED_MANY)
+                       *flags |= (MPOL_F_MOF | MPOL_F_MORON);
+               else
                        return -EINVAL;
-               *flags |= (MPOL_F_MOF | MPOL_F_MORON);
        }
        return 0;
 }
@@ -2770,15 +2771,26 @@ int mpol_misplaced(struct folio *folio, struct vm_fault *vmf,
                break;
 
        case MPOL_BIND:
-               /* Optimize placement among multiple nodes via NUMA balancing */
+       case MPOL_PREFERRED_MANY:
+               /*
+                * Even though MPOL_PREFERRED_MANY can allocate pages outside
+                * policy nodemask we don't allow numa migration to nodes
+                * outside policy nodemask for now. This is done so that if we
+                * want demotion to slow memory to happen, before allocating
+                * from some DRAM node say 'x', we will end up using a
+                * MPOL_PREFERRED_MANY mask excluding node 'x'. In such scenario
+                * we should not promote to node 'x' from slow memory node.
+                */
                if (pol->flags & MPOL_F_MORON) {
+                       /*
+                        * Optimize placement among multiple nodes
+                        * via NUMA balancing
+                        */
                        if (node_isset(thisnid, pol->nodes))
                                break;
                        goto out;
                }
-               fallthrough;
 
-       case MPOL_PREFERRED_MANY:
                /*
                 * use current page if in policy nodemask,
                 * else select nearest allowed node, if any.