mm/page_alloc: make pcpu_drain_mutex and pcpu_drain static
[linux-2.6-microblaze.git] / mm / mempolicy.c
index 5fb427a..48ba972 100644 (file)
@@ -127,6 +127,32 @@ static struct mempolicy default_policy = {
 
 static struct mempolicy preferred_node_policy[MAX_NUMNODES];
 
+/**
+ * numa_map_to_online_node - Find closest online node
+ * @nid: Node id to start the search
+ *
+ * Lookup the next closest node by distance if @nid is not online.
+ */
+int numa_map_to_online_node(int node)
+{
+       int min_dist = INT_MAX, dist, n, min_node;
+
+       if (node == NUMA_NO_NODE || node_online(node))
+               return node;
+
+       min_node = node;
+       for_each_online_node(n) {
+               dist = node_distance(node, n);
+               if (dist < min_dist) {
+                       min_dist = dist;
+                       min_node = n;
+               }
+       }
+
+       return min_node;
+}
+EXPORT_SYMBOL_GPL(numa_map_to_online_node);
+
 struct mempolicy *get_task_policy(struct task_struct *p)
 {
        struct mempolicy *pol = p->mempolicy;
@@ -442,6 +468,7 @@ static inline bool queue_pages_required(struct page *page,
  */
 static int queue_pages_pmd(pmd_t *pmd, spinlock_t *ptl, unsigned long addr,
                                unsigned long end, struct mm_walk *walk)
+       __releases(ptl)
 {
        int ret = 0;
        struct page *page;
@@ -627,7 +654,7 @@ unsigned long change_prot_numa(struct vm_area_struct *vma,
 {
        int nr_updated;
 
-       nr_updated = change_protection(vma, addr, end, PAGE_NONE, 0, 1);
+       nr_updated = change_protection(vma, addr, end, PAGE_NONE, MM_CP_PROT_NUMA);
        if (nr_updated)
                count_vm_numa_events(NUMA_PTE_UPDATES, nr_updated);
 
@@ -678,8 +705,7 @@ static int queue_pages_test_walk(unsigned long start, unsigned long end,
 
        if (flags & MPOL_MF_LAZY) {
                /* Similar to task_numa_work, skip inaccessible VMAs */
-               if (!is_vm_hugetlb_page(vma) &&
-                       (vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)) &&
+               if (!is_vm_hugetlb_page(vma) && vma_is_accessible(vma) &&
                        !(vma->vm_flags & VM_MIXEDMAP))
                        change_prot_numa(vma, start, endvma);
                return 1;
@@ -881,7 +907,6 @@ static void get_policy_nodemask(struct mempolicy *p, nodemask_t *nodes)
 
        switch (p->mode) {
        case MPOL_BIND:
-               /* Fall through */
        case MPOL_INTERLEAVE:
                *nodes = p->v.nodes;
                break;
@@ -897,12 +922,15 @@ static void get_policy_nodemask(struct mempolicy *p, nodemask_t *nodes)
 
 static int lookup_node(struct mm_struct *mm, unsigned long addr)
 {
-       struct page *p;
+       struct page *p = NULL;
        int err;
 
        int locked = 1;
        err = get_user_pages_locked(addr & PAGE_MASK, 1, 0, &p, &locked);
-       if (err >= 0) {
+       if (err == 0) {
+               /* E.g. GUP interrupted by fatal signal */
+               err = -EFAULT;
+       } else if (err > 0) {
                err = page_to_nid(p);
                put_page(p);
        }
@@ -1023,7 +1051,7 @@ static int migrate_page_add(struct page *page, struct list_head *pagelist,
                if (!isolate_lru_page(head)) {
                        list_add_tail(&head->lru, pagelist);
                        mod_node_page_state(page_pgdat(head),
-                               NR_ISOLATED_ANON + page_is_file_cache(head),
+                               NR_ISOLATED_ANON + page_is_file_lru(head),
                                hpage_nr_pages(head));
                } else if (flags & MPOL_MF_STRICT) {
                        /*
@@ -2066,7 +2094,6 @@ bool init_nodemask_of_mempolicy(nodemask_t *mask)
                break;
 
        case MPOL_BIND:
-               /* Fall through */
        case MPOL_INTERLEAVE:
                *mask =  mempolicy->v.nodes;
                break;
@@ -2333,7 +2360,6 @@ bool __mpol_equal(struct mempolicy *a, struct mempolicy *b)
 
        switch (a->mode) {
        case MPOL_BIND:
-               /* Fall through */
        case MPOL_INTERLEAVE:
                return !!nodes_equal(a->v.nodes, b->v.nodes);
        case MPOL_PREFERRED: