cputhreads.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #ifndef _ASM_POWERPC_CPUTHREADS_H
  2. #define _ASM_POWERPC_CPUTHREADS_H
  3. #include <linux/cpumask.h>
  4. /*
  5. * Mapping of threads to cores
  6. *
  7. * Note: This implementation is limited to a power of 2 number of
  8. * threads per core and the same number for each core in the system
  9. * (though it would work if some processors had less threads as long
  10. * as the CPU numbers are still allocated, just not brought online).
  11. *
  12. * However, the API allows for a different implementation in the future
  13. * if needed, as long as you only use the functions and not the variables
  14. * directly.
  15. */
  16. #ifdef CONFIG_SMP
  17. extern int threads_per_core;
  18. extern int threads_per_subcore;
  19. extern int threads_shift;
  20. extern cpumask_t threads_core_mask;
  21. #else
  22. #define threads_per_core 1
  23. #define threads_per_subcore 1
  24. #define threads_shift 0
  25. #define threads_core_mask (*get_cpu_mask(0))
  26. #endif
  27. /* cpu_thread_mask_to_cores - Return a cpumask of one per cores
  28. * hit by the argument
  29. *
  30. * @threads: a cpumask of online threads
  31. *
  32. * This function returns a cpumask which will have one online cpu's
  33. * bit set for each core that has at least one thread set in the argument.
  34. *
  35. * This can typically be used for things like IPI for tlb invalidations
  36. * since those need to be done only once per core/TLB
  37. */
  38. static inline cpumask_t cpu_thread_mask_to_cores(const struct cpumask *threads)
  39. {
  40. cpumask_t tmp, res;
  41. int i, cpu;
  42. cpumask_clear(&res);
  43. for (i = 0; i < NR_CPUS; i += threads_per_core) {
  44. cpumask_shift_left(&tmp, &threads_core_mask, i);
  45. if (cpumask_intersects(threads, &tmp)) {
  46. cpu = cpumask_next_and(-1, &tmp, cpu_online_mask);
  47. if (cpu < nr_cpu_ids)
  48. cpumask_set_cpu(cpu, &res);
  49. }
  50. }
  51. return res;
  52. }
  53. static inline int cpu_nr_cores(void)
  54. {
  55. return nr_cpu_ids >> threads_shift;
  56. }
  57. static inline cpumask_t cpu_online_cores_map(void)
  58. {
  59. return cpu_thread_mask_to_cores(cpu_online_mask);
  60. }
  61. #ifdef CONFIG_SMP
  62. int cpu_core_index_of_thread(int cpu);
  63. int cpu_first_thread_of_core(int core);
  64. #else
  65. static inline int cpu_core_index_of_thread(int cpu) { return cpu; }
  66. static inline int cpu_first_thread_of_core(int core) { return core; }
  67. #endif
  68. static inline int cpu_thread_in_core(int cpu)
  69. {
  70. return cpu & (threads_per_core - 1);
  71. }
  72. static inline int cpu_thread_in_subcore(int cpu)
  73. {
  74. return cpu & (threads_per_subcore - 1);
  75. }
  76. static inline int cpu_first_thread_sibling(int cpu)
  77. {
  78. return cpu & ~(threads_per_core - 1);
  79. }
  80. static inline int cpu_last_thread_sibling(int cpu)
  81. {
  82. return cpu | (threads_per_core - 1);
  83. }
  84. static inline u32 get_tensr(void)
  85. {
  86. #ifdef CONFIG_BOOKE
  87. if (cpu_has_feature(CPU_FTR_SMT))
  88. return mfspr(SPRN_TENSR);
  89. #endif
  90. return 1;
  91. }
  92. #endif /* _ASM_POWERPC_CPUTHREADS_H */