diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index 5f1c74df264d..a47d02df99ac 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h @@ -100,12 +100,12 @@ static inline void mpol_get(struct mempolicy *pol) atomic_inc(&pol->refcnt); } -extern bool __mpol_equal(struct mempolicy *a, struct mempolicy *b); -static inline bool mpol_equal(struct mempolicy *a, struct mempolicy *b) +extern bool __mpol_equal(struct mempolicy *a, struct mempolicy *b, int nflag); +static inline bool mpol_equal(struct mempolicy *a, struct mempolicy *b, int nflag) { if (a == b) return true; - return __mpol_equal(a, b); + return __mpol_equal(a, b, nflag); } /* diff --git a/mm/mempolicy.c b/mm/mempolicy.c index ab51132547b8..75fb61c5f98f 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -800,7 +800,7 @@ static int vma_replace_policy(struct vm_area_struct *vma, /* Step 2: apply policy to a range and do splits. */ static int mbind_range(struct mm_struct *mm, unsigned long start, - unsigned long end, struct mempolicy *new_pol) + unsigned long end, struct mempolicy *new_pol, int nflag) { struct vm_area_struct *next; struct vm_area_struct *prev; @@ -822,7 +822,7 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, vmstart = max(start, vma->vm_start); vmend = min(end, vma->vm_end); - if (mpol_equal(vma_policy(vma), new_pol)) + if (mpol_equal(vma_policy(vma), new_pol, nflag)) continue; pgoff = vma->vm_pgoff + @@ -1282,6 +1282,7 @@ static long do_mbind(unsigned long start, unsigned long len, unsigned long end; int err; int ret; + int nflag; LIST_HEAD(pagelist); if (flags & ~(unsigned long)MPOL_MF_VALID) @@ -1346,8 +1347,11 @@ static long do_mbind(unsigned long start, unsigned long len, err = ret; goto up_out; } - - err = mbind_range(mm, start, end, new); + nflag = 0; + if (new->mode == MPOL_PREFERRED && nodes_empty(*nmask)){ + nflag = 1; + } + err = mbind_range(mm, start, end, new, nflag); if (!err) { int nr_failed = 0; @@ -2328,7 +2332,7 @@ struct mempolicy *__mpol_dup(struct mempolicy *old) } /* Slow path of a mempolicy comparison */ -bool __mpol_equal(struct mempolicy *a, struct mempolicy *b) +bool __mpol_equal(struct mempolicy *a, struct mempolicy *b, int nflag) { if (!a || !b) return false; @@ -2336,9 +2340,10 @@ bool __mpol_equal(struct mempolicy *a, struct mempolicy *b) return false; if (a->flags != b->flags) return false; - if (mpol_store_user_nodemask(a)) + if (mpol_store_user_nodemask(a) && !nflag) { if (!nodes_equal(a->w.user_nodemask, b->w.user_nodemask)) return false; + } switch (a->mode) { case MPOL_BIND: