return cpumask_of_node(cpu_to_node(cpu));
 }
 
+#ifdef CONFIG_NUMA
+int sched_numa_find_nth_cpu(const struct cpumask *cpus, int cpu, int node);
+#else
+static __always_inline int sched_numa_find_nth_cpu(const struct cpumask *cpus, int cpu, int node)
+{
+       return cpumask_nth(cpu, cpus);
+}
+#endif /* CONFIG_NUMA */
 
 #endif /* _LINUX_TOPOLOGY_H */
 
  * Scheduler topology setup/handling methods
  */
 
+#include <linux/bsearch.h>
+
 DEFINE_MUTEX(sched_domains_mutex);
 
 /* Protected by sched_domains_mutex: */
        return found;
 }
 
+struct __cmp_key {
+       const struct cpumask *cpus;
+       struct cpumask ***masks;
+       int node;
+       int cpu;
+       int w;
+};
+
+static int hop_cmp(const void *a, const void *b)
+{
+       struct cpumask **prev_hop = *((struct cpumask ***)b - 1);
+       struct cpumask **cur_hop = *(struct cpumask ***)b;
+       struct __cmp_key *k = (struct __cmp_key *)a;
+
+       if (cpumask_weight_and(k->cpus, cur_hop[k->node]) <= k->cpu)
+               return 1;
+
+       k->w = (b == k->masks) ? 0 : cpumask_weight_and(k->cpus, prev_hop[k->node]);
+       if (k->w <= k->cpu)
+               return 0;
+
+       return -1;
+}
+
+/*
+ * sched_numa_find_nth_cpu() - given the NUMA topology, find the Nth next cpu
+ *                             closest to @cpu from @cpumask.
+ * cpumask: cpumask to find a cpu from
+ * cpu: Nth cpu to find
+ *
+ * returns: cpu, or nr_cpu_ids when nothing found.
+ */
+int sched_numa_find_nth_cpu(const struct cpumask *cpus, int cpu, int node)
+{
+       struct __cmp_key k = { .cpus = cpus, .node = node, .cpu = cpu };
+       struct cpumask ***hop_masks;
+       int hop, ret = nr_cpu_ids;
+
+       rcu_read_lock();
+
+       k.masks = rcu_dereference(sched_domains_numa_masks);
+       if (!k.masks)
+               goto unlock;
+
+       hop_masks = bsearch(&k, k.masks, sched_domains_numa_levels, sizeof(k.masks[0]), hop_cmp);
+       hop = hop_masks - k.masks;
+
+       ret = hop ?
+               cpumask_nth_and_andnot(cpu - k.w, cpus, k.masks[hop][node], k.masks[hop-1][node]) :
+               cpumask_nth_and(cpu, cpus, k.masks[0][node]);
+unlock:
+       rcu_read_unlock();
+       return ret;
+}
+EXPORT_SYMBOL_GPL(sched_numa_find_nth_cpu);
 #endif /* CONFIG_NUMA */
 
 static int __sdt_alloc(const struct cpumask *cpu_map)