1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2024, Advanced Micro Devices, Inc. 4 */ 5 6 #include <drm/amdxdna_accel.h> 7 #include <drm/drm_cache.h> 8 #include <drm/drm_device.h> 9 #include <drm/drm_gem.h> 10 #include <drm/drm_gem_shmem_helper.h> 11 #include <drm/drm_print.h> 12 #include <drm/gpu_scheduler.h> 13 #include <linux/dma-buf.h> 14 #include <linux/dma-direct.h> 15 #include <linux/iosys-map.h> 16 #include <linux/pagemap.h> 17 #include <linux/vmalloc.h> 18 19 #include "amdxdna_cbuf.h" 20 #include "amdxdna_ctx.h" 21 #include "amdxdna_gem.h" 22 #include "amdxdna_pci_drv.h" 23 #include "amdxdna_ubuf.h" 24 25 MODULE_IMPORT_NS("DMA_BUF"); 26 27 /* 28 * The dev BO could be across multiple heap BO chunks. The heap chunks should 29 * be mapped to userspace and the userspace virtual address should be 30 * contiguous. 31 */ 32 static int 33 amdxdna_init_dev_bo(struct amdxdna_gem_obj *dev_bo) 34 { 35 struct amdxdna_client *client = dev_bo->client; 36 struct amdxdna_dev *xdna = client->xdna; 37 struct amdxdna_gem_obj *heap; 38 u64 heap_addr, exp_heap_uva; 39 u32 heap_id; 40 41 if (xa_empty(&client->dev_heap_xa)) { 42 XDNA_DBG(xdna, "Empty heap xa"); 43 return -EAGAIN; 44 } 45 46 for (heap_id = 0; heap_id < client->dev_heap_nid; heap_id++) { 47 heap = xa_load(&client->dev_heap_xa, heap_id); 48 if (!heap) { 49 XDNA_ERR(xdna, "Failed to load heap %d", heap_id); 50 return -EINVAL; 51 } 52 heap_addr = amdxdna_gem_dev_addr(heap); 53 if (heap_addr > dev_bo->mm_node.start) 54 break; 55 } 56 57 heap_id--; 58 heap = xa_load(&client->dev_heap_xa, heap_id); 59 exp_heap_uva = amdxdna_gem_uva(heap); 60 heap_addr = amdxdna_gem_dev_addr(heap); 61 dev_bo->heap_start_id = heap_id; 62 dev_bo->mem.uva = dev_bo->mm_node.start - heap_addr + exp_heap_uva; 63 64 for (; heap_id < client->dev_heap_nid; heap_id++) { 65 heap = xa_load(&client->dev_heap_xa, heap_id); 66 if (!heap) { 67 XDNA_ERR(xdna, "Failed to load heap %d", heap_id); 68 return -EINVAL; 69 } 70 heap_addr = amdxdna_gem_uva(heap); 71 if (heap_addr == AMDXDNA_INVALID_ADDR) { 72 XDNA_ERR(xdna, "Heap %d is not mapped", heap_id); 73 return -EAGAIN; 74 } 75 76 if (heap_addr != exp_heap_uva) { 77 XDNA_ERR(xdna, "Heap %d uva is not contiguous", heap_id); 78 return -EINVAL; 79 } 80 81 if (heap->dev_addr + heap->mem.size >= 82 dev_bo->mm_node.start + dev_bo->mem.size) 83 break; 84 85 exp_heap_uva += heap->mem.size; 86 } 87 88 if (heap_id == client->dev_heap_nid) { 89 XDNA_DBG(xdna, "Can not find heap end"); 90 return -EAGAIN; 91 } 92 93 dev_bo->heap_end_id = heap_id; 94 95 return 0; 96 } 97 98 static int 99 amdxdna_gem_heap_alloc(struct amdxdna_gem_obj *abo) 100 { 101 struct amdxdna_client *client = abo->client; 102 struct amdxdna_dev *xdna = client->xdna; 103 struct amdxdna_mem *mem = &abo->mem; 104 struct amdxdna_gem_obj *heap; 105 unsigned long heap_id; 106 u32 align; 107 int ret; 108 109 mutex_lock(&client->mm_lock); 110 111 if (!mem->size || mem->size > xdna->dev_info->dev_heap_max_size) { 112 XDNA_ERR(xdna, "Invalid dev bo size 0x%lx, max heap 0x%lx", 113 mem->size, xdna->dev_info->dev_heap_max_size); 114 ret = -EINVAL; 115 goto unlock_out; 116 } 117 118 align = 1 << max(PAGE_SHIFT, xdna->dev_info->dev_mem_buf_shift); 119 ret = drm_mm_insert_node_generic(&client->dev_heap_mm, 120 &abo->mm_node, 121 mem->size, align, 122 0, DRM_MM_INSERT_BEST); 123 if (ret) { 124 XDNA_ERR(xdna, "Failed to alloc dev bo memory, ret %d", ret); 125 goto unlock_out; 126 } 127 128 ret = amdxdna_init_dev_bo(abo); 129 if (ret) { 130 drm_mm_remove_node(&abo->mm_node); 131 goto unlock_out; 132 } 133 134 client->heap_usage += mem->size; 135 xa_for_each_range(&client->dev_heap_xa, heap_id, heap, 136 abo->heap_start_id, abo->heap_end_id) 137 drm_gem_object_get(to_gobj(heap)); 138 139 unlock_out: 140 mutex_unlock(&client->mm_lock); 141 142 return ret; 143 } 144 145 static void 146 amdxdna_gem_heap_free(struct amdxdna_gem_obj *abo) 147 { 148 struct amdxdna_client *client = abo->client; 149 struct amdxdna_gem_obj *heap; 150 unsigned long heap_id; 151 152 mutex_lock(&client->mm_lock); 153 154 drm_mm_remove_node(&abo->mm_node); 155 client->heap_usage -= abo->mem.size; 156 157 xa_for_each_range(&client->dev_heap_xa, heap_id, heap, 158 abo->heap_start_id, abo->heap_end_id) 159 drm_gem_object_put(to_gobj(heap)); 160 161 mutex_unlock(&client->mm_lock); 162 } 163 164 static struct amdxdna_gem_obj * 165 amdxdna_gem_create_obj(struct drm_device *dev, size_t size) 166 { 167 struct amdxdna_gem_obj *abo; 168 169 abo = kzalloc_obj(*abo); 170 if (!abo) 171 return ERR_PTR(-ENOMEM); 172 173 abo->pinned = false; 174 abo->assigned_hwctx = AMDXDNA_INVALID_CTX_HANDLE; 175 mutex_init(&abo->lock); 176 177 abo->mem.dma_addr = AMDXDNA_INVALID_ADDR; 178 abo->mem.uva = AMDXDNA_INVALID_ADDR; 179 abo->mem.size = size; 180 abo->open_ref = 0; 181 abo->internal = false; 182 INIT_LIST_HEAD(&abo->mem.umap_list); 183 184 return abo; 185 } 186 187 static void 188 amdxdna_gem_destroy_obj(struct amdxdna_gem_obj *abo) 189 { 190 mutex_destroy(&abo->lock); 191 kfree(abo); 192 } 193 194 /* 195 * Obtains a kernel virtual address on the BO (usually of small size). 196 * The mapping is established on the first call and stays valid until 197 * amdxdna_gem_vunmap() is called. 198 */ 199 void *amdxdna_gem_vmap(struct amdxdna_gem_obj *abo) 200 { 201 struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL); 202 int ret; 203 204 if (abo->mem.kva) 205 return abo->mem.kva; 206 207 /* The first call to get the kva, taking slow path. */ 208 guard(mutex)(&abo->lock); 209 210 if (!abo->mem.kva) { 211 ret = drm_gem_vmap(to_gobj(abo), &map); 212 if (ret) 213 XDNA_ERR(abo->client->xdna, "Vmap bo failed, ret %d", ret); 214 else 215 abo->mem.kva = map.vaddr; 216 } 217 return abo->mem.kva; 218 } 219 220 /* 221 * Free mapping established through amdxdna_gem_vmap() 222 */ 223 static void amdxdna_gem_vunmap(struct amdxdna_gem_obj *abo) 224 { 225 guard(mutex)(&abo->lock); 226 227 if (abo->mem.kva) { 228 struct iosys_map map = IOSYS_MAP_INIT_VADDR(abo->mem.kva); 229 230 drm_gem_vunmap(to_gobj(abo), &map); 231 abo->mem.kva = NULL; 232 } 233 } 234 235 /* 236 * Obtain the address for device to access the BO. 237 */ 238 u64 amdxdna_gem_dev_addr(struct amdxdna_gem_obj *abo) 239 { 240 if (abo->type == AMDXDNA_BO_DEV_HEAP) 241 return abo->dev_addr; 242 if (abo->type == AMDXDNA_BO_DEV) 243 return abo->mm_node.start; 244 return amdxdna_obj_dma_addr(abo); 245 } 246 247 static bool amdxdna_hmm_invalidate(struct mmu_interval_notifier *mni, 248 const struct mmu_notifier_range *range, 249 unsigned long cur_seq) 250 { 251 struct amdxdna_umap *mapp = container_of(mni, struct amdxdna_umap, notifier); 252 struct amdxdna_gem_obj *abo = mapp->abo; 253 struct amdxdna_dev *xdna; 254 255 xdna = to_xdna_dev(to_gobj(abo)->dev); 256 XDNA_DBG(xdna, "Invalidating range 0x%lx, 0x%lx, type %d", 257 mapp->vma->vm_start, mapp->vma->vm_end, abo->type); 258 259 if (!mmu_notifier_range_blockable(range)) 260 return false; 261 262 down_write(&xdna->notifier_lock); 263 abo->mem.map_invalid = true; 264 mapp->invalid = true; 265 mmu_interval_set_seq(&mapp->notifier, cur_seq); 266 up_write(&xdna->notifier_lock); 267 268 if (xdna->dev_info->ops->hmm_invalidate) 269 xdna->dev_info->ops->hmm_invalidate(abo, cur_seq); 270 271 if (range->event == MMU_NOTIFY_UNMAP) { 272 down_write(&xdna->notifier_lock); 273 if (!mapp->unmapped) { 274 queue_work(xdna->notifier_wq, &mapp->hmm_unreg_work); 275 mapp->unmapped = true; 276 } 277 up_write(&xdna->notifier_lock); 278 } 279 280 return true; 281 } 282 283 static const struct mmu_interval_notifier_ops amdxdna_hmm_ops = { 284 .invalidate = amdxdna_hmm_invalidate, 285 }; 286 287 static void amdxdna_hmm_unregister(struct amdxdna_gem_obj *abo, 288 struct vm_area_struct *vma) 289 { 290 struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev); 291 struct amdxdna_umap *mapp; 292 293 down_read(&xdna->notifier_lock); 294 list_for_each_entry(mapp, &abo->mem.umap_list, node) { 295 if (!vma || mapp->vma == vma) { 296 if (!mapp->unmapped) { 297 queue_work(xdna->notifier_wq, &mapp->hmm_unreg_work); 298 mapp->unmapped = true; 299 } 300 if (vma) 301 break; 302 } 303 } 304 up_read(&xdna->notifier_lock); 305 } 306 307 static void amdxdna_umap_release(struct kref *ref) 308 { 309 struct amdxdna_umap *mapp = container_of(ref, struct amdxdna_umap, refcnt); 310 struct amdxdna_gem_obj *abo = mapp->abo; 311 struct vm_area_struct *vma = mapp->vma; 312 struct amdxdna_dev *xdna; 313 314 mmu_interval_notifier_remove(&mapp->notifier); 315 if (is_import_bo(abo) && vma->vm_file && vma->vm_file->f_mapping) 316 mapping_clear_unevictable(vma->vm_file->f_mapping); 317 318 xdna = to_xdna_dev(to_gobj(mapp->abo)->dev); 319 down_write(&xdna->notifier_lock); 320 list_del(&mapp->node); 321 if (list_empty(&abo->mem.umap_list)) 322 abo->mem.uva = AMDXDNA_INVALID_ADDR; 323 up_write(&xdna->notifier_lock); 324 325 kvfree(mapp->range.hmm_pfns); 326 kfree(mapp); 327 } 328 329 void amdxdna_umap_put(struct amdxdna_umap *mapp) 330 { 331 kref_put(&mapp->refcnt, amdxdna_umap_release); 332 } 333 334 static void amdxdna_hmm_unreg_work(struct work_struct *work) 335 { 336 struct amdxdna_umap *mapp = container_of(work, struct amdxdna_umap, 337 hmm_unreg_work); 338 339 amdxdna_umap_put(mapp); 340 } 341 342 static int amdxdna_hmm_register(struct amdxdna_gem_obj *abo, 343 struct vm_area_struct *vma) 344 { 345 struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev); 346 unsigned long len = vma->vm_end - vma->vm_start; 347 unsigned long addr = vma->vm_start; 348 struct amdxdna_umap *mapp; 349 u32 nr_pages; 350 int ret; 351 352 if (!amdxdna_pasid_on(abo->client)) { 353 /* Need to set uva for heap uva validation */ 354 abo->mem.uva = addr; 355 return 0; 356 } 357 358 mapp = kzalloc_obj(*mapp); 359 if (!mapp) 360 return -ENOMEM; 361 362 nr_pages = (PAGE_ALIGN(addr + len) - (addr & PAGE_MASK)) >> PAGE_SHIFT; 363 mapp->range.hmm_pfns = kvzalloc_objs(*mapp->range.hmm_pfns, nr_pages); 364 if (!mapp->range.hmm_pfns) { 365 ret = -ENOMEM; 366 goto free_map; 367 } 368 369 ret = mmu_interval_notifier_insert_locked(&mapp->notifier, 370 current->mm, 371 addr, 372 len, 373 &amdxdna_hmm_ops); 374 if (ret) { 375 XDNA_ERR(xdna, "Insert mmu notifier failed, ret %d", ret); 376 goto free_pfns; 377 } 378 379 mapp->range.notifier = &mapp->notifier; 380 mapp->range.start = vma->vm_start; 381 mapp->range.end = vma->vm_end; 382 mapp->range.default_flags = HMM_PFN_REQ_FAULT; 383 mapp->vma = vma; 384 mapp->abo = abo; 385 kref_init(&mapp->refcnt); 386 387 INIT_WORK(&mapp->hmm_unreg_work, amdxdna_hmm_unreg_work); 388 if (is_import_bo(abo) && vma->vm_file && vma->vm_file->f_mapping) 389 mapping_set_unevictable(vma->vm_file->f_mapping); 390 391 down_write(&xdna->notifier_lock); 392 if (list_empty(&abo->mem.umap_list)) 393 abo->mem.uva = addr; 394 list_add_tail(&mapp->node, &abo->mem.umap_list); 395 up_write(&xdna->notifier_lock); 396 397 return 0; 398 399 free_pfns: 400 kvfree(mapp->range.hmm_pfns); 401 free_map: 402 kfree(mapp); 403 return ret; 404 } 405 406 static void amdxdna_gem_dev_obj_free(struct drm_gem_object *gobj) 407 { 408 struct amdxdna_dev *xdna = to_xdna_dev(gobj->dev); 409 struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); 410 411 XDNA_DBG(xdna, "BO type %d xdna_addr 0x%llx", abo->type, amdxdna_gem_dev_addr(abo)); 412 if (abo->pinned) 413 amdxdna_gem_unpin(abo); 414 415 amdxdna_gem_vunmap(abo); 416 amdxdna_gem_heap_free(abo); 417 drm_gem_object_release(gobj); 418 amdxdna_gem_destroy_obj(abo); 419 } 420 421 static int amdxdna_insert_pages(struct amdxdna_gem_obj *abo, 422 struct vm_area_struct *vma) 423 { 424 struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev); 425 unsigned long num_pages = vma_pages(vma); 426 unsigned long offset = 0; 427 int ret; 428 429 if (!is_import_bo(abo)) { 430 ret = drm_gem_shmem_mmap(&abo->base, vma); 431 if (ret) { 432 XDNA_ERR(xdna, "Failed shmem mmap %d", ret); 433 return ret; 434 } 435 436 /* The buffer is based on memory pages. Fix the flag. */ 437 vm_flags_mod(vma, VM_MIXEDMAP, VM_PFNMAP); 438 ret = vm_insert_pages(vma, vma->vm_start, abo->base.pages, 439 &num_pages); 440 if (ret) { 441 XDNA_ERR(xdna, "Failed insert pages %d", ret); 442 vma->vm_ops->close(vma); 443 return ret; 444 } 445 446 return 0; 447 } 448 449 vma->vm_private_data = NULL; 450 vma->vm_ops = NULL; 451 ret = dma_buf_mmap(abo->dma_buf, vma, 0); 452 if (ret) { 453 XDNA_ERR(xdna, "Failed to mmap dma buf %d", ret); 454 return ret; 455 } 456 457 do { 458 vm_fault_t fault_ret; 459 460 fault_ret = handle_mm_fault(vma, vma->vm_start + offset, 461 FAULT_FLAG_WRITE, NULL); 462 if (fault_ret & VM_FAULT_ERROR) { 463 vma->vm_ops->close(vma); 464 XDNA_ERR(xdna, "Fault in page failed"); 465 return -EFAULT; 466 } 467 468 offset += PAGE_SIZE; 469 } while (--num_pages); 470 471 /* Drop the reference drm_gem_mmap_obj() acquired.*/ 472 drm_gem_object_put(to_gobj(abo)); 473 474 return 0; 475 } 476 477 static int amdxdna_gem_obj_mmap(struct drm_gem_object *gobj, 478 struct vm_area_struct *vma) 479 { 480 struct amdxdna_dev *xdna = to_xdna_dev(gobj->dev); 481 struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); 482 int ret; 483 484 ret = amdxdna_hmm_register(abo, vma); 485 if (ret) 486 return ret; 487 488 ret = amdxdna_insert_pages(abo, vma); 489 if (ret) { 490 XDNA_ERR(xdna, "Failed insert pages, ret %d", ret); 491 goto hmm_unreg; 492 } 493 494 XDNA_DBG(xdna, "BO map_offset 0x%llx type %d userptr 0x%lx size 0x%lx", 495 drm_vma_node_offset_addr(&gobj->vma_node), abo->type, 496 vma->vm_start, gobj->size); 497 return 0; 498 499 hmm_unreg: 500 amdxdna_hmm_unregister(abo, vma); 501 return ret; 502 } 503 504 static int amdxdna_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma) 505 { 506 struct drm_gem_object *gobj = dma_buf->priv; 507 struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); 508 unsigned long num_pages = vma_pages(vma); 509 int ret; 510 511 vma->vm_ops = &drm_gem_shmem_vm_ops; 512 vma->vm_private_data = gobj; 513 514 drm_gem_object_get(gobj); 515 ret = drm_gem_shmem_mmap(&abo->base, vma); 516 if (ret) 517 goto put_obj; 518 519 /* The buffer is based on memory pages. Fix the flag. */ 520 vm_flags_mod(vma, VM_MIXEDMAP, VM_PFNMAP); 521 ret = vm_insert_pages(vma, vma->vm_start, abo->base.pages, 522 &num_pages); 523 if (ret) 524 goto close_vma; 525 526 return 0; 527 528 close_vma: 529 vma->vm_ops->close(vma); 530 put_obj: 531 drm_gem_object_put(gobj); 532 return ret; 533 } 534 535 static const struct dma_buf_ops amdxdna_dmabuf_ops = { 536 .attach = drm_gem_map_attach, 537 .detach = drm_gem_map_detach, 538 .map_dma_buf = drm_gem_map_dma_buf, 539 .unmap_dma_buf = drm_gem_unmap_dma_buf, 540 .release = drm_gem_dmabuf_release, 541 .mmap = amdxdna_gem_dmabuf_mmap, 542 .vmap = drm_gem_dmabuf_vmap, 543 .vunmap = drm_gem_dmabuf_vunmap, 544 }; 545 546 static struct dma_buf *amdxdna_gem_prime_export(struct drm_gem_object *gobj, int flags) 547 { 548 struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); 549 DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 550 551 if (abo->private_buffer) 552 return ERR_PTR(-EOPNOTSUPP); 553 554 if (abo->dma_buf) { 555 get_dma_buf(abo->dma_buf); 556 return abo->dma_buf; 557 } 558 559 exp_info.ops = &amdxdna_dmabuf_ops; 560 exp_info.size = gobj->size; 561 exp_info.flags = flags; 562 exp_info.priv = gobj; 563 exp_info.resv = gobj->resv; 564 565 return drm_gem_dmabuf_export(gobj->dev, &exp_info); 566 } 567 568 static void amdxdna_imported_obj_free(struct amdxdna_gem_obj *abo) 569 { 570 dma_buf_unmap_attachment_unlocked(abo->attach, abo->base.sgt, DMA_BIDIRECTIONAL); 571 dma_buf_detach(abo->dma_buf, abo->attach); 572 dma_buf_put(abo->dma_buf); 573 drm_gem_object_release(to_gobj(abo)); 574 kfree(abo); 575 } 576 577 static inline bool 578 amdxdna_gem_skip_bo_usage(struct amdxdna_gem_obj *abo) 579 { 580 /* Already counted as part of HEAP BO */ 581 if (abo->type == AMDXDNA_BO_DEV) 582 return true; 583 584 return false; 585 } 586 587 static void 588 amdxdna_gem_add_bo_usage(struct amdxdna_gem_obj *abo) 589 { 590 struct amdxdna_client *client = abo->client; 591 592 if (amdxdna_gem_skip_bo_usage(abo)) 593 return; 594 595 guard(mutex)(&client->mm_lock); 596 597 client->total_bo_usage += abo->mem.size; 598 if (abo->internal) 599 client->total_int_bo_usage += abo->mem.size; 600 } 601 602 static void 603 amdxdna_gem_del_bo_usage(struct amdxdna_gem_obj *abo) 604 { 605 struct amdxdna_client *client = abo->client; 606 607 if (amdxdna_gem_skip_bo_usage(abo)) 608 return; 609 610 guard(mutex)(&client->mm_lock); 611 612 client->total_bo_usage -= abo->mem.size; 613 if (abo->internal) 614 client->total_int_bo_usage -= abo->mem.size; 615 } 616 617 static void amdxdna_gem_obj_free(struct drm_gem_object *gobj) 618 { 619 struct amdxdna_dev *xdna = to_xdna_dev(gobj->dev); 620 struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); 621 622 amdxdna_hmm_unregister(abo, NULL); 623 flush_workqueue(xdna->notifier_wq); 624 625 if (abo->pinned) 626 amdxdna_gem_unpin(abo); 627 628 amdxdna_dma_unmap_bo(xdna, abo); 629 amdxdna_gem_vunmap(abo); 630 mutex_destroy(&abo->lock); 631 632 if (is_import_bo(abo)) 633 amdxdna_imported_obj_free(abo); 634 else 635 drm_gem_shmem_free(&abo->base); 636 } 637 638 static int amdxdna_gem_obj_open(struct drm_gem_object *gobj, struct drm_file *filp) 639 { 640 struct amdxdna_dev *xdna = to_xdna_dev(gobj->dev); 641 struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); 642 int ret; 643 644 guard(mutex)(&abo->lock); 645 abo->open_ref++; 646 if (abo->open_ref > 1) 647 return 0; 648 649 /* Attached to the client when first opened by it. */ 650 abo->client = filp->driver_priv; 651 652 /* No need to set up dma addr mapping in PASID mode. */ 653 if (!amdxdna_pasid_on(abo->client)) { 654 ret = amdxdna_dma_map_bo(xdna, abo); 655 if (ret) 656 return ret; 657 } 658 659 amdxdna_gem_add_bo_usage(abo); 660 return 0; 661 } 662 663 static void amdxdna_gem_obj_close(struct drm_gem_object *gobj, struct drm_file *filp) 664 { 665 struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); 666 667 guard(mutex)(&abo->lock); 668 abo->open_ref--; 669 670 if (abo->open_ref == 0) { 671 amdxdna_gem_del_bo_usage(abo); 672 /* Detach from the client when last closed by it. */ 673 abo->client = NULL; 674 } 675 } 676 677 static int amdxdna_gem_obj_vmap(struct drm_gem_object *obj, struct iosys_map *map) 678 { 679 struct amdxdna_gem_obj *abo = to_xdna_obj(obj); 680 int ret; 681 682 iosys_map_clear(map); 683 684 dma_resv_assert_held(obj->resv); 685 686 if (is_import_bo(abo)) 687 ret = dma_buf_vmap(abo->dma_buf, map); 688 else 689 ret = drm_gem_shmem_object_vmap(obj, map); 690 if (ret) 691 return ret; 692 if (!map->vaddr) 693 return -ENOMEM; 694 695 return 0; 696 } 697 698 static void amdxdna_gem_obj_vunmap(struct drm_gem_object *obj, struct iosys_map *map) 699 { 700 struct amdxdna_gem_obj *abo = to_xdna_obj(obj); 701 702 dma_resv_assert_held(obj->resv); 703 704 if (is_import_bo(abo)) 705 dma_buf_vunmap(abo->dma_buf, map); 706 else 707 drm_gem_shmem_object_vunmap(obj, map); 708 } 709 710 static int amdxdna_gem_dev_obj_vmap(struct drm_gem_object *obj, struct iosys_map *map) 711 { 712 struct amdxdna_gem_obj *abo = to_xdna_obj(obj); 713 struct amdxdna_gem_obj *heap; 714 void *base; 715 u64 offset; 716 717 /* vmap dev bo which is across more than 1 heap is not allowed */ 718 if (abo->heap_start_id != abo->heap_end_id) 719 return -ENOMEM; 720 721 heap = xa_load(&abo->client->dev_heap_xa, abo->heap_start_id); 722 if (!heap) 723 return -ENOMEM; 724 725 base = amdxdna_gem_vmap(heap); 726 if (!base) 727 return -ENOMEM; 728 729 offset = amdxdna_gem_dev_addr(abo) - amdxdna_gem_dev_addr(heap); 730 iosys_map_set_vaddr(map, base + offset); 731 return 0; 732 } 733 734 static const struct drm_gem_object_funcs amdxdna_gem_dev_obj_funcs = { 735 .free = amdxdna_gem_dev_obj_free, 736 .vmap = amdxdna_gem_dev_obj_vmap, 737 }; 738 739 static const struct drm_gem_object_funcs amdxdna_gem_shmem_funcs = { 740 .free = amdxdna_gem_obj_free, 741 .open = amdxdna_gem_obj_open, 742 .close = amdxdna_gem_obj_close, 743 .print_info = drm_gem_shmem_object_print_info, 744 .pin = drm_gem_shmem_object_pin, 745 .unpin = drm_gem_shmem_object_unpin, 746 .get_sg_table = drm_gem_shmem_object_get_sg_table, 747 .vmap = amdxdna_gem_obj_vmap, 748 .vunmap = amdxdna_gem_obj_vunmap, 749 .mmap = amdxdna_gem_obj_mmap, 750 .vm_ops = &drm_gem_shmem_vm_ops, 751 .export = amdxdna_gem_prime_export, 752 }; 753 754 /* For drm_driver->gem_create_object callback */ 755 struct drm_gem_object * 756 amdxdna_gem_create_shmem_object_cb(struct drm_device *dev, size_t size) 757 { 758 struct amdxdna_gem_obj *abo; 759 760 abo = amdxdna_gem_create_obj(dev, size); 761 if (IS_ERR(abo)) 762 return ERR_CAST(abo); 763 764 to_gobj(abo)->funcs = &amdxdna_gem_shmem_funcs; 765 766 return to_gobj(abo); 767 } 768 769 static struct amdxdna_gem_obj * 770 amdxdna_gem_create_shmem_object(struct drm_device *dev, struct amdxdna_drm_create_bo *args) 771 { 772 size_t size = args->size; 773 struct drm_gem_shmem_object *shmem = drm_gem_shmem_create(dev, size); 774 775 if (IS_ERR(shmem)) 776 return ERR_CAST(shmem); 777 778 shmem->map_wc = false; 779 return to_xdna_obj(&shmem->base); 780 } 781 782 static struct amdxdna_gem_obj * 783 amdxdna_gem_create_ubuf_object(struct drm_device *dev, struct amdxdna_drm_create_bo *args) 784 { 785 struct amdxdna_dev *xdna = to_xdna_dev(dev); 786 struct amdxdna_drm_va_tbl va_tbl; 787 struct amdxdna_gem_obj *abo; 788 struct drm_gem_object *gobj; 789 struct dma_buf *dma_buf; 790 791 if (copy_from_user(&va_tbl, u64_to_user_ptr(args->vaddr), sizeof(va_tbl))) { 792 XDNA_DBG(xdna, "Access va table failed"); 793 return ERR_PTR(-EINVAL); 794 } 795 796 if (va_tbl.num_entries) { 797 dma_buf = amdxdna_get_ubuf(dev, va_tbl.num_entries, 798 u64_to_user_ptr(args->vaddr + sizeof(va_tbl))); 799 } else { 800 dma_buf = dma_buf_get(va_tbl.dmabuf_fd); 801 } 802 803 if (IS_ERR(dma_buf)) 804 return ERR_CAST(dma_buf); 805 806 gobj = amdxdna_gem_prime_import(dev, dma_buf); 807 if (IS_ERR(gobj)) { 808 dma_buf_put(dma_buf); 809 return ERR_CAST(gobj); 810 } 811 812 dma_buf_put(dma_buf); 813 814 abo = to_xdna_obj(gobj); 815 abo->private_buffer = true; 816 817 return abo; 818 } 819 820 static struct amdxdna_gem_obj * 821 amdxdna_gem_create_cbuf_object(struct drm_device *dev, struct amdxdna_drm_create_bo *args) 822 { 823 struct amdxdna_dev *xdna = to_xdna_dev(dev); 824 size_t size = PAGE_ALIGN(args->size); 825 struct drm_gem_object *gobj; 826 struct amdxdna_gem_obj *ret; 827 struct dma_buf *dma_buf; 828 u64 align; 829 830 if (!size) { 831 XDNA_ERR(xdna, "Invalid BO size 0x%llx", args->size); 832 return ERR_PTR(-EINVAL); 833 } 834 835 align = (args->type == AMDXDNA_BO_DEV_HEAP) ? xdna->dev_info->dev_mem_size : 0; 836 dma_buf = amdxdna_get_cbuf(dev, size, align); 837 if (IS_ERR(dma_buf)) 838 return ERR_CAST(dma_buf); 839 840 gobj = amdxdna_gem_prime_import(dev, dma_buf); 841 if (IS_ERR(gobj)) 842 ret = ERR_CAST(gobj); 843 else 844 ret = to_xdna_obj(gobj); 845 846 dma_buf_put(dma_buf); 847 return ret; 848 } 849 850 struct drm_gem_object * 851 amdxdna_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf) 852 { 853 struct dma_buf_attachment *attach; 854 struct amdxdna_gem_obj *abo; 855 struct drm_gem_object *gobj; 856 struct sg_table *sgt; 857 int ret; 858 859 get_dma_buf(dma_buf); 860 861 attach = dma_buf_attach(dma_buf, dev->dev); 862 if (IS_ERR(attach)) { 863 ret = PTR_ERR(attach); 864 goto put_buf; 865 } 866 867 sgt = dma_buf_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL); 868 if (IS_ERR(sgt)) { 869 ret = PTR_ERR(sgt); 870 goto fail_detach; 871 } 872 873 gobj = drm_gem_shmem_prime_import_sg_table(dev, attach, sgt); 874 if (IS_ERR(gobj)) { 875 ret = PTR_ERR(gobj); 876 goto fail_unmap; 877 } 878 879 abo = to_xdna_obj(gobj); 880 abo->attach = attach; 881 abo->dma_buf = dma_buf; 882 abo->type = AMDXDNA_BO_SHARE; 883 gobj->resv = dma_buf->resv; 884 885 return gobj; 886 887 fail_unmap: 888 dma_buf_unmap_attachment_unlocked(attach, sgt, DMA_BIDIRECTIONAL); 889 fail_detach: 890 dma_buf_detach(dma_buf, attach); 891 put_buf: 892 dma_buf_put(dma_buf); 893 894 return ERR_PTR(ret); 895 } 896 897 static struct amdxdna_gem_obj * 898 amdxdna_drm_create_share_bo(struct drm_device *dev, 899 struct amdxdna_drm_create_bo *args, struct drm_file *filp) 900 { 901 struct amdxdna_gem_obj *abo; 902 903 if (args->vaddr) 904 abo = amdxdna_gem_create_ubuf_object(dev, args); 905 else if (amdxdna_use_carveout(to_xdna_dev(dev))) 906 abo = amdxdna_gem_create_cbuf_object(dev, args); 907 else 908 abo = amdxdna_gem_create_shmem_object(dev, args); 909 if (IS_ERR(abo)) 910 return ERR_CAST(abo); 911 912 if (args->type == AMDXDNA_BO_DEV_HEAP) { 913 abo->type = AMDXDNA_BO_DEV_HEAP; 914 abo->internal = true; 915 } else { 916 abo->type = AMDXDNA_BO_SHARE; 917 abo->internal = args->type == AMDXDNA_BO_CMD; 918 } 919 920 return abo; 921 } 922 923 static struct amdxdna_gem_obj * 924 amdxdna_drm_create_dev_heap_bo(struct drm_device *dev, 925 struct amdxdna_drm_create_bo *args, struct drm_file *filp) 926 { 927 struct amdxdna_client *client = filp->driver_priv; 928 struct amdxdna_dev *xdna = to_xdna_dev(dev); 929 struct amdxdna_gem_obj *abo; 930 int ret; 931 932 WARN_ON(!is_power_of_2(xdna->dev_info->dev_mem_size)); 933 XDNA_DBG(xdna, "Requested dev heap size 0x%llx", args->size); 934 if (!args->size || !IS_ALIGNED(args->size, xdna->dev_info->dev_mem_size)) { 935 XDNA_ERR(xdna, "The dev heap size 0x%llx is not multiple of 0x%lx", 936 args->size, xdna->dev_info->dev_mem_size); 937 return ERR_PTR(-EINVAL); 938 } 939 940 /* HEAP BO is a special case of SHARE BO. */ 941 abo = amdxdna_drm_create_share_bo(dev, args, filp); 942 if (IS_ERR(abo)) 943 return ERR_CAST(abo); 944 945 /* Set up heap for this client. */ 946 mutex_lock(&client->mm_lock); 947 948 if (!xdna->dev_info->ops->hwctx_heap_expand && 949 client->dev_heap_nid > 0) { 950 XDNA_ERR(xdna, "Heap expansion is not supported"); 951 ret = -EOPNOTSUPP; 952 goto mm_unlock; 953 } 954 955 if (client->total_heap_size + abo->mem.size > 956 xdna->dev_info->dev_heap_max_size) { 957 XDNA_ERR(xdna, "Heap size 0x%lx + 0x%lx exceeds max 0x%lx", 958 client->total_heap_size, abo->mem.size, 959 xdna->dev_info->dev_heap_max_size); 960 ret = -ENOSPC; 961 goto mm_unlock; 962 } 963 964 ret = xa_insert(&client->dev_heap_xa, client->dev_heap_nid, abo, GFP_KERNEL); 965 if (ret) { 966 XDNA_ERR(xdna, "Add heap failed %d", ret); 967 goto mm_unlock; 968 } 969 970 abo->dev_addr = xdna->dev_info->dev_mem_base + client->total_heap_size; 971 client->total_heap_size += abo->mem.size; 972 client->dev_heap_nid++; 973 drm_gem_object_get(to_gobj(abo)); 974 975 mutex_unlock(&client->mm_lock); 976 977 return abo; 978 979 mm_unlock: 980 mutex_unlock(&client->mm_lock); 981 drm_gem_object_put(to_gobj(abo)); 982 return ERR_PTR(ret); 983 } 984 985 struct amdxdna_gem_obj * 986 amdxdna_drm_create_dev_bo(struct drm_device *dev, 987 struct amdxdna_drm_create_bo *args, struct drm_file *filp) 988 { 989 size_t aligned_sz = PAGE_ALIGN(args->size); 990 struct amdxdna_client *client = filp->driver_priv; 991 struct amdxdna_dev *xdna = to_xdna_dev(dev); 992 struct amdxdna_gem_obj *abo; 993 struct drm_gem_object *gobj; 994 int ret; 995 996 if (!aligned_sz) { 997 XDNA_ERR(xdna, "Invalid BO size 0x%llx", args->size); 998 return ERR_PTR(-EINVAL); 999 } 1000 1001 abo = amdxdna_gem_create_obj(dev, aligned_sz); 1002 if (IS_ERR(abo)) 1003 return abo; 1004 gobj = to_gobj(abo); 1005 gobj->funcs = &amdxdna_gem_dev_obj_funcs; 1006 abo->type = AMDXDNA_BO_DEV; 1007 abo->internal = true; 1008 /* 1009 * DEV BOs cannot be alive when client is gone, it's OK to 1010 * always establish the connection. 1011 */ 1012 abo->client = client; 1013 1014 ret = amdxdna_gem_heap_alloc(abo); 1015 if (ret) { 1016 amdxdna_gem_destroy_obj(abo); 1017 return ERR_PTR(ret); 1018 } 1019 1020 drm_gem_private_object_init(dev, gobj, aligned_sz); 1021 1022 return abo; 1023 } 1024 1025 int amdxdna_drm_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) 1026 { 1027 struct amdxdna_client *client = filp->driver_priv; 1028 struct amdxdna_dev *xdna = to_xdna_dev(dev); 1029 struct amdxdna_drm_create_bo *args = data; 1030 struct amdxdna_gem_obj *abo; 1031 int ret; 1032 1033 if (args->flags) 1034 return -EINVAL; 1035 1036 XDNA_DBG(xdna, "BO arg type %d vaddr 0x%llx size 0x%llx flags 0x%llx", 1037 args->type, args->vaddr, args->size, args->flags); 1038 switch (args->type) { 1039 case AMDXDNA_BO_CMD: 1040 case AMDXDNA_BO_SHARE: 1041 abo = amdxdna_drm_create_share_bo(dev, args, filp); 1042 break; 1043 case AMDXDNA_BO_DEV_HEAP: 1044 abo = amdxdna_drm_create_dev_heap_bo(dev, args, filp); 1045 break; 1046 case AMDXDNA_BO_DEV: 1047 abo = amdxdna_drm_create_dev_bo(dev, args, filp); 1048 if (!IS_ERR(abo)) { 1049 mutex_lock(&xdna->dev_lock); 1050 ret = amdxdna_update_heap(client, NULL); 1051 mutex_unlock(&xdna->dev_lock); 1052 if (ret) 1053 goto put_obj; 1054 } 1055 break; 1056 default: 1057 return -EINVAL; 1058 } 1059 if (IS_ERR(abo)) 1060 return PTR_ERR(abo); 1061 1062 /* Ready to publish object to userspace and count for BO usage. */ 1063 ret = drm_gem_handle_create(filp, to_gobj(abo), &args->handle); 1064 if (ret) { 1065 XDNA_ERR(xdna, "Create handle failed"); 1066 goto put_obj; 1067 } 1068 1069 XDNA_DBG(xdna, "BO hdl %d type %d userptr 0x%llx xdna_addr 0x%llx size 0x%lx", 1070 args->handle, args->type, amdxdna_gem_uva(abo), 1071 amdxdna_gem_dev_addr(abo), abo->mem.size); 1072 put_obj: 1073 /* Dereference object reference. Handle holds it now. */ 1074 drm_gem_object_put(to_gobj(abo)); 1075 return ret; 1076 } 1077 1078 static int amdxdna_bo_pin(struct amdxdna_gem_obj *abo) 1079 { 1080 struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev); 1081 int ret; 1082 1083 if (is_import_bo(abo)) 1084 return 0; 1085 1086 ret = drm_gem_shmem_pin(&abo->base); 1087 1088 XDNA_DBG(xdna, "BO type %d ret %d", abo->type, ret); 1089 return ret; 1090 } 1091 1092 static void amdxdna_bo_unpin(struct amdxdna_gem_obj *abo) 1093 { 1094 struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev); 1095 1096 if (is_import_bo(abo)) 1097 return; 1098 1099 drm_gem_shmem_unpin(&abo->base); 1100 1101 XDNA_DBG(xdna, "BO type %d", abo->type); 1102 } 1103 1104 int amdxdna_gem_pin_nolock(struct amdxdna_gem_obj *abo) 1105 { 1106 struct amdxdna_client *client = abo->client; 1107 struct amdxdna_gem_obj *heap; 1108 unsigned long heap_id, last = ULONG_MAX; 1109 int ret = 0; 1110 1111 if (abo->type != AMDXDNA_BO_DEV) 1112 return amdxdna_bo_pin(abo); 1113 1114 xa_for_each_range(&client->dev_heap_xa, heap_id, heap, 1115 abo->heap_start_id, abo->heap_end_id) { 1116 ret = amdxdna_bo_pin(heap); 1117 if (ret) 1118 break; 1119 last = heap_id; 1120 } 1121 1122 if (ret && last <= abo->heap_end_id) { 1123 xa_for_each_range(&client->dev_heap_xa, heap_id, heap, 1124 abo->heap_start_id, last) 1125 amdxdna_bo_unpin(heap); 1126 } 1127 1128 return ret; 1129 } 1130 1131 int amdxdna_gem_pin(struct amdxdna_gem_obj *abo) 1132 { 1133 int ret; 1134 1135 mutex_lock(&abo->lock); 1136 ret = amdxdna_gem_pin_nolock(abo); 1137 mutex_unlock(&abo->lock); 1138 1139 return ret; 1140 } 1141 1142 void amdxdna_gem_unpin(struct amdxdna_gem_obj *abo) 1143 { 1144 mutex_lock(&abo->lock); 1145 if (abo->type == AMDXDNA_BO_DEV) { 1146 struct amdxdna_gem_obj *heap; 1147 unsigned long heap_id; 1148 1149 xa_for_each_range(&abo->client->dev_heap_xa, heap_id, heap, 1150 abo->heap_start_id, abo->heap_end_id) 1151 amdxdna_bo_unpin(heap); 1152 } else { 1153 amdxdna_bo_unpin(abo); 1154 } 1155 1156 mutex_unlock(&abo->lock); 1157 } 1158 1159 struct amdxdna_gem_obj *amdxdna_gem_get_obj(struct amdxdna_client *client, 1160 u32 bo_hdl, u8 bo_type) 1161 { 1162 struct amdxdna_gem_obj *abo; 1163 struct drm_gem_object *gobj; 1164 1165 gobj = drm_gem_object_lookup(client->filp, bo_hdl); 1166 if (!gobj) { 1167 XDNA_DBG(client->xdna, "Can not find bo %d", bo_hdl); 1168 return NULL; 1169 } 1170 1171 abo = to_xdna_obj(gobj); 1172 if (bo_type == AMDXDNA_BO_INVALID || abo->type == bo_type) 1173 return abo; 1174 1175 drm_gem_object_put(gobj); 1176 return NULL; 1177 } 1178 1179 int amdxdna_drm_get_bo_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) 1180 { 1181 struct amdxdna_drm_get_bo_info *args = data; 1182 struct amdxdna_dev *xdna = to_xdna_dev(dev); 1183 struct amdxdna_gem_obj *abo; 1184 struct drm_gem_object *gobj; 1185 int ret = 0; 1186 1187 if (args->ext || args->ext_flags || args->pad) 1188 return -EINVAL; 1189 1190 gobj = drm_gem_object_lookup(filp, args->handle); 1191 if (!gobj) { 1192 XDNA_DBG(xdna, "Lookup GEM object %d failed", args->handle); 1193 return -ENOENT; 1194 } 1195 1196 abo = to_xdna_obj(gobj); 1197 args->vaddr = amdxdna_gem_uva(abo); 1198 args->xdna_addr = amdxdna_gem_dev_addr(abo); 1199 1200 if (abo->type != AMDXDNA_BO_DEV) 1201 args->map_offset = drm_vma_node_offset_addr(&gobj->vma_node); 1202 else 1203 args->map_offset = AMDXDNA_INVALID_ADDR; 1204 1205 XDNA_DBG(xdna, "BO hdl %d map_offset 0x%llx vaddr 0x%llx xdna_addr 0x%llx", 1206 args->handle, args->map_offset, args->vaddr, args->xdna_addr); 1207 1208 drm_gem_object_put(gobj); 1209 return ret; 1210 } 1211 1212 static int amdxdna_flush_bo(struct amdxdna_gem_obj *abo, u64 offset, u64 size) 1213 { 1214 u64 end; 1215 1216 if (offset >= abo->mem.size) 1217 return -EINVAL; 1218 1219 if (check_add_overflow(offset, size, &end)) 1220 return -EINVAL; 1221 1222 size = min(abo->mem.size, end) - offset; 1223 if (is_import_bo(abo)) 1224 drm_clflush_sg(abo->base.sgt); 1225 else if (amdxdna_gem_vmap(abo)) 1226 drm_clflush_virt_range(amdxdna_gem_vmap(abo) + offset, size); 1227 else if (abo->base.pages) 1228 drm_clflush_pages(abo->base.pages, abo->mem.size >> PAGE_SHIFT); 1229 else 1230 return -EINVAL; 1231 1232 return 0; 1233 } 1234 1235 /* 1236 * The sync bo ioctl is to make sure the CPU cache is in sync with memory. 1237 * This is required because NPU is not cache coherent device. CPU cache 1238 * flushing/invalidation is expensive so it is best to handle this outside 1239 * of the command submission path. This ioctl allows explicit cache 1240 * flushing/invalidation outside of the critical path. 1241 */ 1242 int amdxdna_drm_sync_bo_ioctl(struct drm_device *dev, 1243 void *data, struct drm_file *filp) 1244 { 1245 struct amdxdna_client *client = filp->driver_priv; 1246 struct amdxdna_dev *xdna = to_xdna_dev(dev); 1247 struct amdxdna_drm_sync_bo *args = data; 1248 struct amdxdna_gem_obj *abo; 1249 struct drm_gem_object *gobj; 1250 int ret = 0; 1251 1252 gobj = drm_gem_object_lookup(filp, args->handle); 1253 if (!gobj) { 1254 XDNA_ERR(xdna, "Lookup GEM object failed"); 1255 return -ENOENT; 1256 } 1257 abo = to_xdna_obj(gobj); 1258 1259 if (abo->type == AMDXDNA_BO_DEV) { 1260 struct amdxdna_gem_obj *heap; 1261 unsigned long heap_id; 1262 u64 bo_start = amdxdna_gem_dev_addr(abo); 1263 u64 flush_start = bo_start + args->offset; 1264 u64 flush_end = flush_start + args->size; 1265 1266 xa_for_each_range(&client->dev_heap_xa, heap_id, heap, 1267 abo->heap_start_id, abo->heap_end_id) { 1268 u64 heap_start = amdxdna_gem_dev_addr(heap); 1269 u64 heap_end = heap_start + heap->mem.size; 1270 u64 start = max(flush_start, heap_start); 1271 u64 end = min(flush_end, heap_end); 1272 1273 if (start >= end) 1274 continue; 1275 1276 ret = amdxdna_flush_bo(heap, start - heap_start, end - start); 1277 if (ret) { 1278 XDNA_ERR(xdna, "Failed to flush heap %ld ret %d", 1279 heap_id, ret); 1280 goto put_obj; 1281 } 1282 } 1283 } else { 1284 ret = amdxdna_gem_pin(abo); 1285 if (ret) { 1286 XDNA_ERR(xdna, "Pin BO %d failed, ret %d", args->handle, ret); 1287 goto put_obj; 1288 } 1289 1290 ret = amdxdna_flush_bo(abo, args->offset, args->size); 1291 amdxdna_gem_unpin(abo); 1292 1293 if (ret) { 1294 drm_WARN(&xdna->ddev, 1, "Can not get flush memory"); 1295 goto put_obj; 1296 } 1297 } 1298 1299 XDNA_DBG(xdna, "Sync bo %d offset 0x%llx, size 0x%llx\n", 1300 args->handle, args->offset, args->size); 1301 1302 if (args->direction == SYNC_DIRECT_FROM_DEVICE) 1303 ret = amdxdna_hwctx_sync_debug_bo(abo->client, args->handle); 1304 1305 put_obj: 1306 drm_gem_object_put(gobj); 1307 return ret; 1308 } 1309 1310 int amdxdna_drm_get_bo_usage(struct drm_device *dev, struct amdxdna_drm_get_array *args) 1311 { 1312 size_t min_sz = min(args->element_size, sizeof(struct amdxdna_drm_bo_usage)); 1313 char __user *buf = u64_to_user_ptr(args->buffer); 1314 struct amdxdna_dev *xdna = to_xdna_dev(dev); 1315 struct amdxdna_client *tmp_client; 1316 struct amdxdna_drm_bo_usage tmp; 1317 1318 drm_WARN_ON(dev, !mutex_is_locked(&xdna->dev_lock)); 1319 1320 if (args->num_element != 1) 1321 return -EINVAL; 1322 1323 if (copy_from_user(&tmp, buf, min_sz)) 1324 return -EFAULT; 1325 1326 if (!tmp.pid) 1327 return -EINVAL; 1328 1329 tmp.total_usage = 0; 1330 tmp.internal_usage = 0; 1331 tmp.heap_usage = 0; 1332 1333 list_for_each_entry(tmp_client, &xdna->client_list, node) { 1334 if (tmp.pid != tmp_client->pid) 1335 continue; 1336 1337 mutex_lock(&tmp_client->mm_lock); 1338 tmp.total_usage += tmp_client->total_bo_usage; 1339 tmp.internal_usage += tmp_client->total_int_bo_usage; 1340 tmp.heap_usage += tmp_client->heap_usage; 1341 mutex_unlock(&tmp_client->mm_lock); 1342 } 1343 1344 if (copy_to_user(buf, &tmp, min_sz)) 1345 return -EFAULT; 1346 1347 return 0; 1348 } 1349