lima_sched.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553
  1. // SPDX-License-Identifier: GPL-2.0 OR MIT
  2. /* Copyright 2017-2019 Qiang Yu <yuq825@gmail.com> */
  3. #include <linux/hardirq.h>
  4. #include <linux/iosys-map.h>
  5. #include <linux/kthread.h>
  6. #include <linux/slab.h>
  7. #include <linux/vmalloc.h>
  8. #include <linux/pm_runtime.h>
  9. #include "lima_devfreq.h"
  10. #include "lima_drv.h"
  11. #include "lima_sched.h"
  12. #include "lima_vm.h"
  13. #include "lima_mmu.h"
  14. #include "lima_l2_cache.h"
  15. #include "lima_gem.h"
  16. #include "lima_trace.h"
  17. struct lima_fence {
  18. struct dma_fence base;
  19. struct lima_sched_pipe *pipe;
  20. };
  21. static struct kmem_cache *lima_fence_slab;
  22. static int lima_fence_slab_refcnt;
  23. int lima_sched_slab_init(void)
  24. {
  25. if (!lima_fence_slab) {
  26. lima_fence_slab = kmem_cache_create(
  27. "lima_fence", sizeof(struct lima_fence), 0,
  28. SLAB_HWCACHE_ALIGN, NULL);
  29. if (!lima_fence_slab)
  30. return -ENOMEM;
  31. }
  32. lima_fence_slab_refcnt++;
  33. return 0;
  34. }
  35. void lima_sched_slab_fini(void)
  36. {
  37. if (!--lima_fence_slab_refcnt) {
  38. kmem_cache_destroy(lima_fence_slab);
  39. lima_fence_slab = NULL;
  40. }
  41. }
  42. static inline struct lima_fence *to_lima_fence(struct dma_fence *fence)
  43. {
  44. return container_of(fence, struct lima_fence, base);
  45. }
  46. static const char *lima_fence_get_driver_name(struct dma_fence *fence)
  47. {
  48. return "lima";
  49. }
  50. static const char *lima_fence_get_timeline_name(struct dma_fence *fence)
  51. {
  52. struct lima_fence *f = to_lima_fence(fence);
  53. return f->pipe->base.name;
  54. }
  55. static void lima_fence_release_rcu(struct rcu_head *rcu)
  56. {
  57. struct dma_fence *f = container_of(rcu, struct dma_fence, rcu);
  58. struct lima_fence *fence = to_lima_fence(f);
  59. kmem_cache_free(lima_fence_slab, fence);
  60. }
  61. static void lima_fence_release(struct dma_fence *fence)
  62. {
  63. struct lima_fence *f = to_lima_fence(fence);
  64. call_rcu(&f->base.rcu, lima_fence_release_rcu);
  65. }
  66. static const struct dma_fence_ops lima_fence_ops = {
  67. .get_driver_name = lima_fence_get_driver_name,
  68. .get_timeline_name = lima_fence_get_timeline_name,
  69. .release = lima_fence_release,
  70. };
  71. static struct lima_fence *lima_fence_create(struct lima_sched_pipe *pipe)
  72. {
  73. struct lima_fence *fence;
  74. fence = kmem_cache_zalloc(lima_fence_slab, GFP_KERNEL);
  75. if (!fence)
  76. return NULL;
  77. fence->pipe = pipe;
  78. dma_fence_init(&fence->base, &lima_fence_ops, &pipe->fence_lock,
  79. pipe->fence_context, ++pipe->fence_seqno);
  80. return fence;
  81. }
  82. static inline struct lima_sched_task *to_lima_task(struct drm_sched_job *job)
  83. {
  84. return container_of(job, struct lima_sched_task, base);
  85. }
  86. static inline struct lima_sched_pipe *to_lima_pipe(struct drm_gpu_scheduler *sched)
  87. {
  88. return container_of(sched, struct lima_sched_pipe, base);
  89. }
  90. int lima_sched_task_init(struct lima_sched_task *task,
  91. struct lima_sched_context *context,
  92. struct lima_bo **bos, int num_bos,
  93. struct lima_vm *vm)
  94. {
  95. int err, i;
  96. task->bos = kmemdup(bos, sizeof(*bos) * num_bos, GFP_KERNEL);
  97. if (!task->bos)
  98. return -ENOMEM;
  99. for (i = 0; i < num_bos; i++)
  100. drm_gem_object_get(&bos[i]->base.base);
  101. err = drm_sched_job_init(&task->base, &context->base, 1, vm);
  102. if (err) {
  103. kfree(task->bos);
  104. return err;
  105. }
  106. drm_sched_job_arm(&task->base);
  107. task->num_bos = num_bos;
  108. task->vm = lima_vm_get(vm);
  109. return 0;
  110. }
  111. void lima_sched_task_fini(struct lima_sched_task *task)
  112. {
  113. int i;
  114. drm_sched_job_cleanup(&task->base);
  115. if (task->bos) {
  116. for (i = 0; i < task->num_bos; i++)
  117. drm_gem_object_put(&task->bos[i]->base.base);
  118. kfree(task->bos);
  119. }
  120. lima_vm_put(task->vm);
  121. }
  122. int lima_sched_context_init(struct lima_sched_pipe *pipe,
  123. struct lima_sched_context *context)
  124. {
  125. struct drm_gpu_scheduler *sched = &pipe->base;
  126. return drm_sched_entity_init(&context->base, DRM_SCHED_PRIORITY_NORMAL,
  127. &sched, 1, NULL);
  128. }
  129. void lima_sched_context_fini(struct lima_sched_pipe *pipe,
  130. struct lima_sched_context *context)
  131. {
  132. drm_sched_entity_destroy(&context->base);
  133. }
  134. struct dma_fence *lima_sched_context_queue_task(struct lima_sched_task *task)
  135. {
  136. struct dma_fence *fence = dma_fence_get(&task->base.s_fence->finished);
  137. trace_lima_task_submit(task);
  138. drm_sched_entity_push_job(&task->base);
  139. return fence;
  140. }
  141. static int lima_pm_busy(struct lima_device *ldev)
  142. {
  143. int ret;
  144. /* resume GPU if it has been suspended by runtime PM */
  145. ret = pm_runtime_resume_and_get(ldev->dev);
  146. if (ret < 0)
  147. return ret;
  148. lima_devfreq_record_busy(&ldev->devfreq);
  149. return 0;
  150. }
  151. static void lima_pm_idle(struct lima_device *ldev)
  152. {
  153. lima_devfreq_record_idle(&ldev->devfreq);
  154. /* GPU can do auto runtime suspend */
  155. pm_runtime_mark_last_busy(ldev->dev);
  156. pm_runtime_put_autosuspend(ldev->dev);
  157. }
  158. static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job)
  159. {
  160. struct lima_sched_task *task = to_lima_task(job);
  161. struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
  162. struct lima_device *ldev = pipe->ldev;
  163. struct lima_fence *fence;
  164. int i, err;
  165. /* after GPU reset */
  166. if (job->s_fence->finished.error < 0)
  167. return NULL;
  168. fence = lima_fence_create(pipe);
  169. if (!fence)
  170. return NULL;
  171. err = lima_pm_busy(ldev);
  172. if (err < 0) {
  173. dma_fence_put(&fence->base);
  174. return NULL;
  175. }
  176. task->fence = &fence->base;
  177. /* for caller usage of the fence, otherwise irq handler
  178. * may consume the fence before caller use it
  179. */
  180. dma_fence_get(task->fence);
  181. pipe->current_task = task;
  182. /* this is needed for MMU to work correctly, otherwise GP/PP
  183. * will hang or page fault for unknown reason after running for
  184. * a while.
  185. *
  186. * Need to investigate:
  187. * 1. is it related to TLB
  188. * 2. how much performance will be affected by L2 cache flush
  189. * 3. can we reduce the calling of this function because all
  190. * GP/PP use the same L2 cache on mali400
  191. *
  192. * TODO:
  193. * 1. move this to task fini to save some wait time?
  194. * 2. when GP/PP use different l2 cache, need PP wait GP l2
  195. * cache flush?
  196. */
  197. for (i = 0; i < pipe->num_l2_cache; i++)
  198. lima_l2_cache_flush(pipe->l2_cache[i]);
  199. lima_vm_put(pipe->current_vm);
  200. pipe->current_vm = lima_vm_get(task->vm);
  201. if (pipe->bcast_mmu)
  202. lima_mmu_switch_vm(pipe->bcast_mmu, pipe->current_vm);
  203. else {
  204. for (i = 0; i < pipe->num_mmu; i++)
  205. lima_mmu_switch_vm(pipe->mmu[i], pipe->current_vm);
  206. }
  207. trace_lima_task_run(task);
  208. pipe->error = false;
  209. pipe->task_run(pipe, task);
  210. return task->fence;
  211. }
  212. static void lima_sched_build_error_task_list(struct lima_sched_task *task)
  213. {
  214. struct lima_sched_error_task *et;
  215. struct lima_sched_pipe *pipe = to_lima_pipe(task->base.sched);
  216. struct lima_ip *ip = pipe->processor[0];
  217. int pipe_id = ip->id == lima_ip_gp ? lima_pipe_gp : lima_pipe_pp;
  218. struct lima_device *dev = ip->dev;
  219. struct lima_sched_context *sched_ctx =
  220. container_of(task->base.entity,
  221. struct lima_sched_context, base);
  222. struct lima_ctx *ctx =
  223. container_of(sched_ctx, struct lima_ctx, context[pipe_id]);
  224. struct lima_dump_task *dt;
  225. struct lima_dump_chunk *chunk;
  226. struct lima_dump_chunk_pid *pid_chunk;
  227. struct lima_dump_chunk_buffer *buffer_chunk;
  228. u32 size, task_size, mem_size;
  229. int i;
  230. struct iosys_map map;
  231. int ret;
  232. mutex_lock(&dev->error_task_list_lock);
  233. if (dev->dump.num_tasks >= lima_max_error_tasks) {
  234. dev_info(dev->dev, "fail to save task state from %s pid %d: "
  235. "error task list is full\n", ctx->pname, ctx->pid);
  236. goto out;
  237. }
  238. /* frame chunk */
  239. size = sizeof(struct lima_dump_chunk) + pipe->frame_size;
  240. /* process name chunk */
  241. size += sizeof(struct lima_dump_chunk) + sizeof(ctx->pname);
  242. /* pid chunk */
  243. size += sizeof(struct lima_dump_chunk);
  244. /* buffer chunks */
  245. for (i = 0; i < task->num_bos; i++) {
  246. struct lima_bo *bo = task->bos[i];
  247. size += sizeof(struct lima_dump_chunk);
  248. size += bo->heap_size ? bo->heap_size : lima_bo_size(bo);
  249. }
  250. task_size = size + sizeof(struct lima_dump_task);
  251. mem_size = task_size + sizeof(*et);
  252. et = kvmalloc(mem_size, GFP_KERNEL);
  253. if (!et) {
  254. dev_err(dev->dev, "fail to alloc task dump buffer of size %x\n",
  255. mem_size);
  256. goto out;
  257. }
  258. et->data = et + 1;
  259. et->size = task_size;
  260. dt = et->data;
  261. memset(dt, 0, sizeof(*dt));
  262. dt->id = pipe_id;
  263. dt->size = size;
  264. chunk = (struct lima_dump_chunk *)(dt + 1);
  265. memset(chunk, 0, sizeof(*chunk));
  266. chunk->id = LIMA_DUMP_CHUNK_FRAME;
  267. chunk->size = pipe->frame_size;
  268. memcpy(chunk + 1, task->frame, pipe->frame_size);
  269. dt->num_chunks++;
  270. chunk = (void *)(chunk + 1) + chunk->size;
  271. memset(chunk, 0, sizeof(*chunk));
  272. chunk->id = LIMA_DUMP_CHUNK_PROCESS_NAME;
  273. chunk->size = sizeof(ctx->pname);
  274. memcpy(chunk + 1, ctx->pname, sizeof(ctx->pname));
  275. dt->num_chunks++;
  276. pid_chunk = (void *)(chunk + 1) + chunk->size;
  277. memset(pid_chunk, 0, sizeof(*pid_chunk));
  278. pid_chunk->id = LIMA_DUMP_CHUNK_PROCESS_ID;
  279. pid_chunk->pid = ctx->pid;
  280. dt->num_chunks++;
  281. buffer_chunk = (void *)(pid_chunk + 1) + pid_chunk->size;
  282. for (i = 0; i < task->num_bos; i++) {
  283. struct lima_bo *bo = task->bos[i];
  284. void *data;
  285. memset(buffer_chunk, 0, sizeof(*buffer_chunk));
  286. buffer_chunk->id = LIMA_DUMP_CHUNK_BUFFER;
  287. buffer_chunk->va = lima_vm_get_va(task->vm, bo);
  288. if (bo->heap_size) {
  289. buffer_chunk->size = bo->heap_size;
  290. data = vmap(bo->base.pages, bo->heap_size >> PAGE_SHIFT,
  291. VM_MAP, pgprot_writecombine(PAGE_KERNEL));
  292. if (!data) {
  293. kvfree(et);
  294. goto out;
  295. }
  296. memcpy(buffer_chunk + 1, data, buffer_chunk->size);
  297. vunmap(data);
  298. } else {
  299. buffer_chunk->size = lima_bo_size(bo);
  300. ret = drm_gem_vmap_unlocked(&bo->base.base, &map);
  301. if (ret) {
  302. kvfree(et);
  303. goto out;
  304. }
  305. memcpy(buffer_chunk + 1, map.vaddr, buffer_chunk->size);
  306. drm_gem_vunmap_unlocked(&bo->base.base, &map);
  307. }
  308. buffer_chunk = (void *)(buffer_chunk + 1) + buffer_chunk->size;
  309. dt->num_chunks++;
  310. }
  311. list_add(&et->list, &dev->error_task_list);
  312. dev->dump.size += et->size;
  313. dev->dump.num_tasks++;
  314. dev_info(dev->dev, "save error task state success\n");
  315. out:
  316. mutex_unlock(&dev->error_task_list_lock);
  317. }
  318. static enum drm_gpu_sched_stat lima_sched_timedout_job(struct drm_sched_job *job)
  319. {
  320. struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
  321. struct lima_sched_task *task = to_lima_task(job);
  322. struct lima_device *ldev = pipe->ldev;
  323. struct lima_ip *ip = pipe->processor[0];
  324. int i;
  325. /*
  326. * If the GPU managed to complete this jobs fence, the timeout is
  327. * spurious. Bail out.
  328. */
  329. if (dma_fence_is_signaled(task->fence)) {
  330. DRM_WARN("%s spurious timeout\n", lima_ip_name(ip));
  331. return DRM_GPU_SCHED_STAT_NOMINAL;
  332. }
  333. /*
  334. * Lima IRQ handler may take a long time to process an interrupt
  335. * if there is another IRQ handler hogging the processing.
  336. * In order to catch such cases and not report spurious Lima job
  337. * timeouts, synchronize the IRQ handler and re-check the fence
  338. * status.
  339. */
  340. for (i = 0; i < pipe->num_processor; i++)
  341. synchronize_irq(pipe->processor[i]->irq);
  342. if (pipe->bcast_processor)
  343. synchronize_irq(pipe->bcast_processor->irq);
  344. if (dma_fence_is_signaled(task->fence)) {
  345. DRM_WARN("%s unexpectedly high interrupt latency\n", lima_ip_name(ip));
  346. return DRM_GPU_SCHED_STAT_NOMINAL;
  347. }
  348. /*
  349. * The task might still finish while this timeout handler runs.
  350. * To prevent a race condition on its completion, mask all irqs
  351. * on the running core until the next hard reset completes.
  352. */
  353. pipe->task_mask_irq(pipe);
  354. if (!pipe->error)
  355. DRM_ERROR("%s job timeout\n", lima_ip_name(ip));
  356. drm_sched_stop(&pipe->base, &task->base);
  357. drm_sched_increase_karma(&task->base);
  358. if (lima_max_error_tasks)
  359. lima_sched_build_error_task_list(task);
  360. pipe->task_error(pipe);
  361. if (pipe->bcast_mmu)
  362. lima_mmu_page_fault_resume(pipe->bcast_mmu);
  363. else {
  364. for (i = 0; i < pipe->num_mmu; i++)
  365. lima_mmu_page_fault_resume(pipe->mmu[i]);
  366. }
  367. lima_vm_put(pipe->current_vm);
  368. pipe->current_vm = NULL;
  369. pipe->current_task = NULL;
  370. lima_pm_idle(ldev);
  371. drm_sched_resubmit_jobs(&pipe->base);
  372. drm_sched_start(&pipe->base);
  373. return DRM_GPU_SCHED_STAT_NOMINAL;
  374. }
  375. static void lima_sched_free_job(struct drm_sched_job *job)
  376. {
  377. struct lima_sched_task *task = to_lima_task(job);
  378. struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
  379. struct lima_vm *vm = task->vm;
  380. struct lima_bo **bos = task->bos;
  381. int i;
  382. dma_fence_put(task->fence);
  383. for (i = 0; i < task->num_bos; i++)
  384. lima_vm_bo_del(vm, bos[i]);
  385. lima_sched_task_fini(task);
  386. kmem_cache_free(pipe->task_slab, task);
  387. }
  388. static const struct drm_sched_backend_ops lima_sched_ops = {
  389. .run_job = lima_sched_run_job,
  390. .timedout_job = lima_sched_timedout_job,
  391. .free_job = lima_sched_free_job,
  392. };
  393. static void lima_sched_recover_work(struct work_struct *work)
  394. {
  395. struct lima_sched_pipe *pipe =
  396. container_of(work, struct lima_sched_pipe, recover_work);
  397. int i;
  398. for (i = 0; i < pipe->num_l2_cache; i++)
  399. lima_l2_cache_flush(pipe->l2_cache[i]);
  400. if (pipe->bcast_mmu) {
  401. lima_mmu_flush_tlb(pipe->bcast_mmu);
  402. } else {
  403. for (i = 0; i < pipe->num_mmu; i++)
  404. lima_mmu_flush_tlb(pipe->mmu[i]);
  405. }
  406. if (pipe->task_recover(pipe))
  407. drm_sched_fault(&pipe->base);
  408. }
  409. int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name)
  410. {
  411. unsigned int timeout = lima_sched_timeout_ms > 0 ?
  412. lima_sched_timeout_ms : 10000;
  413. pipe->fence_context = dma_fence_context_alloc(1);
  414. spin_lock_init(&pipe->fence_lock);
  415. INIT_WORK(&pipe->recover_work, lima_sched_recover_work);
  416. return drm_sched_init(&pipe->base, &lima_sched_ops, NULL,
  417. DRM_SCHED_PRIORITY_COUNT,
  418. 1,
  419. lima_job_hang_limit,
  420. msecs_to_jiffies(timeout), NULL,
  421. NULL, name, pipe->ldev->dev);
  422. }
  423. void lima_sched_pipe_fini(struct lima_sched_pipe *pipe)
  424. {
  425. drm_sched_fini(&pipe->base);
  426. }
  427. void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe)
  428. {
  429. struct lima_sched_task *task = pipe->current_task;
  430. struct lima_device *ldev = pipe->ldev;
  431. if (pipe->error) {
  432. if (task && task->recoverable)
  433. schedule_work(&pipe->recover_work);
  434. else
  435. drm_sched_fault(&pipe->base);
  436. } else {
  437. pipe->task_fini(pipe);
  438. dma_fence_signal(task->fence);
  439. lima_pm_idle(ldev);
  440. }
  441. }