mt_hotplug_strategy_cpu.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * Copyright (c) 2015 MediaTek Inc.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/init.h>
  17. #include <linux/sched.h>
  18. #include "mt_hotplug_strategy_internal.h"
  19. #define HP_HAVE_SCHED_TPLG 0
  20. #if !HP_HAVE_SCHED_TPLG
  21. #include <linux/cpumask.h>
  22. #include <asm/topology.h>
  23. #endif
  24. /*
  25. * hps cpu interface - cpumask
  26. */
  27. int hps_cpu_is_cpu_big(int cpu)
  28. {
  29. if (!cpumask_empty(&hps_ctxt.big_cpumask)) {
  30. if (cpumask_test_cpu(cpu, &hps_ctxt.big_cpumask))
  31. return 1;
  32. else
  33. return 0;
  34. } else
  35. return 0;
  36. }
  37. int hps_cpu_is_cpu_little(int cpu)
  38. {
  39. if (!cpumask_empty(&hps_ctxt.little_cpumask)) {
  40. if (cpumask_test_cpu(cpu, &hps_ctxt.little_cpumask))
  41. return 1;
  42. else
  43. return 0;
  44. } else
  45. return 0;
  46. }
  47. unsigned int num_online_little_cpus(void)
  48. {
  49. struct cpumask dst_cpumask;
  50. cpumask_and(&dst_cpumask, &hps_ctxt.little_cpumask, cpu_online_mask);
  51. return cpumask_weight(&dst_cpumask);
  52. }
  53. unsigned int num_online_big_cpus(void)
  54. {
  55. struct cpumask dst_cpumask;
  56. cpumask_and(&dst_cpumask, &hps_ctxt.big_cpumask, cpu_online_mask);
  57. return cpumask_weight(&dst_cpumask);
  58. }
  59. /*
  60. * hps cpu interface - scheduler
  61. */
  62. unsigned int hps_cpu_get_percpu_load(int cpu)
  63. {
  64. #ifdef CONFIG_MTK_SCHED_RQAVG_US
  65. return sched_get_percpu_load(cpu, 1, 0);
  66. #else
  67. return 100;
  68. #endif
  69. }
  70. unsigned int hps_cpu_get_nr_heavy_task(void)
  71. {
  72. #ifdef CONFIG_MTK_SCHED_RQAVG_US
  73. return sched_get_nr_heavy_task();
  74. #else
  75. return 0;
  76. #endif
  77. }
  78. void hps_cpu_get_tlp(unsigned int *avg, unsigned int *iowait_avg)
  79. {
  80. #ifdef CONFIG_MTK_SCHED_RQAVG_KS
  81. sched_get_nr_running_avg((int *)avg, (int *)iowait_avg);
  82. #else
  83. *avg = 0;
  84. *iowait_avg = 0;
  85. #endif
  86. }
  87. void hps_cpu_get_big_little_cpumasks(struct cpumask *big, struct cpumask *little)
  88. {
  89. #if HP_HAVE_SCHED_TPLG
  90. sched_get_big_little_cpus(big, little);
  91. #else
  92. unsigned int cpu;
  93. cpumask_clear(big);
  94. cpumask_clear(little);
  95. for_each_possible_cpu(cpu) {
  96. if (arch_cpu_is_big(cpu))
  97. cpumask_set_cpu(cpu, big);
  98. else
  99. cpumask_set_cpu(cpu, little);
  100. }
  101. #endif /* HP_HAVE_SCHED_TPLG */
  102. }
  103. /*
  104. * init
  105. */
  106. int hps_cpu_init(void)
  107. {
  108. int r = 0;
  109. char str1[32];
  110. hps_warn("hps_cpu_init\n");
  111. /* init cpu arch in hps_ctxt */
  112. /* init cpumask */
  113. cpumask_clear(&hps_ctxt.little_cpumask);
  114. cpumask_clear(&hps_ctxt.big_cpumask);
  115. /* a. call api */
  116. hps_cpu_get_big_little_cpumasks(&hps_ctxt.big_cpumask, &hps_ctxt.little_cpumask);
  117. /* b. fix 2L2b */
  118. /* cpulist_parse("0-1", &hps_ctxt.little_cpumask); */
  119. /* cpulist_parse("2-3", &hps_ctxt.big_cpumask); */
  120. /* c. 4L */
  121. /* cpulist_parse("0-3", &hps_ctxt.little_cpumask); */
  122. cpulist_scnprintf(str1, sizeof(str1), &hps_ctxt.little_cpumask);
  123. hps_warn("hps_ctxt.little_cpumask: %s\n", str1);
  124. cpulist_scnprintf(str1, sizeof(str1), &hps_ctxt.big_cpumask);
  125. hps_warn("hps_ctxt.big_cpumask: %s\n", str1);
  126. if (cpumask_weight(&hps_ctxt.little_cpumask) == 0) {
  127. cpumask_copy(&hps_ctxt.little_cpumask, &hps_ctxt.big_cpumask);
  128. cpumask_clear(&hps_ctxt.big_cpumask);
  129. }
  130. /* verify arch is hmp or smp */
  131. if (!cpumask_empty(&hps_ctxt.little_cpumask) &&
  132. !cpumask_empty(&hps_ctxt.big_cpumask)) {
  133. unsigned int cpu;
  134. hps_ctxt.is_hmp = 1;
  135. hps_ctxt.little_cpu_id_min = num_possible_cpus();
  136. hps_ctxt.big_cpu_id_min = num_possible_cpus();
  137. for_each_cpu((cpu), &hps_ctxt.little_cpumask) {
  138. if (cpu < hps_ctxt.little_cpu_id_min)
  139. hps_ctxt.little_cpu_id_min = cpu;
  140. if (cpu > hps_ctxt.little_cpu_id_max)
  141. hps_ctxt.little_cpu_id_max = cpu;
  142. }
  143. for_each_cpu((cpu), &hps_ctxt.big_cpumask) {
  144. if (cpu < hps_ctxt.big_cpu_id_min)
  145. hps_ctxt.big_cpu_id_min = cpu;
  146. if (cpu > hps_ctxt.big_cpu_id_max)
  147. hps_ctxt.big_cpu_id_max = cpu;
  148. }
  149. } else {
  150. hps_ctxt.is_hmp = 0;
  151. hps_ctxt.little_cpu_id_min = 0;
  152. hps_ctxt.little_cpu_id_max = num_possible_little_cpus() - 1;
  153. }
  154. /* init bound in hps_ctxt */
  155. hps_ctxt.little_num_base_perf_serv = 1;
  156. hps_ctxt.little_num_limit_thermal =
  157. cpumask_weight(&hps_ctxt.little_cpumask);
  158. hps_ctxt.little_num_limit_low_battery =
  159. cpumask_weight(&hps_ctxt.little_cpumask);
  160. hps_ctxt.little_num_limit_ultra_power_saving =
  161. cpumask_weight(&hps_ctxt.little_cpumask);
  162. hps_ctxt.little_num_limit_power_serv =
  163. cpumask_weight(&hps_ctxt.little_cpumask);
  164. hps_ctxt.big_num_base_perf_serv = 0;
  165. hps_ctxt.big_num_limit_thermal = cpumask_weight(&hps_ctxt.big_cpumask);
  166. hps_ctxt.big_num_limit_low_battery =
  167. cpumask_weight(&hps_ctxt.big_cpumask);
  168. hps_ctxt.big_num_limit_ultra_power_saving =
  169. cpumask_weight(&hps_ctxt.big_cpumask);
  170. hps_ctxt.big_num_limit_power_serv =
  171. cpumask_weight(&hps_ctxt.big_cpumask);
  172. hps_warn(
  173. "%s: little_cpu_id_min: %u, little_cpu_id_max: %u, big_cpu_id_min: %u, big_cpu_id_max: %u\n",
  174. __func__,
  175. hps_ctxt.little_cpu_id_min, hps_ctxt.little_cpu_id_max,
  176. hps_ctxt.big_cpu_id_min, hps_ctxt.big_cpu_id_max);
  177. return r;
  178. }
  179. /*
  180. * deinit
  181. */
  182. int hps_cpu_deinit(void)
  183. {
  184. int r = 0;
  185. hps_warn("hps_cpu_deinit\n");
  186. return r;
  187. }