1 // SPDX-License-Identifier: GPL-2.0 or MIT 2 /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */ 3 /* Copyright 2023 Collabora ltd. */ 4 /* Copyright 2025 Amazon.com, Inc. or its affiliates */ 5 /* Copyright 2025 ARM Limited. All rights reserved. */ 6 7 #include <linux/cleanup.h> 8 #include <linux/debugfs.h> 9 #include <linux/dma-buf.h> 10 #include <linux/dma-mapping.h> 11 #include <linux/err.h> 12 #include <linux/slab.h> 13 #include <linux/vmalloc.h> 14 15 #include <drm/drm_debugfs.h> 16 #include <drm/drm_file.h> 17 #include <drm/drm_gpuvm.h> 18 #include <drm/drm_managed.h> 19 #include <drm/drm_prime.h> 20 #include <drm/drm_print.h> 21 #include <drm/panthor_drm.h> 22 23 #include "panthor_device.h" 24 #include "panthor_drv.h" 25 #include "panthor_fw.h" 26 #include "panthor_gem.h" 27 #include "panthor_mmu.h" 28 29 void panthor_gem_init(struct panthor_device *ptdev) 30 { 31 int err; 32 33 if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && 34 !panthor_transparent_hugepage) 35 return; 36 37 err = drm_gem_huge_mnt_create(&ptdev->base, "within_size"); 38 if (drm_gem_get_huge_mnt(&ptdev->base)) 39 drm_info(&ptdev->base, "Using Transparent Hugepage\n"); 40 else if (err) 41 drm_warn(&ptdev->base, "Can't use Transparent Hugepage (%d)\n", 42 err); 43 } 44 45 #ifdef CONFIG_DEBUG_FS 46 static void panthor_gem_debugfs_bo_init(struct panthor_gem_object *bo) 47 { 48 INIT_LIST_HEAD(&bo->debugfs.node); 49 } 50 51 static void panthor_gem_debugfs_bo_add(struct panthor_gem_object *bo) 52 { 53 struct panthor_device *ptdev = container_of(bo->base.dev, 54 struct panthor_device, base); 55 56 bo->debugfs.creator.tgid = current->tgid; 57 get_task_comm(bo->debugfs.creator.process_name, current->group_leader); 58 59 mutex_lock(&ptdev->gems.lock); 60 list_add_tail(&bo->debugfs.node, &ptdev->gems.node); 61 mutex_unlock(&ptdev->gems.lock); 62 } 63 64 static void panthor_gem_debugfs_bo_rm(struct panthor_gem_object *bo) 65 { 66 struct panthor_device *ptdev = container_of(bo->base.dev, 67 struct panthor_device, base); 68 69 if (list_empty(&bo->debugfs.node)) 70 return; 71 72 mutex_lock(&ptdev->gems.lock); 73 list_del_init(&bo->debugfs.node); 74 mutex_unlock(&ptdev->gems.lock); 75 } 76 77 static void panthor_gem_debugfs_set_usage_flags(struct panthor_gem_object *bo, u32 usage_flags) 78 { 79 bo->debugfs.flags = usage_flags; 80 panthor_gem_debugfs_bo_add(bo); 81 } 82 #else 83 static void panthor_gem_debugfs_bo_rm(struct panthor_gem_object *bo) {} 84 static void panthor_gem_debugfs_set_usage_flags(struct panthor_gem_object *bo, u32 usage_flags) {} 85 static void panthor_gem_debugfs_bo_init(struct panthor_gem_object *bo) {} 86 #endif 87 88 static bool 89 should_map_wc(struct panthor_gem_object *bo) 90 { 91 struct panthor_device *ptdev = container_of(bo->base.dev, struct panthor_device, base); 92 93 /* We can't do uncached mappings if the device is coherent, 94 * because the zeroing done by the shmem layer at page allocation 95 * time happens on a cached mapping which isn't CPU-flushed (at least 96 * not on Arm64 where the flush is deferred to PTE setup time, and 97 * only done conditionally based on the mapping permissions). We can't 98 * rely on dma_map_sgtable()/dma_sync_sgtable_for_xxx() either to flush 99 * those, because they are NOPed if dma_dev_coherent() returns true. 100 * 101 * FIXME: Note that this problem is going to pop up again when we 102 * decide to support mapping buffers with the NO_MMAP flag as 103 * non-shareable (AKA buffers accessed only by the GPU), because we 104 * need the same CPU flush to happen after page allocation, otherwise 105 * there's a risk of data leak or late corruption caused by a dirty 106 * cacheline being evicted. At this point we'll need a way to force 107 * CPU cache maintenance regardless of whether the device is coherent 108 * or not. 109 */ 110 if (ptdev->coherent) 111 return false; 112 113 /* Cached mappings are explicitly requested, so no write-combine. */ 114 if (bo->flags & DRM_PANTHOR_BO_WB_MMAP) 115 return false; 116 117 /* The default is write-combine. */ 118 return true; 119 } 120 121 static bool is_gpu_mapped(struct panthor_gem_object *bo, 122 enum panthor_gem_reclaim_state *state) 123 { 124 struct drm_gpuvm_bo *vm_bo; 125 u32 vm_count = 0; 126 127 drm_gem_for_each_gpuvm_bo(vm_bo, &bo->base) { 128 /* Skip evicted GPU mappings. */ 129 if (vm_bo->evicted) 130 continue; 131 132 if (vm_count++) { 133 *state = PANTHOR_GEM_GPU_MAPPED_MULTI_VM; 134 break; 135 } 136 137 *state = PANTHOR_GEM_GPU_MAPPED_SINGLE_VM; 138 } 139 140 return vm_count > 0; 141 } 142 143 static enum panthor_gem_reclaim_state 144 panthor_gem_evaluate_reclaim_state_locked(struct panthor_gem_object *bo) 145 { 146 enum panthor_gem_reclaim_state gpu_mapped_state; 147 148 dma_resv_assert_held(bo->base.resv); 149 lockdep_assert_held(&bo->base.gpuva.lock); 150 151 /* If pages have not been allocated, there's nothing to reclaim. */ 152 if (!bo->backing.pages) 153 return PANTHOR_GEM_UNRECLAIMABLE; 154 155 /* If memory is pinned, we prevent reclaim. */ 156 if (refcount_read(&bo->backing.pin_count)) 157 return PANTHOR_GEM_UNRECLAIMABLE; 158 159 if (is_gpu_mapped(bo, &gpu_mapped_state)) 160 return gpu_mapped_state; 161 162 if (refcount_read(&bo->cmap.mmap_count)) 163 return PANTHOR_GEM_MMAPPED; 164 165 return PANTHOR_GEM_UNUSED; 166 } 167 168 void panthor_gem_update_reclaim_state_locked(struct panthor_gem_object *bo, 169 enum panthor_gem_reclaim_state *old_statep) 170 { 171 struct panthor_device *ptdev = container_of(bo->base.dev, struct panthor_device, base); 172 enum panthor_gem_reclaim_state old_state = bo->reclaim_state; 173 enum panthor_gem_reclaim_state new_state; 174 bool was_gpu_mapped, is_gpu_mapped; 175 176 if (old_statep) 177 *old_statep = old_state; 178 179 new_state = panthor_gem_evaluate_reclaim_state_locked(bo); 180 if (new_state == old_state) 181 return; 182 183 was_gpu_mapped = old_state == PANTHOR_GEM_GPU_MAPPED_MULTI_VM || 184 old_state == PANTHOR_GEM_GPU_MAPPED_SINGLE_VM; 185 is_gpu_mapped = new_state == PANTHOR_GEM_GPU_MAPPED_MULTI_VM || 186 new_state == PANTHOR_GEM_GPU_MAPPED_SINGLE_VM; 187 188 if (is_gpu_mapped && !was_gpu_mapped) 189 ptdev->reclaim.gpu_mapped_count += bo->base.size >> PAGE_SHIFT; 190 else if (!is_gpu_mapped && was_gpu_mapped) 191 ptdev->reclaim.gpu_mapped_count -= bo->base.size >> PAGE_SHIFT; 192 193 switch (new_state) { 194 case PANTHOR_GEM_UNUSED: 195 drm_gem_lru_move_tail(&ptdev->reclaim.unused, &bo->base); 196 break; 197 case PANTHOR_GEM_MMAPPED: 198 drm_gem_lru_move_tail(&ptdev->reclaim.mmapped, &bo->base); 199 break; 200 case PANTHOR_GEM_GPU_MAPPED_SINGLE_VM: 201 panthor_vm_update_bo_reclaim_lru_locked(bo); 202 break; 203 case PANTHOR_GEM_GPU_MAPPED_MULTI_VM: 204 drm_gem_lru_move_tail(&ptdev->reclaim.gpu_mapped_shared, &bo->base); 205 break; 206 case PANTHOR_GEM_UNRECLAIMABLE: 207 drm_gem_lru_remove(&bo->base); 208 break; 209 default: 210 drm_WARN(&ptdev->base, true, "invalid GEM reclaim state (%d)\n", new_state); 211 break; 212 } 213 214 bo->reclaim_state = new_state; 215 } 216 217 static void 218 bo_assert_locked_or_gone(struct panthor_gem_object *bo) 219 { 220 /* If the refcount is zero, the BO is being freed, and we 221 * allow the lock to not be held in that particular case. 222 */ 223 if (kref_read(&bo->base.refcount)) 224 dma_resv_assert_held(bo->base.resv); 225 } 226 227 static void 228 panthor_gem_backing_cleanup_locked(struct panthor_gem_object *bo) 229 { 230 bo_assert_locked_or_gone(bo); 231 232 if (!bo->backing.pages) 233 return; 234 235 drm_gem_put_pages(&bo->base, bo->backing.pages, true, false); 236 bo->backing.pages = NULL; 237 } 238 239 static int 240 panthor_gem_backing_get_pages_locked(struct panthor_gem_object *bo) 241 { 242 struct page **pages; 243 244 dma_resv_assert_held(bo->base.resv); 245 246 if (bo->backing.pages) 247 return 0; 248 249 pages = drm_gem_get_pages(&bo->base); 250 if (IS_ERR(pages)) { 251 drm_dbg_driver(bo->base.dev, "Failed to get pages (%pe)\n", pages); 252 return PTR_ERR(pages); 253 } 254 255 bo->backing.pages = pages; 256 return 0; 257 } 258 259 static int panthor_gem_backing_pin_locked(struct panthor_gem_object *bo) 260 { 261 int ret; 262 263 dma_resv_assert_held(bo->base.resv); 264 drm_WARN_ON_ONCE(bo->base.dev, drm_gem_is_imported(&bo->base)); 265 266 if (refcount_inc_not_zero(&bo->backing.pin_count)) 267 return 0; 268 269 ret = panthor_gem_backing_get_pages_locked(bo); 270 if (!ret) { 271 refcount_set(&bo->backing.pin_count, 1); 272 mutex_lock(&bo->base.gpuva.lock); 273 panthor_gem_update_reclaim_state_locked(bo, NULL); 274 mutex_unlock(&bo->base.gpuva.lock); 275 } 276 277 return ret; 278 } 279 280 static void panthor_gem_backing_unpin_locked(struct panthor_gem_object *bo) 281 { 282 bo_assert_locked_or_gone(bo); 283 drm_WARN_ON_ONCE(bo->base.dev, drm_gem_is_imported(&bo->base)); 284 285 if (refcount_dec_and_test(&bo->backing.pin_count)) { 286 /* We don't release anything when pin_count drops to zero. 287 * Pages stay there until an explicit cleanup is requested. 288 */ 289 mutex_lock(&bo->base.gpuva.lock); 290 panthor_gem_update_reclaim_state_locked(bo, NULL); 291 mutex_unlock(&bo->base.gpuva.lock); 292 } 293 } 294 295 static void 296 panthor_gem_dev_map_cleanup_locked(struct panthor_gem_object *bo) 297 { 298 bo_assert_locked_or_gone(bo); 299 300 if (!bo->dmap.sgt) 301 return; 302 303 dma_unmap_sgtable(drm_dev_dma_dev(bo->base.dev), bo->dmap.sgt, DMA_BIDIRECTIONAL, 0); 304 sg_free_table(bo->dmap.sgt); 305 kfree(bo->dmap.sgt); 306 bo->dmap.sgt = NULL; 307 } 308 309 static struct sg_table * 310 panthor_gem_dev_map_get_sgt_locked(struct panthor_gem_object *bo) 311 { 312 struct sg_table *sgt; 313 int ret; 314 315 dma_resv_assert_held(bo->base.resv); 316 317 if (bo->dmap.sgt) 318 return bo->dmap.sgt; 319 320 ret = panthor_gem_backing_get_pages_locked(bo); 321 if (ret) 322 return ERR_PTR(ret); 323 324 sgt = drm_prime_pages_to_sg(bo->base.dev, bo->backing.pages, 325 bo->base.size >> PAGE_SHIFT); 326 if (IS_ERR(sgt)) 327 return sgt; 328 329 /* Map the pages for use by the h/w. */ 330 ret = dma_map_sgtable(drm_dev_dma_dev(bo->base.dev), sgt, DMA_BIDIRECTIONAL, 0); 331 if (ret) 332 goto err_free_sgt; 333 334 bo->dmap.sgt = sgt; 335 return sgt; 336 337 err_free_sgt: 338 sg_free_table(sgt); 339 kfree(sgt); 340 return ERR_PTR(ret); 341 } 342 343 struct sg_table * 344 panthor_gem_get_dev_sgt(struct panthor_gem_object *bo) 345 { 346 struct sg_table *sgt; 347 348 dma_resv_lock(bo->base.resv, NULL); 349 sgt = panthor_gem_dev_map_get_sgt_locked(bo); 350 dma_resv_unlock(bo->base.resv); 351 352 return sgt; 353 } 354 355 static void 356 panthor_gem_vmap_cleanup_locked(struct panthor_gem_object *bo) 357 { 358 if (!bo->cmap.vaddr) 359 return; 360 361 vunmap(bo->cmap.vaddr); 362 bo->cmap.vaddr = NULL; 363 panthor_gem_backing_unpin_locked(bo); 364 } 365 366 static int 367 panthor_gem_prep_for_cpu_map_locked(struct panthor_gem_object *bo) 368 { 369 if (should_map_wc(bo)) { 370 struct sg_table *sgt; 371 372 sgt = panthor_gem_dev_map_get_sgt_locked(bo); 373 if (IS_ERR(sgt)) 374 return PTR_ERR(sgt); 375 } 376 377 return 0; 378 } 379 380 static void * 381 panthor_gem_vmap_get_locked(struct panthor_gem_object *bo) 382 { 383 pgprot_t prot = PAGE_KERNEL; 384 void *vaddr; 385 int ret; 386 387 dma_resv_assert_held(bo->base.resv); 388 389 if (drm_WARN_ON_ONCE(bo->base.dev, drm_gem_is_imported(&bo->base))) 390 return ERR_PTR(-EINVAL); 391 392 if (refcount_inc_not_zero(&bo->cmap.vaddr_use_count)) { 393 drm_WARN_ON_ONCE(bo->base.dev, !bo->cmap.vaddr); 394 return bo->cmap.vaddr; 395 } 396 397 ret = panthor_gem_backing_pin_locked(bo); 398 if (ret) 399 return ERR_PTR(ret); 400 401 ret = panthor_gem_prep_for_cpu_map_locked(bo); 402 if (ret) 403 goto err_unpin; 404 405 if (should_map_wc(bo)) 406 prot = pgprot_writecombine(prot); 407 408 vaddr = vmap(bo->backing.pages, bo->base.size >> PAGE_SHIFT, VM_MAP, prot); 409 if (!vaddr) { 410 ret = -ENOMEM; 411 goto err_unpin; 412 } 413 414 bo->cmap.vaddr = vaddr; 415 refcount_set(&bo->cmap.vaddr_use_count, 1); 416 return vaddr; 417 418 err_unpin: 419 panthor_gem_backing_unpin_locked(bo); 420 return ERR_PTR(ret); 421 } 422 423 static void 424 panthor_gem_vmap_put_locked(struct panthor_gem_object *bo) 425 { 426 dma_resv_assert_held(bo->base.resv); 427 428 if (drm_WARN_ON_ONCE(bo->base.dev, drm_gem_is_imported(&bo->base))) 429 return; 430 431 if (refcount_dec_and_test(&bo->cmap.vaddr_use_count)) 432 panthor_gem_vmap_cleanup_locked(bo); 433 } 434 435 static void panthor_gem_free_object(struct drm_gem_object *obj) 436 { 437 struct panthor_gem_object *bo = to_panthor_bo(obj); 438 struct drm_gem_object *vm_root_gem = bo->exclusive_vm_root_gem; 439 440 panthor_gem_debugfs_bo_rm(bo); 441 442 /* 443 * Label might have been allocated with kstrdup_const(), 444 * we need to take that into account when freeing the memory 445 */ 446 kfree_const(bo->label.str); 447 448 mutex_destroy(&bo->label.lock); 449 450 if (drm_gem_is_imported(obj)) { 451 drm_prime_gem_destroy(obj, bo->dmap.sgt); 452 } else { 453 /* The last ref on the GEM object can be released 454 * by the shrinker, which can't block on the resv 455 * lock acquisition. In practice, even if we were 456 * taking the lock, it wouldn't block because we're 457 * the last piece of code having a visibility on 458 * this GEM, but lockdep can't see that, so we've 459 * just tought the _cleanup_locked() helpers about 460 * this "being freed" exception, and we call those 461 * without the lock held here. 462 */ 463 panthor_gem_vmap_cleanup_locked(bo); 464 panthor_gem_dev_map_cleanup_locked(bo); 465 panthor_gem_backing_cleanup_locked(bo); 466 } 467 468 drm_gem_object_release(obj); 469 470 kfree(bo); 471 drm_gem_object_put(vm_root_gem); 472 } 473 474 static struct sg_table * 475 panthor_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, 476 enum dma_data_direction dir) 477 { 478 struct sg_table *sgt = drm_gem_map_dma_buf(attach, dir); 479 480 if (!IS_ERR(sgt)) 481 attach->priv = sgt; 482 483 return sgt; 484 } 485 486 static void 487 panthor_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach, 488 struct sg_table *sgt, 489 enum dma_data_direction dir) 490 { 491 attach->priv = NULL; 492 drm_gem_unmap_dma_buf(attach, sgt, dir); 493 } 494 495 static int 496 panthor_gem_prime_begin_cpu_access(struct dma_buf *dma_buf, 497 enum dma_data_direction dir) 498 { 499 struct drm_gem_object *obj = dma_buf->priv; 500 struct drm_device *dev = obj->dev; 501 struct panthor_gem_object *bo = to_panthor_bo(obj); 502 struct dma_buf_attachment *attach; 503 504 dma_resv_lock(obj->resv, NULL); 505 if (bo->dmap.sgt) 506 dma_sync_sgtable_for_cpu(drm_dev_dma_dev(dev), bo->dmap.sgt, dir); 507 508 if (bo->cmap.vaddr) 509 invalidate_kernel_vmap_range(bo->cmap.vaddr, bo->base.size); 510 511 list_for_each_entry(attach, &dma_buf->attachments, node) { 512 struct sg_table *sgt = attach->priv; 513 514 if (sgt) 515 dma_sync_sgtable_for_cpu(attach->dev, sgt, dir); 516 } 517 dma_resv_unlock(obj->resv); 518 519 return 0; 520 } 521 522 static int 523 panthor_gem_prime_end_cpu_access(struct dma_buf *dma_buf, 524 enum dma_data_direction dir) 525 { 526 struct drm_gem_object *obj = dma_buf->priv; 527 struct drm_device *dev = obj->dev; 528 struct panthor_gem_object *bo = to_panthor_bo(obj); 529 struct dma_buf_attachment *attach; 530 531 dma_resv_lock(obj->resv, NULL); 532 list_for_each_entry(attach, &dma_buf->attachments, node) { 533 struct sg_table *sgt = attach->priv; 534 535 if (sgt) 536 dma_sync_sgtable_for_device(attach->dev, sgt, dir); 537 } 538 539 if (bo->cmap.vaddr) 540 flush_kernel_vmap_range(bo->cmap.vaddr, bo->base.size); 541 542 if (bo->dmap.sgt) 543 dma_sync_sgtable_for_device(drm_dev_dma_dev(dev), bo->dmap.sgt, dir); 544 545 dma_resv_unlock(obj->resv); 546 return 0; 547 } 548 549 static const struct dma_buf_ops panthor_dma_buf_ops = { 550 .attach = drm_gem_map_attach, 551 .detach = drm_gem_map_detach, 552 .map_dma_buf = panthor_gem_prime_map_dma_buf, 553 .unmap_dma_buf = panthor_gem_prime_unmap_dma_buf, 554 .release = drm_gem_dmabuf_release, 555 .mmap = drm_gem_dmabuf_mmap, 556 .vmap = drm_gem_dmabuf_vmap, 557 .vunmap = drm_gem_dmabuf_vunmap, 558 .begin_cpu_access = panthor_gem_prime_begin_cpu_access, 559 .end_cpu_access = panthor_gem_prime_end_cpu_access, 560 }; 561 562 static struct dma_buf * 563 panthor_gem_prime_export(struct drm_gem_object *obj, int flags) 564 { 565 struct drm_device *dev = obj->dev; 566 struct dma_buf_export_info exp_info = { 567 .exp_name = KBUILD_MODNAME, 568 .owner = THIS_MODULE, 569 .ops = &panthor_dma_buf_ops, 570 .size = obj->size, 571 .flags = flags, 572 .priv = obj, 573 .resv = obj->resv, 574 }; 575 576 /* We can't export GEMs that have an exclusive VM. */ 577 if (to_panthor_bo(obj)->exclusive_vm_root_gem) 578 return ERR_PTR(-EINVAL); 579 580 return drm_gem_dmabuf_export(dev, &exp_info); 581 } 582 583 struct drm_gem_object * 584 panthor_gem_prime_import(struct drm_device *dev, 585 struct dma_buf *dma_buf) 586 { 587 struct drm_gem_object *obj = dma_buf->priv; 588 589 if (dma_buf->ops == &panthor_dma_buf_ops && obj->dev == dev) { 590 /* Importing dmabuf exported from our own gem increases 591 * refcount on gem itself instead of f_count of dmabuf. 592 */ 593 drm_gem_object_get(obj); 594 return obj; 595 } 596 597 return drm_gem_prime_import(dev, dma_buf); 598 } 599 600 static void panthor_gem_print_info(struct drm_printer *p, unsigned int indent, 601 const struct drm_gem_object *obj) 602 { 603 const struct panthor_gem_object *bo = to_panthor_bo(obj); 604 605 if (drm_gem_is_imported(&bo->base)) 606 return; 607 608 drm_printf_indent(p, indent, "resident=%s\n", str_true_false(bo->backing.pages)); 609 drm_printf_indent(p, indent, "pages_pin_count=%u\n", refcount_read(&bo->backing.pin_count)); 610 drm_printf_indent(p, indent, "vmap_use_count=%u\n", 611 refcount_read(&bo->cmap.vaddr_use_count)); 612 drm_printf_indent(p, indent, "vaddr=%p\n", bo->cmap.vaddr); 613 drm_printf_indent(p, indent, "mmap_count=%u\n", refcount_read(&bo->cmap.mmap_count)); 614 } 615 616 static int panthor_gem_pin_locked(struct drm_gem_object *obj) 617 { 618 if (!drm_gem_is_imported(obj)) 619 return panthor_gem_backing_pin_locked(to_panthor_bo(obj)); 620 621 return 0; 622 } 623 624 static void panthor_gem_unpin_locked(struct drm_gem_object *obj) 625 { 626 if (!drm_gem_is_imported(obj)) 627 panthor_gem_backing_unpin_locked(to_panthor_bo(obj)); 628 } 629 630 int panthor_gem_pin(struct panthor_gem_object *bo) 631 { 632 int ret = 0; 633 634 if (drm_gem_is_imported(&bo->base)) 635 return 0; 636 637 if (refcount_inc_not_zero(&bo->backing.pin_count)) 638 return 0; 639 640 dma_resv_lock(bo->base.resv, NULL); 641 ret = panthor_gem_backing_pin_locked(bo); 642 dma_resv_unlock(bo->base.resv); 643 644 return ret; 645 } 646 647 void panthor_gem_unpin(struct panthor_gem_object *bo) 648 { 649 if (drm_gem_is_imported(&bo->base)) 650 return; 651 652 if (refcount_dec_not_one(&bo->backing.pin_count)) 653 return; 654 655 dma_resv_lock(bo->base.resv, NULL); 656 panthor_gem_backing_unpin_locked(bo); 657 dma_resv_unlock(bo->base.resv); 658 } 659 660 int panthor_gem_swapin_locked(struct panthor_gem_object *bo) 661 { 662 struct sg_table *sgt; 663 664 dma_resv_assert_held(bo->base.resv); 665 666 if (drm_WARN_ON_ONCE(bo->base.dev, drm_gem_is_imported(&bo->base))) 667 return -EINVAL; 668 669 sgt = panthor_gem_dev_map_get_sgt_locked(bo); 670 if (IS_ERR(sgt)) 671 return PTR_ERR(sgt); 672 673 return 0; 674 } 675 676 static void panthor_gem_evict_locked(struct panthor_gem_object *bo) 677 { 678 dma_resv_assert_held(bo->base.resv); 679 lockdep_assert_held(&bo->base.gpuva.lock); 680 681 if (drm_WARN_ON_ONCE(bo->base.dev, drm_gem_is_imported(&bo->base))) 682 return; 683 684 if (drm_WARN_ON_ONCE(bo->base.dev, refcount_read(&bo->backing.pin_count))) 685 return; 686 687 if (drm_WARN_ON_ONCE(bo->base.dev, !bo->backing.pages)) 688 return; 689 690 panthor_gem_dev_map_cleanup_locked(bo); 691 panthor_gem_backing_cleanup_locked(bo); 692 panthor_gem_update_reclaim_state_locked(bo, NULL); 693 } 694 695 static struct sg_table *panthor_gem_get_sg_table(struct drm_gem_object *obj) 696 { 697 struct panthor_gem_object *bo = to_panthor_bo(obj); 698 699 drm_WARN_ON_ONCE(obj->dev, drm_gem_is_imported(obj)); 700 drm_WARN_ON_ONCE(obj->dev, !bo->backing.pages); 701 drm_WARN_ON_ONCE(obj->dev, !refcount_read(&bo->backing.pin_count)); 702 703 return drm_prime_pages_to_sg(obj->dev, bo->backing.pages, obj->size >> PAGE_SHIFT); 704 } 705 706 static int panthor_gem_vmap_locked(struct drm_gem_object *obj, 707 struct iosys_map *map) 708 { 709 struct panthor_gem_object *bo = to_panthor_bo(obj); 710 void *vaddr; 711 712 dma_resv_assert_held(obj->resv); 713 714 if (drm_gem_is_imported(obj)) 715 return dma_buf_vmap(obj->import_attach->dmabuf, map); 716 717 vaddr = panthor_gem_vmap_get_locked(bo); 718 if (IS_ERR(vaddr)) 719 return PTR_ERR(vaddr); 720 721 iosys_map_set_vaddr(map, vaddr); 722 return 0; 723 } 724 725 static void panthor_gem_vunmap_locked(struct drm_gem_object *obj, 726 struct iosys_map *map) 727 { 728 struct panthor_gem_object *bo = to_panthor_bo(obj); 729 730 dma_resv_assert_held(obj->resv); 731 732 if (drm_gem_is_imported(obj)) { 733 dma_buf_vunmap(obj->import_attach->dmabuf, map); 734 } else { 735 drm_WARN_ON_ONCE(obj->dev, bo->cmap.vaddr != map->vaddr); 736 panthor_gem_vmap_put_locked(bo); 737 } 738 } 739 740 static int panthor_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) 741 { 742 struct panthor_gem_object *bo = to_panthor_bo(obj); 743 int ret; 744 745 if (drm_gem_is_imported(obj)) { 746 /* Reset both vm_ops and vm_private_data, so we don't end up with 747 * vm_ops pointing to our implementation if the dma-buf backend 748 * doesn't set those fields. 749 */ 750 vma->vm_private_data = NULL; 751 vma->vm_ops = NULL; 752 753 ret = dma_buf_mmap(obj->dma_buf, vma, 0); 754 755 /* Drop the reference drm_gem_mmap_obj() acquired.*/ 756 if (!ret) 757 drm_gem_object_put(obj); 758 759 return ret; 760 } 761 762 if (is_cow_mapping(vma->vm_flags)) 763 return -EINVAL; 764 765 if (!refcount_inc_not_zero(&bo->cmap.mmap_count)) { 766 dma_resv_lock(obj->resv, NULL); 767 if (!refcount_inc_not_zero(&bo->cmap.mmap_count)) { 768 refcount_set(&bo->cmap.mmap_count, 1); 769 mutex_lock(&bo->base.gpuva.lock); 770 panthor_gem_update_reclaim_state_locked(bo, NULL); 771 mutex_unlock(&bo->base.gpuva.lock); 772 } 773 dma_resv_unlock(obj->resv); 774 } 775 776 vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP); 777 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); 778 if (should_map_wc(bo)) 779 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); 780 781 return 0; 782 } 783 784 static enum drm_gem_object_status panthor_gem_status(struct drm_gem_object *obj) 785 { 786 struct panthor_gem_object *bo = to_panthor_bo(obj); 787 enum drm_gem_object_status res = 0; 788 789 if (drm_gem_is_imported(&bo->base) || bo->backing.pages) 790 res |= DRM_GEM_OBJECT_RESIDENT; 791 792 return res; 793 } 794 795 static vm_fault_t insert_page(struct vm_fault *vmf, unsigned int order, struct page *page) 796 { 797 if (!order) { 798 return vmf_insert_pfn(vmf->vma, vmf->address, page_to_pfn(page)); 799 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP 800 } else if (order == PMD_ORDER) { 801 unsigned long pfn = page_to_pfn(page); 802 unsigned long paddr = pfn << PAGE_SHIFT; 803 bool aligned = (vmf->address & ~PMD_MASK) == (paddr & ~PMD_MASK); 804 805 if (aligned && 806 folio_test_pmd_mappable(page_folio(page))) { 807 pfn &= PMD_MASK >> PAGE_SHIFT; 808 return vmf_insert_pfn_pmd(vmf, pfn, vmf->flags & FAULT_FLAG_WRITE); 809 } 810 #endif 811 } 812 813 return VM_FAULT_FALLBACK; 814 } 815 816 static vm_fault_t nonblocking_page_setup(struct vm_fault *vmf, 817 unsigned int order, 818 pgoff_t page_offset) 819 { 820 struct vm_area_struct *vma = vmf->vma; 821 struct panthor_gem_object *bo = to_panthor_bo(vma->vm_private_data); 822 vm_fault_t ret; 823 824 if (!dma_resv_trylock(bo->base.resv)) 825 return VM_FAULT_RETRY; 826 827 if (bo->backing.pages) 828 ret = insert_page(vmf, order, bo->backing.pages[page_offset]); 829 else 830 ret = VM_FAULT_RETRY; 831 832 dma_resv_unlock(bo->base.resv); 833 return ret; 834 } 835 836 static vm_fault_t blocking_page_setup(struct vm_fault *vmf, unsigned int order, 837 struct panthor_gem_object *bo, 838 pgoff_t page_offset, bool mmap_lock_held) 839 { 840 vm_fault_t ret; 841 int err; 842 843 err = dma_resv_lock_interruptible(bo->base.resv, NULL); 844 if (err) 845 return mmap_lock_held ? VM_FAULT_NOPAGE : VM_FAULT_RETRY; 846 847 err = panthor_gem_backing_get_pages_locked(bo); 848 if (!err) 849 err = panthor_gem_prep_for_cpu_map_locked(bo); 850 851 if (err) { 852 ret = mmap_lock_held ? VM_FAULT_SIGBUS : VM_FAULT_RETRY; 853 } else { 854 struct page *page = bo->backing.pages[page_offset]; 855 856 mutex_lock(&bo->base.gpuva.lock); 857 panthor_gem_update_reclaim_state_locked(bo, NULL); 858 mutex_unlock(&bo->base.gpuva.lock); 859 860 if (mmap_lock_held) 861 ret = insert_page(vmf, order, page); 862 else 863 ret = VM_FAULT_RETRY; 864 } 865 866 dma_resv_unlock(bo->base.resv); 867 868 return ret; 869 } 870 871 static vm_fault_t panthor_gem_any_fault(struct vm_fault *vmf, unsigned int order) 872 { 873 struct vm_area_struct *vma = vmf->vma; 874 struct panthor_gem_object *bo = to_panthor_bo(vma->vm_private_data); 875 loff_t num_pages = bo->base.size >> PAGE_SHIFT; 876 pgoff_t page_offset; 877 vm_fault_t ret; 878 879 if (order && order != PMD_ORDER) 880 return VM_FAULT_FALLBACK; 881 882 /* Offset to faulty address in the VMA. */ 883 page_offset = vmf->pgoff - vma->vm_pgoff; 884 if (page_offset >= num_pages) 885 return VM_FAULT_SIGBUS; 886 887 ret = nonblocking_page_setup(vmf, order, page_offset); 888 if (ret != VM_FAULT_RETRY) 889 return ret; 890 891 /* Check if we're allowed to retry. */ 892 if (fault_flag_allow_retry_first(vmf->flags)) { 893 /* If we're allowed to retry but not wait here, return 894 * immediately, the wait will be done when the fault 895 * handler is called again, with the mmap_lock held. 896 */ 897 if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT) 898 return VM_FAULT_RETRY; 899 900 /* Wait with the mmap lock released, if we're allowed to. */ 901 drm_gem_object_get(&bo->base); 902 903 if (vmf->flags & FAULT_FLAG_VMA_LOCK) 904 vma_end_read(vmf->vma); 905 else 906 mmap_read_unlock(vmf->vma->vm_mm); 907 908 ret = blocking_page_setup(vmf, order, bo, page_offset, false); 909 drm_gem_object_put(&bo->base); 910 return ret; 911 } 912 913 return blocking_page_setup(vmf, order, bo, page_offset, true); 914 } 915 916 static vm_fault_t panthor_gem_fault(struct vm_fault *vmf) 917 { 918 return panthor_gem_any_fault(vmf, 0); 919 } 920 921 static void panthor_gem_vm_open(struct vm_area_struct *vma) 922 { 923 struct panthor_gem_object *bo = to_panthor_bo(vma->vm_private_data); 924 925 drm_WARN_ON(bo->base.dev, drm_gem_is_imported(&bo->base)); 926 drm_WARN_ON(bo->base.dev, !refcount_inc_not_zero(&bo->cmap.mmap_count)); 927 928 drm_gem_vm_open(vma); 929 } 930 931 static void panthor_gem_vm_close(struct vm_area_struct *vma) 932 { 933 struct panthor_gem_object *bo = to_panthor_bo(vma->vm_private_data); 934 935 if (drm_gem_is_imported(&bo->base)) 936 goto out; 937 938 if (refcount_dec_not_one(&bo->cmap.mmap_count)) 939 goto out; 940 941 dma_resv_lock(bo->base.resv, NULL); 942 if (refcount_dec_and_test(&bo->cmap.mmap_count)) { 943 mutex_lock(&bo->base.gpuva.lock); 944 panthor_gem_update_reclaim_state_locked(bo, NULL); 945 mutex_unlock(&bo->base.gpuva.lock); 946 } 947 dma_resv_unlock(bo->base.resv); 948 949 out: 950 drm_gem_object_put(&bo->base); 951 } 952 953 static const struct vm_operations_struct panthor_gem_vm_ops = { 954 .fault = panthor_gem_fault, 955 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP 956 .huge_fault = panthor_gem_any_fault, 957 #endif 958 .open = panthor_gem_vm_open, 959 .close = panthor_gem_vm_close, 960 }; 961 962 static const struct drm_gem_object_funcs panthor_gem_funcs = { 963 .free = panthor_gem_free_object, 964 .print_info = panthor_gem_print_info, 965 .pin = panthor_gem_pin_locked, 966 .unpin = panthor_gem_unpin_locked, 967 .get_sg_table = panthor_gem_get_sg_table, 968 .vmap = panthor_gem_vmap_locked, 969 .vunmap = panthor_gem_vunmap_locked, 970 .mmap = panthor_gem_mmap, 971 .status = panthor_gem_status, 972 .export = panthor_gem_prime_export, 973 .vm_ops = &panthor_gem_vm_ops, 974 }; 975 976 static struct panthor_gem_object * 977 panthor_gem_alloc_object(u32 flags) 978 { 979 struct panthor_gem_object *bo; 980 981 bo = kzalloc_obj(*bo); 982 if (!bo) 983 return ERR_PTR(-ENOMEM); 984 985 bo->reclaim_state = PANTHOR_GEM_UNRECLAIMABLE; 986 bo->base.funcs = &panthor_gem_funcs; 987 bo->flags = flags; 988 mutex_init(&bo->label.lock); 989 panthor_gem_debugfs_bo_init(bo); 990 return bo; 991 } 992 993 static struct panthor_gem_object * 994 panthor_gem_create(struct drm_device *dev, size_t size, uint32_t flags, 995 struct panthor_vm *exclusive_vm, u32 usage_flags) 996 { 997 struct panthor_gem_object *bo; 998 int ret; 999 1000 bo = panthor_gem_alloc_object(flags); 1001 if (IS_ERR(bo)) 1002 return bo; 1003 1004 size = PAGE_ALIGN(size); 1005 ret = drm_gem_object_init(dev, &bo->base, size); 1006 if (ret) 1007 goto err_put; 1008 1009 /* Our buffers are kept pinned, so allocating them 1010 * from the MOVABLE zone is a really bad idea, and 1011 * conflicts with CMA. See comments above new_inode() 1012 * why this is required _and_ expected if you're 1013 * going to pin these pages. 1014 */ 1015 mapping_set_gfp_mask(bo->base.filp->f_mapping, 1016 GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); 1017 1018 ret = drm_gem_create_mmap_offset(&bo->base); 1019 if (ret) 1020 goto err_put; 1021 1022 if (exclusive_vm) { 1023 bo->exclusive_vm_root_gem = panthor_vm_root_gem(exclusive_vm); 1024 drm_gem_object_get(bo->exclusive_vm_root_gem); 1025 bo->base.resv = bo->exclusive_vm_root_gem->resv; 1026 } 1027 1028 panthor_gem_debugfs_set_usage_flags(bo, usage_flags); 1029 return bo; 1030 1031 err_put: 1032 drm_gem_object_put(&bo->base); 1033 return ERR_PTR(ret); 1034 } 1035 1036 struct drm_gem_object * 1037 panthor_gem_prime_import_sg_table(struct drm_device *dev, 1038 struct dma_buf_attachment *attach, 1039 struct sg_table *sgt) 1040 { 1041 struct panthor_gem_object *bo; 1042 int ret; 1043 1044 bo = panthor_gem_alloc_object(0); 1045 if (IS_ERR(bo)) 1046 return ERR_CAST(bo); 1047 1048 drm_gem_private_object_init(dev, &bo->base, attach->dmabuf->size); 1049 1050 ret = drm_gem_create_mmap_offset(&bo->base); 1051 if (ret) 1052 goto err_put; 1053 1054 bo->dmap.sgt = sgt; 1055 return &bo->base; 1056 1057 err_put: 1058 drm_gem_object_put(&bo->base); 1059 return ERR_PTR(ret); 1060 } 1061 1062 /** 1063 * panthor_gem_create_with_handle() - Create a GEM object and attach it to a handle. 1064 * @file: DRM file. 1065 * @ddev: DRM device. 1066 * @exclusive_vm: Exclusive VM. Not NULL if the GEM object can't be shared. 1067 * @size: Size of the GEM object to allocate. 1068 * @flags: Combination of drm_panthor_bo_flags flags. 1069 * @handle: Pointer holding the handle pointing to the new GEM object. 1070 * 1071 * Return: Zero on success 1072 */ 1073 int 1074 panthor_gem_create_with_handle(struct drm_file *file, 1075 struct drm_device *ddev, 1076 struct panthor_vm *exclusive_vm, 1077 u64 *size, u32 flags, u32 *handle) 1078 { 1079 int ret; 1080 struct panthor_gem_object *bo; 1081 1082 bo = panthor_gem_create(ddev, *size, flags, exclusive_vm, 0); 1083 if (IS_ERR(bo)) 1084 return PTR_ERR(bo); 1085 1086 /* 1087 * Allocate an id of idr table where the obj is registered 1088 * and handle has the id what user can see. 1089 */ 1090 ret = drm_gem_handle_create(file, &bo->base, handle); 1091 if (!ret) 1092 *size = bo->base.size; 1093 1094 /* drop reference from allocate - handle holds it now. */ 1095 drm_gem_object_put(&bo->base); 1096 return ret; 1097 } 1098 1099 void 1100 panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label) 1101 { 1102 struct panthor_gem_object *bo = to_panthor_bo(obj); 1103 const char *old_label; 1104 1105 scoped_guard(mutex, &bo->label.lock) { 1106 old_label = bo->label.str; 1107 bo->label.str = label; 1108 } 1109 1110 kfree_const(old_label); 1111 } 1112 1113 void 1114 panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label) 1115 { 1116 const char *str; 1117 1118 /* We should never attempt labelling a UM-exposed GEM object */ 1119 if (drm_WARN_ON(bo->obj->dev, bo->obj->handle_count > 0)) 1120 return; 1121 1122 if (!label) 1123 return; 1124 1125 str = kstrdup_const(label, GFP_KERNEL); 1126 if (!str) { 1127 /* Failing to allocate memory for a label isn't a fatal condition */ 1128 drm_warn(bo->obj->dev, "Not enough memory to allocate BO label"); 1129 return; 1130 } 1131 1132 panthor_gem_bo_set_label(bo->obj, str); 1133 } 1134 1135 int 1136 panthor_gem_sync(struct drm_gem_object *obj, u32 type, 1137 u64 offset, u64 size) 1138 { 1139 struct panthor_gem_object *bo = to_panthor_bo(obj); 1140 struct device *dma_dev = drm_dev_dma_dev(bo->base.dev); 1141 struct sg_table *sgt; 1142 struct scatterlist *sgl; 1143 unsigned int count; 1144 int ret; 1145 1146 /* Make sure the range is in bounds. */ 1147 if (offset + size < offset || offset + size > bo->base.size) 1148 return -EINVAL; 1149 1150 /* Disallow CPU-cache maintenance on imported buffers. */ 1151 if (drm_gem_is_imported(&bo->base)) 1152 return -EINVAL; 1153 1154 switch (type) { 1155 case DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH: 1156 case DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE: 1157 break; 1158 1159 default: 1160 return -EINVAL; 1161 } 1162 1163 /* Don't bother if it's WC-mapped */ 1164 if (should_map_wc(bo)) 1165 return 0; 1166 1167 /* Nothing to do if the size is zero. */ 1168 if (size == 0) 1169 return 0; 1170 1171 ret = dma_resv_lock_interruptible(bo->base.resv, NULL); 1172 if (ret) 1173 return ret; 1174 1175 /* If there's no pages, there's no point pulling those back, bail out early. */ 1176 if (!bo->backing.pages) { 1177 ret = 0; 1178 goto out_unlock; 1179 } 1180 1181 sgt = panthor_gem_dev_map_get_sgt_locked(bo); 1182 if (IS_ERR(sgt)) { 1183 ret = PTR_ERR(sgt); 1184 goto out_unlock; 1185 } 1186 1187 for_each_sgtable_dma_sg(sgt, sgl, count) { 1188 if (size == 0) 1189 break; 1190 1191 dma_addr_t paddr = sg_dma_address(sgl); 1192 size_t len = sg_dma_len(sgl); 1193 1194 if (len <= offset) { 1195 offset -= len; 1196 continue; 1197 } 1198 1199 paddr += offset; 1200 len -= offset; 1201 len = min_t(size_t, len, size); 1202 size -= len; 1203 offset = 0; 1204 1205 /* It's unclear whether dma_sync_xxx() is the right API to do CPU 1206 * cache maintenance given an IOMMU can register their own 1207 * implementation doing more than just CPU cache flushes/invalidation, 1208 * and what we really care about here is CPU caches only, but that's 1209 * the best we have that is both arch-agnostic and does at least the 1210 * CPU cache maintenance on a <page,offset,size> tuple. 1211 * 1212 * Also, I wish we could do a single 1213 * 1214 * dma_sync_single_for_device(BIDIR) 1215 * 1216 * and get a flush+invalidate, but that's not how it's implemented 1217 * in practice (at least on arm64), so we have to make it 1218 * 1219 * dma_sync_single_for_device(TO_DEVICE) 1220 * dma_sync_single_for_cpu(FROM_DEVICE) 1221 * 1222 * for the flush+invalidate case. 1223 */ 1224 dma_sync_single_for_device(dma_dev, paddr, len, DMA_TO_DEVICE); 1225 if (type == DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE) 1226 dma_sync_single_for_cpu(dma_dev, paddr, len, DMA_FROM_DEVICE); 1227 } 1228 1229 ret = 0; 1230 1231 out_unlock: 1232 dma_resv_unlock(bo->base.resv); 1233 return ret; 1234 } 1235 1236 /** 1237 * panthor_kernel_bo_destroy() - Destroy a kernel buffer object 1238 * @bo: Kernel buffer object to destroy. If NULL or an ERR_PTR(), the destruction 1239 * is skipped. 1240 */ 1241 void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo) 1242 { 1243 struct panthor_device *ptdev; 1244 struct panthor_vm *vm; 1245 1246 if (IS_ERR_OR_NULL(bo)) 1247 return; 1248 1249 ptdev = container_of(bo->obj->dev, struct panthor_device, base); 1250 vm = bo->vm; 1251 panthor_kernel_bo_vunmap(bo); 1252 1253 drm_WARN_ON(bo->obj->dev, 1254 to_panthor_bo(bo->obj)->exclusive_vm_root_gem != panthor_vm_root_gem(vm)); 1255 panthor_vm_unmap_range(vm, bo->va_node.start, bo->va_node.size); 1256 panthor_vm_free_va(vm, &bo->va_node); 1257 if (vm == panthor_fw_vm(ptdev)) 1258 panthor_gem_unpin(to_panthor_bo(bo->obj)); 1259 drm_gem_object_put(bo->obj); 1260 panthor_vm_put(vm); 1261 kfree(bo); 1262 } 1263 1264 /** 1265 * panthor_kernel_bo_create() - Create and map a GEM object to a VM 1266 * @ptdev: Device. 1267 * @vm: VM to map the GEM to. 1268 * @size: Size of the buffer object. 1269 * @bo_flags: Combination of drm_panthor_bo_flags flags. 1270 * @vm_map_flags: Combination of drm_panthor_vm_bind_op_flags (only those 1271 * that are related to map operations). 1272 * @gpu_va: GPU address assigned when mapping to the VM. 1273 * If gpu_va == PANTHOR_VM_KERNEL_AUTO_VA, the virtual address will be 1274 * automatically allocated. 1275 * @name: Descriptive label of the BO's contents 1276 * 1277 * Return: A valid pointer in case of success, an ERR_PTR() otherwise. 1278 */ 1279 struct panthor_kernel_bo * 1280 panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, 1281 size_t size, u32 bo_flags, u32 vm_map_flags, 1282 u64 gpu_va, const char *name) 1283 { 1284 struct panthor_kernel_bo *kbo; 1285 struct panthor_gem_object *bo; 1286 u32 debug_flags = PANTHOR_DEBUGFS_GEM_USAGE_FLAG_KERNEL; 1287 int ret; 1288 1289 if (drm_WARN_ON(&ptdev->base, !vm)) 1290 return ERR_PTR(-EINVAL); 1291 1292 kbo = kzalloc_obj(*kbo); 1293 if (!kbo) 1294 return ERR_PTR(-ENOMEM); 1295 1296 if (vm == panthor_fw_vm(ptdev)) 1297 debug_flags |= PANTHOR_DEBUGFS_GEM_USAGE_FLAG_FW_MAPPED; 1298 1299 bo = panthor_gem_create(&ptdev->base, size, bo_flags, vm, debug_flags); 1300 if (IS_ERR(bo)) { 1301 ret = PTR_ERR(bo); 1302 goto err_free_kbo; 1303 } 1304 1305 kbo->obj = &bo->base; 1306 1307 if (vm == panthor_fw_vm(ptdev)) { 1308 ret = panthor_gem_pin(bo); 1309 if (ret) 1310 goto err_put_obj; 1311 } 1312 1313 panthor_gem_kernel_bo_set_label(kbo, name); 1314 1315 /* The system and GPU MMU page size might differ, which becomes a 1316 * problem for FW sections that need to be mapped at explicit address 1317 * since our PAGE_SIZE alignment might cover a VA range that's 1318 * expected to be used for another section. 1319 * Make sure we never map more than we need. 1320 */ 1321 size = ALIGN(size, panthor_vm_page_size(vm)); 1322 ret = panthor_vm_alloc_va(vm, gpu_va, size, &kbo->va_node); 1323 if (ret) 1324 goto err_unpin; 1325 1326 ret = panthor_vm_map_bo_range(vm, bo, 0, size, kbo->va_node.start, vm_map_flags); 1327 if (ret) 1328 goto err_free_va; 1329 1330 kbo->vm = panthor_vm_get(vm); 1331 return kbo; 1332 1333 err_free_va: 1334 panthor_vm_free_va(vm, &kbo->va_node); 1335 1336 err_unpin: 1337 if (vm == panthor_fw_vm(ptdev)) 1338 panthor_gem_unpin(bo); 1339 1340 err_put_obj: 1341 drm_gem_object_put(&bo->base); 1342 1343 err_free_kbo: 1344 kfree(kbo); 1345 return ERR_PTR(ret); 1346 } 1347 1348 static bool can_swap(void) 1349 { 1350 return get_nr_swap_pages() > 0; 1351 } 1352 1353 static bool can_block(struct shrink_control *sc) 1354 { 1355 /* If direct reclaim is allowed, we can always block. 1356 * If kswapd reclaim is allowed, we can block, but only if we're called 1357 * by the kswapd thread. 1358 */ 1359 return (sc->gfp_mask & __GFP_DIRECT_RECLAIM) || 1360 ((sc->gfp_mask & __GFP_KSWAPD_RECLAIM) && current_is_kswapd()); 1361 } 1362 1363 static unsigned long 1364 panthor_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) 1365 { 1366 struct panthor_device *ptdev = shrinker->private_data; 1367 unsigned long count; 1368 1369 /* We currently don't have a flag to tell when the content of a 1370 * BO can be discarded. 1371 */ 1372 if (!can_swap()) 1373 return 0; 1374 1375 /* This is racy, but that's okay because the returned count is just a 1376 * hint. That's also what MSM is doing (no atomic var, it's relying on 1377 * the fact unsigned long access is usually atomic), so if it's good 1378 * enough for them, it's good enough for us too. 1379 */ 1380 count = ptdev->reclaim.unused.count; 1381 count += ptdev->reclaim.mmapped.count; 1382 1383 if (can_block(sc)) 1384 count += ptdev->reclaim.gpu_mapped_count; 1385 1386 return count ? count : SHRINK_EMPTY; 1387 } 1388 1389 static bool panthor_gem_try_evict_no_resv_wait(struct drm_gem_object *obj, 1390 struct ww_acquire_ctx *ticket) 1391 { 1392 /* 1393 * Track last locked entry for unwinding locks in error and 1394 * success paths 1395 */ 1396 struct panthor_gem_object *bo = to_panthor_bo(obj); 1397 struct drm_gpuvm_bo *vm_bo, *last_locked = NULL; 1398 enum panthor_gem_reclaim_state old_state; 1399 int ret = 0; 1400 1401 /* To avoid potential lock ordering issue between bo_gpuva and 1402 * mapping->i_mmap_rwsem, unmap the pages from CPU side before 1403 * acquring the bo_gpuva lock. As the bo_resv lock is held, CPU 1404 * page fault handler won't be able to map in the pages whilst 1405 * eviction is in progress. 1406 */ 1407 drm_vma_node_unmap(&bo->base.vma_node, bo->base.dev->anon_inode->i_mapping); 1408 1409 /* We take this lock when walking the list to prevent 1410 * insertion/deletion. 1411 */ 1412 /* We can only trylock in that path, because 1413 * - allocation might happen while some of these locks are held 1414 * - lock ordering is different in other paths 1415 * vm_resv -> bo_resv -> bo_gpuva 1416 * vs 1417 * bo_resv -> bo_gpuva -> vm_resv 1418 * 1419 * If we fail to lock that's fine, we back off and will get 1420 * back to it later. 1421 */ 1422 if (!mutex_trylock(&bo->base.gpuva.lock)) 1423 return false; 1424 1425 drm_gem_for_each_gpuvm_bo(vm_bo, obj) { 1426 struct dma_resv *resv = drm_gpuvm_resv(vm_bo->vm); 1427 1428 if (resv == obj->resv) 1429 continue; 1430 1431 if (!dma_resv_trylock(resv)) { 1432 ret = -EDEADLK; 1433 goto out_unlock; 1434 } 1435 1436 last_locked = vm_bo; 1437 } 1438 1439 /* Update the state before trying to evict the buffer, if the state was 1440 * updated to something that's harder to reclaim (higher value in the 1441 * enum), skip it (will be processed when the relevant LRU is). 1442 */ 1443 panthor_gem_update_reclaim_state_locked(bo, &old_state); 1444 if (old_state < bo->reclaim_state) { 1445 ret = -EAGAIN; 1446 goto out_unlock; 1447 } 1448 1449 /* Couldn't teardown the GPU mappings? Skip. */ 1450 ret = panthor_vm_evict_bo_mappings_locked(bo); 1451 if (ret) 1452 goto out_unlock; 1453 1454 /* If everything went fine, evict the object. */ 1455 panthor_gem_evict_locked(bo); 1456 1457 out_unlock: 1458 if (last_locked) { 1459 drm_gem_for_each_gpuvm_bo(vm_bo, obj) { 1460 struct dma_resv *resv = drm_gpuvm_resv(vm_bo->vm); 1461 1462 if (resv == obj->resv) 1463 continue; 1464 1465 dma_resv_unlock(resv); 1466 1467 if (last_locked == vm_bo) 1468 break; 1469 } 1470 } 1471 mutex_unlock(&bo->base.gpuva.lock); 1472 1473 return ret == 0; 1474 } 1475 1476 static bool panthor_gem_try_evict(struct drm_gem_object *obj, 1477 struct ww_acquire_ctx *ticket) 1478 { 1479 struct panthor_gem_object *bo = to_panthor_bo(obj); 1480 1481 /* Wait was too long, skip. */ 1482 if (dma_resv_wait_timeout(obj->resv, DMA_RESV_USAGE_BOOKKEEP, false, 10) <= 0) 1483 return false; 1484 1485 return panthor_gem_try_evict_no_resv_wait(&bo->base, ticket); 1486 } 1487 1488 static unsigned long 1489 panthor_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) 1490 { 1491 struct panthor_device *ptdev = shrinker->private_data; 1492 unsigned long remaining = 0; 1493 unsigned long freed = 0; 1494 1495 if (!can_swap()) 1496 goto out; 1497 1498 freed += drm_gem_lru_scan(&ptdev->reclaim.unused, 1499 sc->nr_to_scan - freed, &remaining, 1500 panthor_gem_try_evict_no_resv_wait, NULL); 1501 if (freed >= sc->nr_to_scan) 1502 goto out; 1503 1504 freed += drm_gem_lru_scan(&ptdev->reclaim.mmapped, 1505 sc->nr_to_scan - freed, &remaining, 1506 panthor_gem_try_evict_no_resv_wait, NULL); 1507 if (freed >= sc->nr_to_scan) 1508 goto out; 1509 1510 if (!can_block(sc)) 1511 goto out; 1512 1513 freed += panthor_mmu_reclaim_priv_bos(ptdev, sc->nr_to_scan - freed, 1514 &remaining, panthor_gem_try_evict); 1515 if (freed >= sc->nr_to_scan) 1516 goto out; 1517 1518 freed += drm_gem_lru_scan(&ptdev->reclaim.gpu_mapped_shared, 1519 sc->nr_to_scan - freed, &remaining, 1520 panthor_gem_try_evict, NULL); 1521 1522 out: 1523 #ifdef CONFIG_DEBUG_FS 1524 /* This is racy, but that's okay, because this is just debugfs 1525 * reporting and doesn't need to be accurate. 1526 */ 1527 ptdev->reclaim.nr_pages_reclaimed_on_last_scan = freed; 1528 #endif 1529 1530 /* If there are things to reclaim, try a couple times before giving up. */ 1531 if (!freed && remaining > 0 && 1532 atomic_inc_return(&ptdev->reclaim.retry_count) < 2) 1533 return 0; 1534 1535 atomic_set(&ptdev->reclaim.retry_count, 0); 1536 1537 if (freed) 1538 return freed; 1539 1540 /* There's nothing left to reclaim, or the resources are contended. Give up now. */ 1541 return SHRINK_STOP; 1542 } 1543 1544 int panthor_gem_shrinker_init(struct panthor_device *ptdev) 1545 { 1546 struct shrinker *shrinker; 1547 int ret; 1548 1549 ret = drmm_mutex_init(&ptdev->base, &ptdev->reclaim.lock); 1550 if (ret) 1551 return ret; 1552 1553 INIT_LIST_HEAD(&ptdev->reclaim.vms); 1554 drm_gem_lru_init(&ptdev->reclaim.unused, &ptdev->reclaim.lock); 1555 drm_gem_lru_init(&ptdev->reclaim.mmapped, &ptdev->reclaim.lock); 1556 drm_gem_lru_init(&ptdev->reclaim.gpu_mapped_shared, &ptdev->reclaim.lock); 1557 ptdev->reclaim.gpu_mapped_count = 0; 1558 1559 /* Teach lockdep about lock ordering wrt. shrinker: */ 1560 fs_reclaim_acquire(GFP_KERNEL); 1561 might_lock(&ptdev->reclaim.lock); 1562 fs_reclaim_release(GFP_KERNEL); 1563 1564 shrinker = shrinker_alloc(0, "drm-panthor-gem"); 1565 if (!shrinker) 1566 return -ENOMEM; 1567 1568 shrinker->count_objects = panthor_gem_shrinker_count; 1569 shrinker->scan_objects = panthor_gem_shrinker_scan; 1570 shrinker->private_data = ptdev; 1571 ptdev->reclaim.shrinker = shrinker; 1572 1573 shrinker_register(shrinker); 1574 return 0; 1575 } 1576 1577 void panthor_gem_shrinker_unplug(struct panthor_device *ptdev) 1578 { 1579 if (ptdev->reclaim.shrinker) 1580 shrinker_free(ptdev->reclaim.shrinker); 1581 } 1582 1583 #ifdef CONFIG_DEBUG_FS 1584 struct gem_size_totals { 1585 size_t size; 1586 size_t resident; 1587 size_t reclaimable; 1588 }; 1589 1590 static void panthor_gem_debugfs_print_flag_names(struct seq_file *m) 1591 { 1592 int len; 1593 int i; 1594 1595 static const char * const gem_state_flags_names[] = { 1596 [PANTHOR_DEBUGFS_GEM_STATE_IMPORTED_BIT] = "imported", 1597 [PANTHOR_DEBUGFS_GEM_STATE_EXPORTED_BIT] = "exported", 1598 }; 1599 1600 static const char * const gem_usage_flags_names[] = { 1601 [PANTHOR_DEBUGFS_GEM_USAGE_KERNEL_BIT] = "kernel", 1602 [PANTHOR_DEBUGFS_GEM_USAGE_FW_MAPPED_BIT] = "fw-mapped", 1603 }; 1604 1605 seq_puts(m, "GEM state flags: "); 1606 for (i = 0, len = ARRAY_SIZE(gem_state_flags_names); i < len; i++) { 1607 if (!gem_state_flags_names[i]) 1608 continue; 1609 seq_printf(m, "%s (0x%x)%s", gem_state_flags_names[i], 1610 (u32)BIT(i), (i < len - 1) ? ", " : "\n"); 1611 } 1612 1613 seq_puts(m, "GEM usage flags: "); 1614 for (i = 0, len = ARRAY_SIZE(gem_usage_flags_names); i < len; i++) { 1615 if (!gem_usage_flags_names[i]) 1616 continue; 1617 seq_printf(m, "%s (0x%x)%s", gem_usage_flags_names[i], 1618 (u32)BIT(i), (i < len - 1) ? ", " : "\n\n"); 1619 } 1620 } 1621 1622 static void panthor_gem_debugfs_bo_print(struct panthor_gem_object *bo, 1623 struct seq_file *m, 1624 struct gem_size_totals *totals) 1625 { 1626 enum panthor_gem_reclaim_state reclaim_state = bo->reclaim_state; 1627 unsigned int refcount = kref_read(&bo->base.refcount); 1628 char creator_info[32] = {}; 1629 size_t resident_size; 1630 u32 gem_usage_flags = bo->debugfs.flags; 1631 u32 gem_state_flags = 0; 1632 1633 /* Skip BOs being destroyed. */ 1634 if (!refcount) 1635 return; 1636 1637 resident_size = bo->backing.pages ? bo->base.size : 0; 1638 1639 snprintf(creator_info, sizeof(creator_info), 1640 "%s/%d", bo->debugfs.creator.process_name, bo->debugfs.creator.tgid); 1641 seq_printf(m, "%-32s%-16d%-16d%-16zd%-16zd0x%-16lx", 1642 creator_info, 1643 bo->base.name, 1644 refcount, 1645 bo->base.size, 1646 resident_size, 1647 drm_vma_node_start(&bo->base.vma_node)); 1648 1649 if (drm_gem_is_imported(&bo->base)) 1650 gem_state_flags |= PANTHOR_DEBUGFS_GEM_STATE_FLAG_IMPORTED; 1651 if (bo->base.dma_buf) 1652 gem_state_flags |= PANTHOR_DEBUGFS_GEM_STATE_FLAG_EXPORTED; 1653 1654 seq_printf(m, "0x%-8x 0x%-10x", gem_state_flags, gem_usage_flags); 1655 1656 scoped_guard(mutex, &bo->label.lock) { 1657 seq_printf(m, "%s\n", bo->label.str ? : ""); 1658 } 1659 1660 totals->size += bo->base.size; 1661 totals->resident += resident_size; 1662 if (reclaim_state != PANTHOR_GEM_UNRECLAIMABLE) 1663 totals->reclaimable += resident_size; 1664 } 1665 1666 static void panthor_gem_debugfs_print_bos(struct panthor_device *ptdev, 1667 struct seq_file *m) 1668 { 1669 struct gem_size_totals totals = {0}; 1670 struct panthor_gem_object *bo; 1671 1672 panthor_gem_debugfs_print_flag_names(m); 1673 1674 seq_puts(m, "created-by global-name refcount size resident-size file-offset state usage label\n"); 1675 seq_puts(m, "----------------------------------------------------------------------------------------------------------------------------------------------\n"); 1676 1677 scoped_guard(mutex, &ptdev->gems.lock) { 1678 list_for_each_entry(bo, &ptdev->gems.node, debugfs.node) { 1679 panthor_gem_debugfs_bo_print(bo, m, &totals); 1680 } 1681 } 1682 1683 seq_puts(m, "==============================================================================================================================================\n"); 1684 seq_printf(m, "Total size: %zd, Total resident: %zd, Total reclaimable: %zd\n", 1685 totals.size, totals.resident, totals.reclaimable); 1686 } 1687 1688 static int panthor_gem_show_bos(struct seq_file *m, void *data) 1689 { 1690 struct drm_info_node *node = m->private; 1691 struct drm_device *dev = node->minor->dev; 1692 struct panthor_device *ptdev = 1693 container_of(dev, struct panthor_device, base); 1694 1695 panthor_gem_debugfs_print_bos(ptdev, m); 1696 1697 return 0; 1698 } 1699 1700 static struct drm_info_list panthor_gem_debugfs_list[] = { 1701 { "gems", panthor_gem_show_bos, 0, NULL }, 1702 }; 1703 1704 static int shrink_get(void *data, u64 *val) 1705 { 1706 struct panthor_device *ptdev = 1707 container_of(data, struct panthor_device, base); 1708 1709 *val = ptdev->reclaim.nr_pages_reclaimed_on_last_scan; 1710 return 0; 1711 } 1712 1713 static int shrink_set(void *data, u64 val) 1714 { 1715 struct panthor_device *ptdev = 1716 container_of(data, struct panthor_device, base); 1717 struct shrink_control sc = { 1718 .gfp_mask = GFP_KERNEL, 1719 .nr_to_scan = val, 1720 }; 1721 1722 fs_reclaim_acquire(GFP_KERNEL); 1723 if (ptdev->reclaim.shrinker) 1724 panthor_gem_shrinker_scan(ptdev->reclaim.shrinker, &sc); 1725 fs_reclaim_release(GFP_KERNEL); 1726 1727 return 0; 1728 } 1729 1730 DEFINE_DEBUGFS_ATTRIBUTE(panthor_gem_debugfs_shrink_fops, 1731 shrink_get, shrink_set, 1732 "0x%08llx\n"); 1733 1734 void panthor_gem_debugfs_init(struct drm_minor *minor) 1735 { 1736 drm_debugfs_create_files(panthor_gem_debugfs_list, 1737 ARRAY_SIZE(panthor_gem_debugfs_list), 1738 minor->debugfs_root, minor); 1739 debugfs_create_file("shrink", 0600, minor->debugfs_root, 1740 minor->dev, &panthor_gem_debugfs_shrink_fops); 1741 } 1742 #endif 1743