cpumask.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/slab.h>
  3. #include <linux/kernel.h>
  4. #include <linux/bitops.h>
  5. #include <linux/cpumask.h>
  6. #include <linux/export.h>
  7. #include <linux/memblock.h>
  8. #include <linux/numa.h>
  9. /* These are not inline because of header tangles. */
  10. #ifdef CONFIG_CPUMASK_OFFSTACK
  11. /**
  12. * alloc_cpumask_var_node - allocate a struct cpumask on a given node
  13. * @mask: pointer to cpumask_var_t where the cpumask is returned
  14. * @flags: GFP_ flags
  15. * @node: memory node from which to allocate or %NUMA_NO_NODE
  16. *
  17. * Only defined when CONFIG_CPUMASK_OFFSTACK=y, otherwise is
  18. * a nop returning a constant 1 (in <linux/cpumask.h>).
  19. *
  20. * Return: TRUE if memory allocation succeeded, FALSE otherwise.
  21. *
  22. * In addition, mask will be NULL if this fails. Note that gcc is
  23. * usually smart enough to know that mask can never be NULL if
  24. * CONFIG_CPUMASK_OFFSTACK=n, so does code elimination in that case
  25. * too.
  26. */
  27. bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node)
  28. {
  29. *mask = kmalloc_node(cpumask_size(), flags, node);
  30. #ifdef CONFIG_DEBUG_PER_CPU_MAPS
  31. if (!*mask) {
  32. printk(KERN_ERR "=> alloc_cpumask_var: failed!\n");
  33. dump_stack();
  34. }
  35. #endif
  36. return *mask != NULL;
  37. }
  38. EXPORT_SYMBOL(alloc_cpumask_var_node);
  39. /**
  40. * alloc_bootmem_cpumask_var - allocate a struct cpumask from the bootmem arena.
  41. * @mask: pointer to cpumask_var_t where the cpumask is returned
  42. *
  43. * Only defined when CONFIG_CPUMASK_OFFSTACK=y, otherwise is
  44. * a nop (in <linux/cpumask.h>).
  45. * Either returns an allocated (zero-filled) cpumask, or causes the
  46. * system to panic.
  47. */
  48. void __init alloc_bootmem_cpumask_var(cpumask_var_t *mask)
  49. {
  50. *mask = memblock_alloc_or_panic(cpumask_size(), SMP_CACHE_BYTES);
  51. }
  52. /**
  53. * free_cpumask_var - frees memory allocated for a struct cpumask.
  54. * @mask: cpumask to free
  55. *
  56. * This is safe on a NULL mask.
  57. */
  58. void free_cpumask_var(cpumask_var_t mask)
  59. {
  60. kfree(mask);
  61. }
  62. EXPORT_SYMBOL(free_cpumask_var);
  63. /**
  64. * free_bootmem_cpumask_var - frees result of alloc_bootmem_cpumask_var
  65. * @mask: cpumask to free
  66. */
  67. void __init free_bootmem_cpumask_var(cpumask_var_t mask)
  68. {
  69. memblock_free(mask, cpumask_size());
  70. }
  71. #endif
  72. /**
  73. * cpumask_local_spread - select the i'th cpu based on NUMA distances
  74. * @i: index number
  75. * @node: local numa_node
  76. *
  77. * Return: online CPU according to a numa aware policy; local cpus are returned
  78. * first, followed by non-local ones, then it wraps around.
  79. *
  80. * For those who wants to enumerate all CPUs based on their NUMA distances,
  81. * i.e. call this function in a loop, like:
  82. *
  83. * for (i = 0; i < num_online_cpus(); i++) {
  84. * cpu = cpumask_local_spread(i, node);
  85. * do_something(cpu);
  86. * }
  87. *
  88. * There's a better alternative based on for_each()-like iterators:
  89. *
  90. * for_each_numa_hop_mask(mask, node) {
  91. * for_each_cpu_andnot(cpu, mask, prev)
  92. * do_something(cpu);
  93. * prev = mask;
  94. * }
  95. *
  96. * It's simpler and more verbose than above. Complexity of iterator-based
  97. * enumeration is O(sched_domains_numa_levels * nr_cpu_ids), while
  98. * cpumask_local_spread() when called for each cpu is
  99. * O(sched_domains_numa_levels * nr_cpu_ids * log(nr_cpu_ids)).
  100. */
  101. unsigned int cpumask_local_spread(unsigned int i, int node)
  102. {
  103. unsigned int cpu;
  104. /* Wrap: we always want a cpu. */
  105. i %= num_online_cpus();
  106. cpu = sched_numa_find_nth_cpu(cpu_online_mask, i, node);
  107. WARN_ON(cpu >= nr_cpu_ids);
  108. return cpu;
  109. }
  110. EXPORT_SYMBOL(cpumask_local_spread);
  111. static DEFINE_PER_CPU(int, distribute_cpu_mask_prev);
  112. /**
  113. * cpumask_any_and_distribute - Return an arbitrary cpu within src1p & src2p.
  114. * @src1p: first &cpumask for intersection
  115. * @src2p: second &cpumask for intersection
  116. *
  117. * Iterated calls using the same srcp1 and srcp2 will be distributed within
  118. * their intersection.
  119. *
  120. * Return: >= nr_cpu_ids if the intersection is empty.
  121. */
  122. unsigned int cpumask_any_and_distribute(const struct cpumask *src1p,
  123. const struct cpumask *src2p)
  124. {
  125. unsigned int next, prev;
  126. /* NOTE: our first selection will skip 0. */
  127. prev = __this_cpu_read(distribute_cpu_mask_prev);
  128. next = cpumask_next_and_wrap(prev, src1p, src2p);
  129. if (next < nr_cpu_ids)
  130. __this_cpu_write(distribute_cpu_mask_prev, next);
  131. return next;
  132. }
  133. EXPORT_SYMBOL(cpumask_any_and_distribute);
  134. /**
  135. * cpumask_any_distribute - Return an arbitrary cpu from srcp
  136. * @srcp: &cpumask for selection
  137. *
  138. * Return: >= nr_cpu_ids if the intersection is empty.
  139. */
  140. unsigned int cpumask_any_distribute(const struct cpumask *srcp)
  141. {
  142. unsigned int next, prev;
  143. /* NOTE: our first selection will skip 0. */
  144. prev = __this_cpu_read(distribute_cpu_mask_prev);
  145. next = cpumask_next_wrap(prev, srcp);
  146. if (next < nr_cpu_ids)
  147. __this_cpu_write(distribute_cpu_mask_prev, next);
  148. return next;
  149. }
  150. EXPORT_SYMBOL(cpumask_any_distribute);