kfd_queue.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. // SPDX-License-Identifier: GPL-2.0 OR MIT
  2. /*
  3. * Copyright 2014-2022 Advanced Micro Devices, Inc.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9. * and/or sell copies of the Software, and to permit persons to whom the
  10. * Software is furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  19. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  20. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  21. * OTHER DEALINGS IN THE SOFTWARE.
  22. *
  23. */
  24. #include <linux/slab.h>
  25. #include "kfd_priv.h"
  26. #include "kfd_topology.h"
  27. #include "kfd_svm.h"
  28. void print_queue_properties(struct queue_properties *q)
  29. {
  30. if (!q)
  31. return;
  32. pr_debug("Printing queue properties:\n");
  33. pr_debug("Queue Type: %u\n", q->type);
  34. pr_debug("Queue Size: %llu\n", q->queue_size);
  35. pr_debug("Queue percent: %u\n", q->queue_percent);
  36. pr_debug("Queue Address: 0x%llX\n", q->queue_address);
  37. pr_debug("Queue Id: %u\n", q->queue_id);
  38. pr_debug("Queue Process Vmid: %u\n", q->vmid);
  39. pr_debug("Queue Read Pointer: 0x%px\n", q->read_ptr);
  40. pr_debug("Queue Write Pointer: 0x%px\n", q->write_ptr);
  41. pr_debug("Queue Doorbell Pointer: 0x%p\n", q->doorbell_ptr);
  42. pr_debug("Queue Doorbell Offset: %u\n", q->doorbell_off);
  43. }
  44. void print_queue(struct queue *q)
  45. {
  46. if (!q)
  47. return;
  48. pr_debug("Printing queue:\n");
  49. pr_debug("Queue Type: %u\n", q->properties.type);
  50. pr_debug("Queue Size: %llu\n", q->properties.queue_size);
  51. pr_debug("Queue percent: %u\n", q->properties.queue_percent);
  52. pr_debug("Queue Address: 0x%llX\n", q->properties.queue_address);
  53. pr_debug("Queue Id: %u\n", q->properties.queue_id);
  54. pr_debug("Queue Process Vmid: %u\n", q->properties.vmid);
  55. pr_debug("Queue Read Pointer: 0x%px\n", q->properties.read_ptr);
  56. pr_debug("Queue Write Pointer: 0x%px\n", q->properties.write_ptr);
  57. pr_debug("Queue Doorbell Pointer: 0x%p\n", q->properties.doorbell_ptr);
  58. pr_debug("Queue Doorbell Offset: %u\n", q->properties.doorbell_off);
  59. pr_debug("Queue MQD Address: 0x%p\n", q->mqd);
  60. pr_debug("Queue MQD Gart: 0x%llX\n", q->gart_mqd_addr);
  61. pr_debug("Queue Process Address: 0x%p\n", q->process);
  62. pr_debug("Queue Device Address: 0x%p\n", q->device);
  63. }
  64. int init_queue(struct queue **q, const struct queue_properties *properties)
  65. {
  66. struct queue *tmp_q;
  67. tmp_q = kzalloc(sizeof(*tmp_q), GFP_KERNEL);
  68. if (!tmp_q)
  69. return -ENOMEM;
  70. memcpy(&tmp_q->properties, properties, sizeof(*properties));
  71. *q = tmp_q;
  72. return 0;
  73. }
  74. void uninit_queue(struct queue *q)
  75. {
  76. kfree(q);
  77. }
  78. #if IS_ENABLED(CONFIG_HSA_AMD_SVM)
  79. static int kfd_queue_buffer_svm_get(struct kfd_process_device *pdd, u64 addr, u64 size)
  80. {
  81. struct kfd_process *p = pdd->process;
  82. struct list_head update_list;
  83. struct svm_range *prange;
  84. int ret = -EINVAL;
  85. INIT_LIST_HEAD(&update_list);
  86. addr >>= PAGE_SHIFT;
  87. size >>= PAGE_SHIFT;
  88. mutex_lock(&p->svms.lock);
  89. /*
  90. * range may split to multiple svm pranges aligned to granularity boundaery.
  91. */
  92. while (size) {
  93. uint32_t gpuid, gpuidx;
  94. int r;
  95. prange = svm_range_from_addr(&p->svms, addr, NULL);
  96. if (!prange)
  97. break;
  98. if (!prange->mapped_to_gpu)
  99. break;
  100. r = kfd_process_gpuid_from_node(p, pdd->dev, &gpuid, &gpuidx);
  101. if (r < 0)
  102. break;
  103. if (!test_bit(gpuidx, prange->bitmap_access) &&
  104. !test_bit(gpuidx, prange->bitmap_aip))
  105. break;
  106. if (!(prange->flags & KFD_IOCTL_SVM_FLAG_GPU_ALWAYS_MAPPED))
  107. break;
  108. list_add(&prange->update_list, &update_list);
  109. if (prange->last - prange->start + 1 >= size) {
  110. size = 0;
  111. break;
  112. }
  113. size -= prange->last - prange->start + 1;
  114. addr += prange->last - prange->start + 1;
  115. }
  116. if (size) {
  117. pr_debug("[0x%llx 0x%llx] not registered\n", addr, addr + size - 1);
  118. goto out_unlock;
  119. }
  120. list_for_each_entry(prange, &update_list, update_list)
  121. atomic_inc(&prange->queue_refcount);
  122. ret = 0;
  123. out_unlock:
  124. mutex_unlock(&p->svms.lock);
  125. return ret;
  126. }
  127. static void kfd_queue_buffer_svm_put(struct kfd_process_device *pdd, u64 addr, u64 size)
  128. {
  129. struct kfd_process *p = pdd->process;
  130. struct svm_range *prange, *pchild;
  131. struct interval_tree_node *node;
  132. unsigned long last;
  133. addr >>= PAGE_SHIFT;
  134. last = addr + (size >> PAGE_SHIFT) - 1;
  135. mutex_lock(&p->svms.lock);
  136. node = interval_tree_iter_first(&p->svms.objects, addr, last);
  137. while (node) {
  138. struct interval_tree_node *next_node;
  139. unsigned long next_start;
  140. prange = container_of(node, struct svm_range, it_node);
  141. next_node = interval_tree_iter_next(node, addr, last);
  142. next_start = min(node->last, last) + 1;
  143. if (atomic_add_unless(&prange->queue_refcount, -1, 0)) {
  144. list_for_each_entry(pchild, &prange->child_list, child_list)
  145. atomic_add_unless(&pchild->queue_refcount, -1, 0);
  146. }
  147. node = next_node;
  148. addr = next_start;
  149. }
  150. mutex_unlock(&p->svms.lock);
  151. }
  152. #else
  153. static int kfd_queue_buffer_svm_get(struct kfd_process_device *pdd, u64 addr, u64 size)
  154. {
  155. return -EINVAL;
  156. }
  157. static void kfd_queue_buffer_svm_put(struct kfd_process_device *pdd, u64 addr, u64 size)
  158. {
  159. }
  160. #endif
  161. int kfd_queue_buffer_get(struct amdgpu_vm *vm, void __user *addr, struct amdgpu_bo **pbo,
  162. u64 expected_size)
  163. {
  164. struct amdgpu_bo_va_mapping *mapping;
  165. u64 user_addr;
  166. u64 size;
  167. user_addr = (u64)addr >> AMDGPU_GPU_PAGE_SHIFT;
  168. size = expected_size >> AMDGPU_GPU_PAGE_SHIFT;
  169. mapping = amdgpu_vm_bo_lookup_mapping(vm, user_addr);
  170. if (!mapping)
  171. goto out_err;
  172. if (user_addr != mapping->start ||
  173. (size != 0 && user_addr + size - 1 != mapping->last)) {
  174. pr_debug("expected size 0x%llx not equal to mapping addr 0x%llx size 0x%llx\n",
  175. expected_size, mapping->start << AMDGPU_GPU_PAGE_SHIFT,
  176. (mapping->last - mapping->start + 1) << AMDGPU_GPU_PAGE_SHIFT);
  177. goto out_err;
  178. }
  179. *pbo = amdgpu_bo_ref(mapping->bo_va->base.bo);
  180. mapping->bo_va->queue_refcount++;
  181. return 0;
  182. out_err:
  183. *pbo = NULL;
  184. return -EINVAL;
  185. }
  186. /* FIXME: remove this function, just call amdgpu_bo_unref directly */
  187. void kfd_queue_buffer_put(struct amdgpu_bo **bo)
  188. {
  189. amdgpu_bo_unref(bo);
  190. }
  191. int kfd_queue_acquire_buffers(struct kfd_process_device *pdd, struct queue_properties *properties)
  192. {
  193. struct kfd_topology_device *topo_dev;
  194. u64 expected_queue_size;
  195. struct amdgpu_vm *vm;
  196. u32 total_cwsr_size;
  197. int err;
  198. topo_dev = kfd_topology_device_by_id(pdd->dev->id);
  199. if (!topo_dev)
  200. return -EINVAL;
  201. /* AQL queues on GFX7 and GFX8 appear twice their actual size */
  202. if (properties->type == KFD_QUEUE_TYPE_COMPUTE &&
  203. properties->format == KFD_QUEUE_FORMAT_AQL &&
  204. topo_dev->node_props.gfx_target_version >= 70000 &&
  205. topo_dev->node_props.gfx_target_version < 90000)
  206. expected_queue_size = properties->queue_size / 2;
  207. else
  208. expected_queue_size = properties->queue_size;
  209. vm = drm_priv_to_vm(pdd->drm_priv);
  210. err = amdgpu_bo_reserve(vm->root.bo, false);
  211. if (err)
  212. return err;
  213. err = kfd_queue_buffer_get(vm, properties->write_ptr, &properties->wptr_bo, PAGE_SIZE);
  214. if (err)
  215. goto out_err_unreserve;
  216. err = kfd_queue_buffer_get(vm, properties->read_ptr, &properties->rptr_bo, PAGE_SIZE);
  217. if (err)
  218. goto out_err_unreserve;
  219. err = kfd_queue_buffer_get(vm, (void *)properties->queue_address,
  220. &properties->ring_bo, expected_queue_size);
  221. if (err)
  222. goto out_err_unreserve;
  223. /* only compute queue requires EOP buffer and CWSR area */
  224. if (properties->type != KFD_QUEUE_TYPE_COMPUTE)
  225. goto out_unreserve;
  226. /* EOP buffer is not required for all ASICs */
  227. if (properties->eop_ring_buffer_address) {
  228. if (properties->eop_ring_buffer_size != topo_dev->node_props.eop_buffer_size) {
  229. pr_debug("queue eop bo size 0x%x not equal to node eop buf size 0x%x\n",
  230. properties->eop_ring_buffer_size,
  231. topo_dev->node_props.eop_buffer_size);
  232. err = -EINVAL;
  233. goto out_err_unreserve;
  234. }
  235. err = kfd_queue_buffer_get(vm, (void *)properties->eop_ring_buffer_address,
  236. &properties->eop_buf_bo,
  237. properties->eop_ring_buffer_size);
  238. if (err)
  239. goto out_err_unreserve;
  240. }
  241. if (properties->ctl_stack_size != topo_dev->node_props.ctl_stack_size) {
  242. pr_debug("queue ctl stack size 0x%x not equal to node ctl stack size 0x%x\n",
  243. properties->ctl_stack_size,
  244. topo_dev->node_props.ctl_stack_size);
  245. err = -EINVAL;
  246. goto out_err_unreserve;
  247. }
  248. if (properties->ctx_save_restore_area_size != topo_dev->node_props.cwsr_size) {
  249. pr_debug("queue cwsr size 0x%x not equal to node cwsr size 0x%x\n",
  250. properties->ctx_save_restore_area_size,
  251. topo_dev->node_props.cwsr_size);
  252. err = -EINVAL;
  253. goto out_err_unreserve;
  254. }
  255. total_cwsr_size = (topo_dev->node_props.cwsr_size + topo_dev->node_props.debug_memory_size)
  256. * NUM_XCC(pdd->dev->xcc_mask);
  257. total_cwsr_size = ALIGN(total_cwsr_size, PAGE_SIZE);
  258. err = kfd_queue_buffer_get(vm, (void *)properties->ctx_save_restore_area_address,
  259. &properties->cwsr_bo, total_cwsr_size);
  260. if (!err)
  261. goto out_unreserve;
  262. amdgpu_bo_unreserve(vm->root.bo);
  263. err = kfd_queue_buffer_svm_get(pdd, properties->ctx_save_restore_area_address,
  264. total_cwsr_size);
  265. if (err)
  266. goto out_err_release;
  267. return 0;
  268. out_unreserve:
  269. amdgpu_bo_unreserve(vm->root.bo);
  270. return 0;
  271. out_err_unreserve:
  272. amdgpu_bo_unreserve(vm->root.bo);
  273. out_err_release:
  274. /* FIXME: make a _locked version of this that can be called before
  275. * dropping the VM reservation.
  276. */
  277. kfd_queue_unref_bo_vas(pdd, properties);
  278. kfd_queue_release_buffers(pdd, properties);
  279. return err;
  280. }
  281. int kfd_queue_release_buffers(struct kfd_process_device *pdd, struct queue_properties *properties)
  282. {
  283. struct kfd_topology_device *topo_dev;
  284. u32 total_cwsr_size;
  285. kfd_queue_buffer_put(&properties->wptr_bo);
  286. kfd_queue_buffer_put(&properties->rptr_bo);
  287. kfd_queue_buffer_put(&properties->ring_bo);
  288. kfd_queue_buffer_put(&properties->eop_buf_bo);
  289. kfd_queue_buffer_put(&properties->cwsr_bo);
  290. topo_dev = kfd_topology_device_by_id(pdd->dev->id);
  291. if (!topo_dev)
  292. return -EINVAL;
  293. total_cwsr_size = (topo_dev->node_props.cwsr_size + topo_dev->node_props.debug_memory_size)
  294. * NUM_XCC(pdd->dev->xcc_mask);
  295. total_cwsr_size = ALIGN(total_cwsr_size, PAGE_SIZE);
  296. kfd_queue_buffer_svm_put(pdd, properties->ctx_save_restore_area_address, total_cwsr_size);
  297. return 0;
  298. }
  299. void kfd_queue_unref_bo_va(struct amdgpu_vm *vm, struct amdgpu_bo **bo)
  300. {
  301. if (*bo) {
  302. struct amdgpu_bo_va *bo_va;
  303. bo_va = amdgpu_vm_bo_find(vm, *bo);
  304. if (bo_va && bo_va->queue_refcount)
  305. bo_va->queue_refcount--;
  306. }
  307. }
  308. int kfd_queue_unref_bo_vas(struct kfd_process_device *pdd,
  309. struct queue_properties *properties)
  310. {
  311. struct amdgpu_vm *vm;
  312. int err;
  313. vm = drm_priv_to_vm(pdd->drm_priv);
  314. err = amdgpu_bo_reserve(vm->root.bo, false);
  315. if (err)
  316. return err;
  317. kfd_queue_unref_bo_va(vm, &properties->wptr_bo);
  318. kfd_queue_unref_bo_va(vm, &properties->rptr_bo);
  319. kfd_queue_unref_bo_va(vm, &properties->ring_bo);
  320. kfd_queue_unref_bo_va(vm, &properties->eop_buf_bo);
  321. kfd_queue_unref_bo_va(vm, &properties->cwsr_bo);
  322. amdgpu_bo_unreserve(vm->root.bo);
  323. return 0;
  324. }
  325. #define SGPR_SIZE_PER_CU 0x4000
  326. #define LDS_SIZE_PER_CU 0x10000
  327. #define HWREG_SIZE_PER_CU 0x1000
  328. #define DEBUGGER_BYTES_ALIGN 64
  329. #define DEBUGGER_BYTES_PER_WAVE 32
  330. static u32 kfd_get_vgpr_size_per_cu(u32 gfxv)
  331. {
  332. u32 vgpr_size = 0x40000;
  333. if ((gfxv / 100 * 100) == 90400 || /* GFX_VERSION_AQUA_VANJARAM */
  334. gfxv == 90010 || /* GFX_VERSION_ALDEBARAN */
  335. gfxv == 90008) /* GFX_VERSION_ARCTURUS */
  336. vgpr_size = 0x80000;
  337. else if (gfxv == 110000 || /* GFX_VERSION_PLUM_BONITO */
  338. gfxv == 110001 || /* GFX_VERSION_WHEAT_NAS */
  339. gfxv == 120000 || /* GFX_VERSION_GFX1200 */
  340. gfxv == 120001) /* GFX_VERSION_GFX1201 */
  341. vgpr_size = 0x60000;
  342. return vgpr_size;
  343. }
  344. #define WG_CONTEXT_DATA_SIZE_PER_CU(gfxv) \
  345. (kfd_get_vgpr_size_per_cu(gfxv) + SGPR_SIZE_PER_CU +\
  346. LDS_SIZE_PER_CU + HWREG_SIZE_PER_CU)
  347. #define CNTL_STACK_BYTES_PER_WAVE(gfxv) \
  348. ((gfxv) >= 100100 ? 12 : 8) /* GFX_VERSION_NAVI10*/
  349. #define SIZEOF_HSA_USER_CONTEXT_SAVE_AREA_HEADER 40
  350. void kfd_queue_ctx_save_restore_size(struct kfd_topology_device *dev)
  351. {
  352. struct kfd_node_properties *props = &dev->node_props;
  353. u32 gfxv = props->gfx_target_version;
  354. u32 ctl_stack_size;
  355. u32 wg_data_size;
  356. u32 wave_num;
  357. u32 cu_num;
  358. if (gfxv < 80001) /* GFX_VERSION_CARRIZO */
  359. return;
  360. cu_num = props->simd_count / props->simd_per_cu / NUM_XCC(dev->gpu->xcc_mask);
  361. wave_num = (gfxv < 100100) ? /* GFX_VERSION_NAVI10 */
  362. min(cu_num * 40, props->array_count / props->simd_arrays_per_engine * 512)
  363. : cu_num * 32;
  364. wg_data_size = ALIGN(cu_num * WG_CONTEXT_DATA_SIZE_PER_CU(gfxv), PAGE_SIZE);
  365. ctl_stack_size = wave_num * CNTL_STACK_BYTES_PER_WAVE(gfxv) + 8;
  366. ctl_stack_size = ALIGN(SIZEOF_HSA_USER_CONTEXT_SAVE_AREA_HEADER + ctl_stack_size,
  367. PAGE_SIZE);
  368. if ((gfxv / 10000 * 10000) == 100000) {
  369. /* HW design limits control stack size to 0x7000.
  370. * This is insufficient for theoretical PM4 cases
  371. * but sufficient for AQL, limited by SPI events.
  372. */
  373. ctl_stack_size = min(ctl_stack_size, 0x7000);
  374. }
  375. props->ctl_stack_size = ctl_stack_size;
  376. props->debug_memory_size = ALIGN(wave_num * DEBUGGER_BYTES_PER_WAVE, DEBUGGER_BYTES_ALIGN);
  377. props->cwsr_size = ctl_stack_size + wg_data_size;
  378. if (gfxv == 80002) /* GFX_VERSION_TONGA */
  379. props->eop_buffer_size = 0x8000;
  380. else if ((gfxv / 100 * 100) == 90400) /* GFX_VERSION_AQUA_VANJARAM */
  381. props->eop_buffer_size = 4096;
  382. else if (gfxv >= 80000)
  383. props->eop_buffer_size = 4096;
  384. }