mali_kbase_js_backend.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /*
  2. *
  3. * (C) COPYRIGHT 2014-2015 ARM Limited. All rights reserved.
  4. *
  5. * This program is free software and is provided to you under the terms of the
  6. * GNU General Public License version 2 as published by the Free Software
  7. * Foundation, and any use by you of this program is subject to the terms
  8. * of such GNU licence.
  9. *
  10. * A copy of the licence is included with the program, and can also be obtained
  11. * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  12. * Boston, MA 02110-1301, USA.
  13. *
  14. */
  15. /*
  16. * Register-based HW access backend specific job scheduler APIs
  17. */
  18. #include <mali_kbase.h>
  19. #include <mali_kbase_hwaccess_jm.h>
  20. #include <backend/gpu/mali_kbase_jm_internal.h>
  21. #include <backend/gpu/mali_kbase_js_internal.h>
  22. /*
  23. * Define for when dumping is enabled.
  24. * This should not be based on the instrumentation level as whether dumping is
  25. * enabled for a particular level is down to the integrator. However this is
  26. * being used for now as otherwise the cinstr headers would be needed.
  27. */
  28. #define CINSTR_DUMPING_ENABLED 0
  29. /*
  30. * Hold the runpool_mutex for this
  31. */
  32. static inline bool timer_callback_should_run(struct kbase_device *kbdev)
  33. {
  34. struct kbase_backend_data *backend = &kbdev->hwaccess.backend;
  35. s8 nr_running_ctxs;
  36. lockdep_assert_held(&kbdev->js_data.runpool_mutex);
  37. /* Timer must stop if we are suspending */
  38. if (backend->suspend_timer)
  39. return false;
  40. /* nr_contexts_pullable is updated with the runpool_mutex. However, the
  41. * locking in the caller gives us a barrier that ensures
  42. * nr_contexts_pullable is up-to-date for reading */
  43. nr_running_ctxs = atomic_read(&kbdev->js_data.nr_contexts_runnable);
  44. #ifdef CONFIG_MALI_DEBUG
  45. if (kbdev->js_data.softstop_always) {
  46. /* Debug support for allowing soft-stop on a single context */
  47. return true;
  48. }
  49. #endif // ifdef CONFIG_MALI_DEBUG
  50. if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_9435)) {
  51. /* Timeouts would have to be 4x longer (due to micro-
  52. * architectural design) to support OpenCL conformance tests, so
  53. * only run the timer when there's:
  54. * - 2 or more CL contexts
  55. * - 1 or more GLES contexts
  56. *
  57. * NOTE: We will treat a context that has both Compute and Non-
  58. * Compute jobs will be treated as an OpenCL context (hence, we
  59. * don't check KBASEP_JS_CTX_ATTR_NON_COMPUTE).
  60. */
  61. {
  62. s8 nr_compute_ctxs =
  63. kbasep_js_ctx_attr_count_on_runpool(kbdev,
  64. KBASEP_JS_CTX_ATTR_COMPUTE);
  65. s8 nr_noncompute_ctxs = nr_running_ctxs -
  66. nr_compute_ctxs;
  67. return (bool) (nr_compute_ctxs >= 2 ||
  68. nr_noncompute_ctxs > 0);
  69. }
  70. } else {
  71. /* Run the timer callback whenever you have at least 1 context
  72. */
  73. return (bool) (nr_running_ctxs > 0);
  74. }
  75. }
  76. static enum hrtimer_restart timer_callback(struct hrtimer *timer)
  77. {
  78. unsigned long flags;
  79. struct kbase_device *kbdev;
  80. struct kbasep_js_device_data *js_devdata;
  81. struct kbase_backend_data *backend;
  82. int s;
  83. bool reset_needed = false;
  84. KBASE_DEBUG_ASSERT(timer != NULL);
  85. backend = container_of(timer, struct kbase_backend_data,
  86. scheduling_timer);
  87. kbdev = container_of(backend, struct kbase_device, hwaccess.backend);
  88. js_devdata = &kbdev->js_data;
  89. /* Loop through the slots */
  90. spin_lock_irqsave(&js_devdata->runpool_irq.lock, flags);
  91. for (s = 0; s < kbdev->gpu_props.num_job_slots; s++) {
  92. struct kbase_jd_atom *atom = NULL;
  93. if (kbase_backend_nr_atoms_on_slot(kbdev, s) > 0) {
  94. atom = kbase_gpu_inspect(kbdev, s, 0);
  95. KBASE_DEBUG_ASSERT(atom != NULL);
  96. }
  97. if (atom != NULL) {
  98. /* The current version of the model doesn't support
  99. * Soft-Stop */
  100. if (!kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_5736)) {
  101. u32 ticks = atom->sched_info.cfs.ticks++;
  102. #if !CINSTR_DUMPING_ENABLED
  103. u32 soft_stop_ticks, hard_stop_ticks,
  104. gpu_reset_ticks;
  105. if (atom->core_req & BASE_JD_REQ_ONLY_COMPUTE) {
  106. soft_stop_ticks =
  107. js_devdata->soft_stop_ticks_cl;
  108. hard_stop_ticks =
  109. js_devdata->hard_stop_ticks_cl;
  110. gpu_reset_ticks =
  111. js_devdata->gpu_reset_ticks_cl;
  112. } else {
  113. soft_stop_ticks =
  114. js_devdata->soft_stop_ticks;
  115. hard_stop_ticks =
  116. js_devdata->hard_stop_ticks_ss;
  117. gpu_reset_ticks =
  118. js_devdata->gpu_reset_ticks_ss;
  119. }
  120. /* Job is Soft-Stoppable */
  121. if (ticks == soft_stop_ticks) {
  122. int disjoint_threshold =
  123. KBASE_DISJOINT_STATE_INTERLEAVED_CONTEXT_COUNT_THRESHOLD;
  124. u32 softstop_flags = 0u;
  125. /* Job has been scheduled for at least
  126. * js_devdata->soft_stop_ticks ticks.
  127. * Soft stop the slot so we can run
  128. * other jobs.
  129. */
  130. dev_dbg(kbdev->dev, "Soft-stop");
  131. #if !KBASE_DISABLE_SCHEDULING_SOFT_STOPS
  132. /* nr_user_contexts_running is updated
  133. * with the runpool_mutex, but we can't
  134. * take that here.
  135. *
  136. * However, if it's about to be
  137. * increased then the new context can't
  138. * run any jobs until they take the
  139. * runpool_irq lock, so it's OK to
  140. * observe the older value.
  141. *
  142. * Similarly, if it's about to be
  143. * decreased, the last job from another
  144. * context has already finished, so it's
  145. * not too bad that we observe the older
  146. * value and register a disjoint event
  147. * when we try soft-stopping */
  148. if (js_devdata->nr_user_contexts_running
  149. >= disjoint_threshold)
  150. softstop_flags |=
  151. JS_COMMAND_SW_CAUSES_DISJOINT;
  152. kbase_job_slot_softstop_swflags(kbdev,
  153. s, atom, softstop_flags);
  154. #endif // !KBASE_DISABLE_SCHEDULING_SOFT_STOPS
  155. } else if (ticks == hard_stop_ticks) {
  156. /* Job has been scheduled for at least
  157. * js_devdata->hard_stop_ticks_ss ticks.
  158. * It should have been soft-stopped by
  159. * now. Hard stop the slot.
  160. */
  161. #if !KBASE_DISABLE_SCHEDULING_HARD_STOPS
  162. int ms =
  163. js_devdata->scheduling_period_ns
  164. / 1000000u;
  165. dev_warn(kbdev->dev, "JS: Job Hard-Stopped (took more than %lu ticks at %lu ms/tick)",
  166. (unsigned long)ticks,
  167. (unsigned long)ms);
  168. kbase_job_slot_hardstop(atom->kctx, s,
  169. atom);
  170. #endif // !KBASE_DISABLE_SCHEDULING_HARD_STOPS
  171. } else if (ticks == gpu_reset_ticks) {
  172. /* Job has been scheduled for at least
  173. * js_devdata->gpu_reset_ticks_ss ticks.
  174. * It should have left the GPU by now.
  175. * Signal that the GPU needs to be
  176. * reset.
  177. */
  178. reset_needed = true;
  179. }
  180. #else // !CINSTR_DUMPING_ENABLED
  181. /* NOTE: During CINSTR_DUMPING_ENABLED, we use
  182. * the alternate timeouts, which makes the hard-
  183. * stop and GPU reset timeout much longer. We
  184. * also ensure that we don't soft-stop at all.
  185. */
  186. if (ticks == js_devdata->soft_stop_ticks) {
  187. /* Job has been scheduled for at least
  188. * js_devdata->soft_stop_ticks. We do
  189. * not soft-stop during
  190. * CINSTR_DUMPING_ENABLED, however.
  191. */
  192. dev_dbg(kbdev->dev, "Soft-stop");
  193. } else if (ticks ==
  194. js_devdata->hard_stop_ticks_dumping) {
  195. /* Job has been scheduled for at least
  196. * js_devdata->hard_stop_ticks_dumping
  197. * ticks. Hard stop the slot.
  198. */
  199. #if !KBASE_DISABLE_SCHEDULING_HARD_STOPS
  200. int ms =
  201. js_devdata->scheduling_period_ns
  202. / 1000000u;
  203. dev_warn(kbdev->dev, "JS: Job Hard-Stopped (took more than %lu ticks at %lu ms/tick)",
  204. (unsigned long)ticks,
  205. (unsigned long)ms);
  206. kbase_job_slot_hardstop(atom->kctx, s,
  207. atom);
  208. #endif // !KBASE_DISABLE_SCHEDULING_HARD_STOPS
  209. } else if (ticks ==
  210. js_devdata->gpu_reset_ticks_dumping) {
  211. /* Job has been scheduled for at least
  212. * js_devdata->gpu_reset_ticks_dumping
  213. * ticks. It should have left the GPU by
  214. * now. Signal that the GPU needs to be
  215. * reset.
  216. */
  217. reset_needed = true;
  218. }
  219. #endif // !CINSTR_DUMPING_ENABLED
  220. }
  221. }
  222. }
  223. #if KBASE_GPU_RESET_EN
  224. if (reset_needed) {
  225. dev_err(kbdev->dev, "JS: Job has been on the GPU for too long (JS_RESET_TICKS_SS/DUMPING timeout hit). Issueing GPU soft-reset to resolve.");
  226. if (kbase_prepare_to_reset_gpu_locked(kbdev))
  227. kbase_reset_gpu_locked(kbdev);
  228. }
  229. #endif // KBASE_GPU_RESET_EN
  230. /* the timer is re-issued if there is contexts in the run-pool */
  231. if (backend->timer_running)
  232. hrtimer_start(&backend->scheduling_timer,
  233. HR_TIMER_DELAY_NSEC(js_devdata->scheduling_period_ns),
  234. HRTIMER_MODE_REL);
  235. spin_unlock_irqrestore(&js_devdata->runpool_irq.lock, flags);
  236. return HRTIMER_NORESTART;
  237. }
  238. void kbase_backend_ctx_count_changed(struct kbase_device *kbdev)
  239. {
  240. struct kbasep_js_device_data *js_devdata = &kbdev->js_data;
  241. struct kbase_backend_data *backend = &kbdev->hwaccess.backend;
  242. unsigned long flags;
  243. lockdep_assert_held(&js_devdata->runpool_mutex);
  244. if (!timer_callback_should_run(kbdev)) {
  245. /* Take spinlock to force synchronisation with timer */
  246. spin_lock_irqsave(&js_devdata->runpool_irq.lock, flags);
  247. backend->timer_running = false;
  248. spin_unlock_irqrestore(&js_devdata->runpool_irq.lock, flags);
  249. /* From now on, return value of timer_callback_should_run() will
  250. * also cause the timer to not requeue itself. Its return value
  251. * cannot change, because it depends on variables updated with
  252. * the runpool_mutex held, which the caller of this must also
  253. * hold */
  254. hrtimer_cancel(&backend->scheduling_timer);
  255. }
  256. if (timer_callback_should_run(kbdev) && !backend->timer_running) {
  257. /* Take spinlock to force synchronisation with timer */
  258. spin_lock_irqsave(&js_devdata->runpool_irq.lock, flags);
  259. backend->timer_running = true;
  260. spin_unlock_irqrestore(&js_devdata->runpool_irq.lock, flags);
  261. hrtimer_start(&backend->scheduling_timer,
  262. HR_TIMER_DELAY_NSEC(js_devdata->scheduling_period_ns),
  263. HRTIMER_MODE_REL);
  264. KBASE_TRACE_ADD(kbdev, JS_POLICY_TIMER_START, NULL, NULL, 0u,
  265. 0u);
  266. }
  267. }
  268. int kbase_backend_timer_init(struct kbase_device *kbdev)
  269. {
  270. struct kbase_backend_data *backend = &kbdev->hwaccess.backend;
  271. hrtimer_init(&backend->scheduling_timer, CLOCK_MONOTONIC,
  272. HRTIMER_MODE_REL);
  273. backend->scheduling_timer.function = timer_callback;
  274. backend->timer_running = false;
  275. return 0;
  276. }
  277. void kbase_backend_timer_term(struct kbase_device *kbdev)
  278. {
  279. struct kbase_backend_data *backend = &kbdev->hwaccess.backend;
  280. hrtimer_cancel(&backend->scheduling_timer);
  281. }
  282. void kbase_backend_timer_suspend(struct kbase_device *kbdev)
  283. {
  284. struct kbase_backend_data *backend = &kbdev->hwaccess.backend;
  285. backend->suspend_timer = true;
  286. kbase_backend_ctx_count_changed(kbdev);
  287. }
  288. void kbase_backend_timer_resume(struct kbase_device *kbdev)
  289. {
  290. struct kbase_backend_data *backend = &kbdev->hwaccess.backend;
  291. backend->suspend_timer = false;
  292. kbase_backend_ctx_count_changed(kbdev);
  293. }