mm/page_alloc: make pcpu_drain_mutex and pcpu_drain static
[linux-2.6-microblaze.git] / mm / mempolicy.c
index b4a039d..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;
@@ -896,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);
        }