|
@@ -607,6 +607,27 @@ check_range(struct mm_struct *mm, unsigned long start, unsigned long end,
|
|
|
return first;
|
|
|
}
|
|
|
|
|
|
+/* Apply policy to a single VMA */
|
|
|
+static int policy_vma(struct vm_area_struct *vma, struct mempolicy *new)
|
|
|
+{
|
|
|
+ int err = 0;
|
|
|
+ struct mempolicy *old = vma->vm_policy;
|
|
|
+
|
|
|
+ pr_debug("vma %lx-%lx/%lx vm_ops %p vm_file %p set_policy %p\n",
|
|
|
+ vma->vm_start, vma->vm_end, vma->vm_pgoff,
|
|
|
+ vma->vm_ops, vma->vm_file,
|
|
|
+ vma->vm_ops ? vma->vm_ops->set_policy : NULL);
|
|
|
+
|
|
|
+ if (vma->vm_ops && vma->vm_ops->set_policy)
|
|
|
+ err = vma->vm_ops->set_policy(vma, new);
|
|
|
+ if (!err) {
|
|
|
+ mpol_get(new);
|
|
|
+ vma->vm_policy = new;
|
|
|
+ mpol_put(old);
|
|
|
+ }
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
/* 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)
|
|
@@ -655,23 +676,9 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
|
|
|
if (err)
|
|
|
goto out;
|
|
|
}
|
|
|
-
|
|
|
- /*
|
|
|
- * Apply policy to a single VMA. The reference counting of
|
|
|
- * policy for vma_policy linkages has already been handled by
|
|
|
- * vma_merge and split_vma as necessary. If this is a shared
|
|
|
- * policy then ->set_policy will increment the reference count
|
|
|
- * for an sp node.
|
|
|
- */
|
|
|
- pr_debug("vma %lx-%lx/%lx vm_ops %p vm_file %p set_policy %p\n",
|
|
|
- vma->vm_start, vma->vm_end, vma->vm_pgoff,
|
|
|
- vma->vm_ops, vma->vm_file,
|
|
|
- vma->vm_ops ? vma->vm_ops->set_policy : NULL);
|
|
|
- if (vma->vm_ops && vma->vm_ops->set_policy) {
|
|
|
- err = vma->vm_ops->set_policy(vma, new_pol);
|
|
|
- if (err)
|
|
|
- goto out;
|
|
|
- }
|
|
|
+ err = policy_vma(vma, new_pol);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
out:
|