.policy = MPOL_DEFAULT,
};
-static void mpol_rebind_policy(struct mempolicy *pol,
- const nodemask_t *newmask);
-
/* Check that the nodemask contains at least one populated zone */
static int is_valid_nodemask(nodemask_t *nodemask)
{
return ERR_PTR(-EINVAL);
}
+/* Migrate a policy to a different set of nodes */
+static void mpol_rebind_policy(struct mempolicy *pol,
+ const nodemask_t *newmask)
+{
+ nodemask_t tmp;
+ int static_nodes;
+ int relative_nodes;
+
+ if (!pol)
+ return;
+ static_nodes = pol->flags & MPOL_F_STATIC_NODES;
+ relative_nodes = pol->flags & MPOL_F_RELATIVE_NODES;
+ if (!mpol_store_user_nodemask(pol) &&
+ nodes_equal(pol->w.cpuset_mems_allowed, *newmask))
+ return;
+
+ switch (pol->policy) {
+ case MPOL_DEFAULT:
+ break;
+ case MPOL_BIND:
+ /* Fall through */
+ case MPOL_INTERLEAVE:
+ if (static_nodes)
+ nodes_and(tmp, pol->w.user_nodemask, *newmask);
+ else if (relative_nodes)
+ mpol_relative_nodemask(&tmp, &pol->w.user_nodemask,
+ newmask);
+ else {
+ nodes_remap(tmp, pol->v.nodes,
+ pol->w.cpuset_mems_allowed, *newmask);
+ pol->w.cpuset_mems_allowed = *newmask;
+ }
+ pol->v.nodes = tmp;
+ if (!node_isset(current->il_next, tmp)) {
+ current->il_next = next_node(current->il_next, tmp);
+ if (current->il_next >= MAX_NUMNODES)
+ current->il_next = first_node(tmp);
+ if (current->il_next >= MAX_NUMNODES)
+ current->il_next = numa_node_id();
+ }
+ break;
+ case MPOL_PREFERRED:
+ if (static_nodes) {
+ int node = first_node(pol->w.user_nodemask);
+
+ if (node_isset(node, *newmask))
+ pol->v.preferred_node = node;
+ else
+ pol->v.preferred_node = -1;
+ } else if (relative_nodes) {
+ mpol_relative_nodemask(&tmp, &pol->w.user_nodemask,
+ newmask);
+ pol->v.preferred_node = first_node(tmp);
+ } else {
+ pol->v.preferred_node = node_remap(pol->v.preferred_node,
+ pol->w.cpuset_mems_allowed, *newmask);
+ pol->w.cpuset_mems_allowed = *newmask;
+ }
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+/*
+ * Wrapper for mpol_rebind_policy() that just requires task
+ * pointer, and updates task mempolicy.
+ */
+
+void mpol_rebind_task(struct task_struct *tsk, const nodemask_t *new)
+{
+ mpol_rebind_policy(tsk->mempolicy, new);
+}
+
+/*
+ * Rebind each vma in mm to new nodemask.
+ *
+ * Call holding a reference to mm. Takes mm->mmap_sem during call.
+ */
+
+void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new)
+{
+ struct vm_area_struct *vma;
+
+ down_write(&mm->mmap_sem);
+ for (vma = mm->mmap; vma; vma = vma->vm_next)
+ mpol_rebind_policy(vma->vm_policy, new);
+ up_write(&mm->mmap_sem);
+}
+
static void gather_stats(struct page *, void *, int pte_dirty);
static void migrate_page_add(struct page *page, struct list_head *pagelist,
unsigned long flags);
do_set_mempolicy(MPOL_DEFAULT, 0, NULL);
}
-/* Migrate a policy to a different set of nodes */
-static void mpol_rebind_policy(struct mempolicy *pol,
- const nodemask_t *newmask)
-{
- nodemask_t tmp;
- int static_nodes;
- int relative_nodes;
-
- if (!pol)
- return;
- static_nodes = pol->flags & MPOL_F_STATIC_NODES;
- relative_nodes = pol->flags & MPOL_F_RELATIVE_NODES;
- if (!mpol_store_user_nodemask(pol) &&
- nodes_equal(pol->w.cpuset_mems_allowed, *newmask))
- return;
-
- switch (pol->policy) {
- case MPOL_DEFAULT:
- break;
- case MPOL_BIND:
- /* Fall through */
- case MPOL_INTERLEAVE:
- if (static_nodes)
- nodes_and(tmp, pol->w.user_nodemask, *newmask);
- else if (relative_nodes)
- mpol_relative_nodemask(&tmp, &pol->w.user_nodemask,
- newmask);
- else {
- nodes_remap(tmp, pol->v.nodes,
- pol->w.cpuset_mems_allowed, *newmask);
- pol->w.cpuset_mems_allowed = *newmask;
- }
- pol->v.nodes = tmp;
- if (!node_isset(current->il_next, tmp)) {
- current->il_next = next_node(current->il_next, tmp);
- if (current->il_next >= MAX_NUMNODES)
- current->il_next = first_node(tmp);
- if (current->il_next >= MAX_NUMNODES)
- current->il_next = numa_node_id();
- }
- break;
- case MPOL_PREFERRED:
- if (static_nodes) {
- int node = first_node(pol->w.user_nodemask);
-
- if (node_isset(node, *newmask))
- pol->v.preferred_node = node;
- else
- pol->v.preferred_node = -1;
- } else if (relative_nodes) {
- mpol_relative_nodemask(&tmp, &pol->w.user_nodemask,
- newmask);
- pol->v.preferred_node = first_node(tmp);
- } else {
- pol->v.preferred_node = node_remap(pol->v.preferred_node,
- pol->w.cpuset_mems_allowed, *newmask);
- pol->w.cpuset_mems_allowed = *newmask;
- }
- break;
- default:
- BUG();
- break;
- }
-}
-
-/*
- * Wrapper for mpol_rebind_policy() that just requires task
- * pointer, and updates task mempolicy.
- */
-
-void mpol_rebind_task(struct task_struct *tsk, const nodemask_t *new)
-{
- mpol_rebind_policy(tsk->mempolicy, new);
-}
-
-/*
- * Rebind each vma in mm to new nodemask.
- *
- * Call holding a reference to mm. Takes mm->mmap_sem during call.
- */
-
-void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new)
-{
- struct vm_area_struct *vma;
-
- down_write(&mm->mmap_sem);
- for (vma = mm->mmap; vma; vma = vma->vm_next)
- mpol_rebind_policy(vma->vm_policy, new);
- up_write(&mm->mmap_sem);
-}
-
/*
* Display pages allocated per node and memory policy via /proc.
*/