6c840f7b8415578b113bef465de76e2dc5f64fbf
[~tnikolova/compat/.git] / compat / compat-3.16.c
1 #include <linux/slab.h>
2 #include <linux/kernel.h>
3 #include <linux/bitops.h>
4 #include <linux/cpumask.h>
5 #include <linux/export.h>
6 #include <linux/bootmem.h>
7
8 /**
9  * cpumask_set_cpu_local_first - set i'th cpu with local numa cpu's first
10  *
11  * @i: index number
12  * @numa_node: local numa_node
13  * @dstp: cpumask with the relevant cpu bit set according to the policy
14  *
15  * This function sets the cpumask according to a numa aware policy.
16  * cpumask could be used as an affinity hint for the IRQ related to a
17  * queue. When the policy is to spread queues across cores - local cores
18  * first.
19  *
20  * Returns 0 on success, -ENOMEM for no memory, and -EAGAIN when failed to set
21  * the cpu bit and need to re-call the function.
22  */
23 int cpumask_set_cpu_local_first(int i, int numa_node, cpumask_t *dstp)
24 {
25         cpumask_var_t mask;
26         int cpu;
27         int ret = 0;
28
29         if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
30                 return -ENOMEM;
31
32         i %= num_online_cpus();
33
34         if (numa_node == -1 || !cpumask_of_node(numa_node)) {
35                 /* Use all online cpu's for non numa aware system */
36                 cpumask_copy(mask, cpu_online_mask);
37         } else {
38                 int n;
39
40                 cpumask_and(mask,
41                             cpumask_of_node(numa_node), cpu_online_mask);
42
43                 n = cpumask_weight(mask);
44                 if (i >= n) {
45                         i -= n;
46
47                         /* If index > number of local cpu's, mask out local
48                          * cpu's
49                          */
50                         cpumask_andnot(mask, cpu_online_mask, mask);
51                 }
52         }
53
54         for_each_cpu(cpu, mask) {
55                 if (--i < 0)
56                         goto out;
57         }
58
59         ret = -EAGAIN;
60
61 out:
62         free_cpumask_var(mask);
63
64         if (!ret)
65                 cpumask_set_cpu(cpu, dstp);
66
67         return ret;
68 }
69 EXPORT_SYMBOL(cpumask_set_cpu_local_first);