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 atomic_add_unless(&bo->reclaimed_count, 1, INT_MAX); 691 692 panthor_gem_dev_map_cleanup_locked(bo); 693 panthor_gem_backing_cleanup_locked(bo); 694 panthor_gem_update_reclaim_state_locked(bo, NULL); 695 } 696 697 static struct sg_table *panthor_gem_get_sg_table(struct drm_gem_object *obj) 698 { 699 struct panthor_gem_object *bo = to_panthor_bo(obj); 700 701 drm_WARN_ON_ONCE(obj->dev, drm_gem_is_imported(obj)); 702 drm_WARN_ON_ONCE(obj->dev, !bo->backing.pages); 703 drm_WARN_ON_ONCE(obj->dev, !refcount_read(&bo->backing.pin_count)); 704 705 return drm_prime_pages_to_sg(obj->dev, bo->backing.pages, obj->size >> PAGE_SHIFT); 706 } 707 708 static int panthor_gem_vmap_locked(struct drm_gem_object *obj, 709 struct iosys_map *map) 710 { 711 struct panthor_gem_object *bo = to_panthor_bo(obj); 712 void *vaddr; 713 714 dma_resv_assert_held(obj->resv); 715 716 if (drm_gem_is_imported(obj)) 717 return dma_buf_vmap(obj->import_attach->dmabuf, map); 718 719 vaddr = panthor_gem_vmap_get_locked(bo); 720 if (IS_ERR(vaddr)) 721 return PTR_ERR(vaddr); 722 723 iosys_map_set_vaddr(map, vaddr); 724 return 0; 725 } 726 727 static void panthor_gem_vunmap_locked(struct drm_gem_object *obj, 728 struct iosys_map *map) 729 { 730 struct panthor_gem_object *bo = to_panthor_bo(obj); 731 732 dma_resv_assert_held(obj->resv); 733 734 if (drm_gem_is_imported(obj)) { 735 dma_buf_vunmap(obj->import_attach->dmabuf, map); 736 } else { 737 drm_WARN_ON_ONCE(obj->dev, bo->cmap.vaddr != map->vaddr); 738 panthor_gem_vmap_put_locked(bo); 739 } 740 } 741 742 static int panthor_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) 743 { 744 struct panthor_gem_object *bo = to_panthor_bo(obj); 745 int ret; 746 747 if (drm_gem_is_imported(obj)) { 748 /* Reset both vm_ops and vm_private_data, so we don't end up with 749 * vm_ops pointing to our implementation if the dma-buf backend 750 * doesn't set those fields. 751 */ 752 vma->vm_private_data = NULL; 753 vma->vm_ops = NULL; 754 755 ret = dma_buf_mmap(obj->dma_buf, vma, 0); 756 757 /* Drop the reference drm_gem_mmap_obj() acquired.*/ 758 if (!ret) 759 drm_gem_object_put(obj); 760 761 return ret; 762 } 763 764 if (is_cow_mapping(vma->vm_flags)) 765 return -EINVAL; 766 767 if (!refcount_inc_not_zero(&bo->cmap.mmap_count)) { 768 dma_resv_lock(obj->resv, NULL); 769 if (!refcount_inc_not_zero(&bo->cmap.mmap_count)) { 770 refcount_set(&bo->cmap.mmap_count, 1); 771 mutex_lock(&bo->base.gpuva.lock); 772 panthor_gem_update_reclaim_state_locked(bo, NULL); 773 mutex_unlock(&bo->base.gpuva.lock); 774 } 775 dma_resv_unlock(obj->resv); 776 } 777 778 vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP); 779 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); 780 if (should_map_wc(bo)) 781 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); 782 783 return 0; 784 } 785 786 static enum drm_gem_object_status panthor_gem_status(struct drm_gem_object *obj) 787 { 788 struct panthor_gem_object *bo = to_panthor_bo(obj); 789 enum drm_gem_object_status res = 0; 790 791 if (drm_gem_is_imported(&bo->base) || bo->backing.pages) 792 res |= DRM_GEM_OBJECT_RESIDENT; 793 794 return res; 795 } 796 797 static vm_fault_t insert_page(struct vm_fault *vmf, unsigned int order, struct page *page) 798 { 799 if (!order) { 800 return vmf_insert_pfn(vmf->vma, vmf->address, page_to_pfn(page)); 801 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP 802 } else if (order == PMD_ORDER) { 803 unsigned long pfn = page_to_pfn(page); 804 unsigned long paddr = pfn << PAGE_SHIFT; 805 struct vm_area_struct *vma = vmf->vma; 806 unsigned long start = ALIGN_DOWN(vmf->address, PMD_SIZE); 807 unsigned long end = start + PMD_SIZE; 808 bool in_range = vma->vm_start <= start && end <= vma->vm_end; 809 bool aligned = (vmf->address & ~PMD_MASK) == (paddr & ~PMD_MASK); 810 811 if (aligned && in_range && 812 folio_test_pmd_mappable(page_folio(page))) { 813 pfn &= PMD_MASK >> PAGE_SHIFT; 814 return vmf_insert_pfn_pmd(vmf, pfn, vmf->flags & FAULT_FLAG_WRITE); 815 } 816 #endif 817 } 818 819 return VM_FAULT_FALLBACK; 820 } 821 822 static vm_fault_t nonblocking_page_setup(struct vm_fault *vmf, 823 unsigned int order, 824 pgoff_t page_offset) 825 { 826 struct vm_area_struct *vma = vmf->vma; 827 struct panthor_gem_object *bo = to_panthor_bo(vma->vm_private_data); 828 vm_fault_t ret; 829 830 if (!dma_resv_trylock(bo->base.resv)) 831 return VM_FAULT_RETRY; 832 833 if (bo->backing.pages) 834 ret = insert_page(vmf, order, bo->backing.pages[page_offset]); 835 else 836 ret = VM_FAULT_RETRY; 837 838 dma_resv_unlock(bo->base.resv); 839 return ret; 840 } 841 842 static vm_fault_t blocking_page_setup(struct vm_fault *vmf, unsigned int order, 843 struct panthor_gem_object *bo, 844 pgoff_t page_offset, bool mmap_lock_held) 845 { 846 vm_fault_t ret; 847 int err; 848 849 err = dma_resv_lock_interruptible(bo->base.resv, NULL); 850 if (err) 851 return mmap_lock_held ? VM_FAULT_NOPAGE : VM_FAULT_RETRY; 852 853 err = panthor_gem_backing_get_pages_locked(bo); 854 if (!err) 855 err = panthor_gem_prep_for_cpu_map_locked(bo); 856 857 if (err) { 858 ret = mmap_lock_held ? VM_FAULT_SIGBUS : VM_FAULT_RETRY; 859 } else { 860 struct page *page = bo->backing.pages[page_offset]; 861 862 mutex_lock(&bo->base.gpuva.lock); 863 panthor_gem_update_reclaim_state_locked(bo, NULL); 864 mutex_unlock(&bo->base.gpuva.lock); 865 866 if (mmap_lock_held) 867 ret = insert_page(vmf, order, page); 868 else 869 ret = VM_FAULT_RETRY; 870 } 871 872 dma_resv_unlock(bo->base.resv); 873 874 return ret; 875 } 876 877 static vm_fault_t panthor_gem_any_fault(struct vm_fault *vmf, unsigned int order) 878 { 879 struct vm_area_struct *vma = vmf->vma; 880 struct panthor_gem_object *bo = to_panthor_bo(vma->vm_private_data); 881 loff_t num_pages = bo->base.size >> PAGE_SHIFT; 882 pgoff_t page_offset; 883 vm_fault_t ret; 884 885 if (order && order != PMD_ORDER) 886 return VM_FAULT_FALLBACK; 887 888 /* Offset to faulty address in the VMA. */ 889 page_offset = vmf->pgoff - vma->vm_pgoff; 890 if (page_offset >= num_pages) 891 return VM_FAULT_SIGBUS; 892 893 ret = nonblocking_page_setup(vmf, order, page_offset); 894 if (ret != VM_FAULT_RETRY) 895 return ret; 896 897 /* Check if we're allowed to retry. */ 898 if (fault_flag_allow_retry_first(vmf->flags)) { 899 /* If we're allowed to retry but not wait here, return 900 * immediately, the wait will be done when the fault 901 * handler is called again, with the mmap_lock held. 902 */ 903 if (vmf->flags & FAULT_FLAG_RETRY_NOWAIT) 904 return VM_FAULT_RETRY; 905 906 /* Wait with the mmap lock released, if we're allowed to. */ 907 drm_gem_object_get(&bo->base); 908 909 if (vmf->flags & FAULT_FLAG_VMA_LOCK) 910 vma_end_read(vmf->vma); 911 else 912 mmap_read_unlock(vmf->vma->vm_mm); 913 914 ret = blocking_page_setup(vmf, order, bo, page_offset, false); 915 drm_gem_object_put(&bo->base); 916 return ret; 917 } 918 919 return blocking_page_setup(vmf, order, bo, page_offset, true); 920 } 921 922 static vm_fault_t panthor_gem_fault(struct vm_fault *vmf) 923 { 924 return panthor_gem_any_fault(vmf, 0); 925 } 926 927 static void panthor_gem_vm_open(struct vm_area_struct *vma) 928 { 929 struct panthor_gem_object *bo = to_panthor_bo(vma->vm_private_data); 930 931 drm_WARN_ON(bo->base.dev, drm_gem_is_imported(&bo->base)); 932 drm_WARN_ON(bo->base.dev, !refcount_inc_not_zero(&bo->cmap.mmap_count)); 933 934 drm_gem_vm_open(vma); 935 } 936 937 static void panthor_gem_vm_close(struct vm_area_struct *vma) 938 { 939 struct panthor_gem_object *bo = to_panthor_bo(vma->vm_private_data); 940 941 if (drm_gem_is_imported(&bo->base)) 942 goto out; 943 944 if (refcount_dec_not_one(&bo->cmap.mmap_count)) 945 goto out; 946 947 dma_resv_lock(bo->base.resv, NULL); 948 if (refcount_dec_and_test(&bo->cmap.mmap_count)) { 949 mutex_lock(&bo->base.gpuva.lock); 950 panthor_gem_update_reclaim_state_locked(bo, NULL); 951 mutex_unlock(&bo->base.gpuva.lock); 952 } 953 dma_resv_unlock(bo->base.resv); 954 955 out: 956 drm_gem_object_put(&bo->base); 957 } 958 959 static const struct vm_operations_struct panthor_gem_vm_ops = { 960 .fault = panthor_gem_fault, 961 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP 962 .huge_fault = panthor_gem_any_fault, 963 #endif 964 .open = panthor_gem_vm_open, 965 .close = panthor_gem_vm_close, 966 }; 967 968 static const struct drm_gem_object_funcs panthor_gem_funcs = { 969 .free = panthor_gem_free_object, 970 .print_info = panthor_gem_print_info, 971 .pin = panthor_gem_pin_locked, 972 .unpin = panthor_gem_unpin_locked, 973 .get_sg_table = panthor_gem_get_sg_table, 974 .vmap = panthor_gem_vmap_locked, 975 .vunmap = panthor_gem_vunmap_locked, 976 .mmap = panthor_gem_mmap, 977 .status = panthor_gem_status, 978 .export = panthor_gem_prime_export, 979 .vm_ops = &panthor_gem_vm_ops, 980 }; 981 982 static struct panthor_gem_object * 983 panthor_gem_alloc_object(u32 flags) 984 { 985 struct panthor_gem_object *bo; 986 987 bo = kzalloc_obj(*bo); 988 if (!bo) 989 return ERR_PTR(-ENOMEM); 990 991 bo->reclaim_state = PANTHOR_GEM_UNRECLAIMABLE; 992 bo->base.funcs = &panthor_gem_funcs; 993 bo->flags = flags; 994 mutex_init(&bo->label.lock); 995 panthor_gem_debugfs_bo_init(bo); 996 return bo; 997 } 998 999 static struct panthor_gem_object * 1000 panthor_gem_create(struct drm_device *dev, size_t size, uint32_t flags, 1001 struct panthor_vm *exclusive_vm, u32 usage_flags) 1002 { 1003 struct panthor_gem_object *bo; 1004 int ret; 1005 1006 bo = panthor_gem_alloc_object(flags); 1007 if (IS_ERR(bo)) 1008 return bo; 1009 1010 size = PAGE_ALIGN(size); 1011 ret = drm_gem_object_init(dev, &bo->base, size); 1012 if (ret) 1013 goto err_put; 1014 1015 /* Our buffers are kept pinned, so allocating them 1016 * from the MOVABLE zone is a really bad idea, and 1017 * conflicts with CMA. See comments above new_inode() 1018 * why this is required _and_ expected if you're 1019 * going to pin these pages. 1020 */ 1021 mapping_set_gfp_mask(bo->base.filp->f_mapping, 1022 GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); 1023 1024 ret = drm_gem_create_mmap_offset(&bo->base); 1025 if (ret) 1026 goto err_put; 1027 1028 if (exclusive_vm) { 1029 bo->exclusive_vm_root_gem = panthor_vm_root_gem(exclusive_vm); 1030 drm_gem_object_get(bo->exclusive_vm_root_gem); 1031 bo->base.resv = bo->exclusive_vm_root_gem->resv; 1032 } 1033 1034 panthor_gem_debugfs_set_usage_flags(bo, usage_flags); 1035 return bo; 1036 1037 err_put: 1038 drm_gem_object_put(&bo->base); 1039 return ERR_PTR(ret); 1040 } 1041 1042 struct drm_gem_object * 1043 panthor_gem_prime_import_sg_table(struct drm_device *dev, 1044 struct dma_buf_attachment *attach, 1045 struct sg_table *sgt) 1046 { 1047 struct panthor_gem_object *bo; 1048 int ret; 1049 1050 bo = panthor_gem_alloc_object(0); 1051 if (IS_ERR(bo)) 1052 return ERR_CAST(bo); 1053 1054 drm_gem_private_object_init(dev, &bo->base, attach->dmabuf->size); 1055 1056 ret = drm_gem_create_mmap_offset(&bo->base); 1057 if (ret) 1058 goto err_put; 1059 1060 bo->dmap.sgt = sgt; 1061 return &bo->base; 1062 1063 err_put: 1064 drm_gem_object_put(&bo->base); 1065 return ERR_PTR(ret); 1066 } 1067 1068 /** 1069 * panthor_gem_create_with_handle() - Create a GEM object and attach it to a handle. 1070 * @file: DRM file. 1071 * @ddev: DRM device. 1072 * @exclusive_vm: Exclusive VM. Not NULL if the GEM object can't be shared. 1073 * @size: Size of the GEM object to allocate. 1074 * @flags: Combination of drm_panthor_bo_flags flags. 1075 * @handle: Pointer holding the handle pointing to the new GEM object. 1076 * 1077 * Return: Zero on success 1078 */ 1079 int 1080 panthor_gem_create_with_handle(struct drm_file *file, 1081 struct drm_device *ddev, 1082 struct panthor_vm *exclusive_vm, 1083 u64 *size, u32 flags, u32 *handle) 1084 { 1085 int ret; 1086 struct panthor_gem_object *bo; 1087 1088 bo = panthor_gem_create(ddev, *size, flags, exclusive_vm, 0); 1089 if (IS_ERR(bo)) 1090 return PTR_ERR(bo); 1091 1092 /* 1093 * Allocate an id of idr table where the obj is registered 1094 * and handle has the id what user can see. 1095 */ 1096 ret = drm_gem_handle_create(file, &bo->base, handle); 1097 if (!ret) 1098 *size = bo->base.size; 1099 1100 /* drop reference from allocate - handle holds it now. */ 1101 drm_gem_object_put(&bo->base); 1102 return ret; 1103 } 1104 1105 void 1106 panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label) 1107 { 1108 struct panthor_gem_object *bo = to_panthor_bo(obj); 1109 const char *old_label; 1110 1111 scoped_guard(mutex, &bo->label.lock) { 1112 old_label = bo->label.str; 1113 bo->label.str = label; 1114 } 1115 1116 kfree_const(old_label); 1117 } 1118 1119 void 1120 panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label) 1121 { 1122 const char *str; 1123 1124 /* We should never attempt labelling a UM-exposed GEM object */ 1125 if (drm_WARN_ON(bo->obj->dev, bo->obj->handle_count > 0)) 1126 return; 1127 1128 if (!label) 1129 return; 1130 1131 str = kstrdup_const(label, GFP_KERNEL); 1132 if (!str) { 1133 /* Failing to allocate memory for a label isn't a fatal condition */ 1134 drm_warn(bo->obj->dev, "Not enough memory to allocate BO label"); 1135 return; 1136 } 1137 1138 panthor_gem_bo_set_label(bo->obj, str); 1139 } 1140 1141 int 1142 panthor_gem_sync(struct drm_gem_object *obj, u32 type, 1143 u64 offset, u64 size) 1144 { 1145 struct panthor_gem_object *bo = to_panthor_bo(obj); 1146 struct device *dma_dev = drm_dev_dma_dev(bo->base.dev); 1147 struct sg_table *sgt; 1148 struct scatterlist *sgl; 1149 unsigned int count; 1150 int ret; 1151 1152 /* Make sure the range is in bounds. */ 1153 if (offset + size < offset || offset + size > bo->base.size) 1154 return -EINVAL; 1155 1156 /* Disallow CPU-cache maintenance on imported buffers. */ 1157 if (drm_gem_is_imported(&bo->base)) 1158 return -EINVAL; 1159 1160 switch (type) { 1161 case DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH: 1162 case DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE: 1163 break; 1164 1165 default: 1166 return -EINVAL; 1167 } 1168 1169 /* Don't bother if it's WC-mapped */ 1170 if (should_map_wc(bo)) 1171 return 0; 1172 1173 /* Nothing to do if the size is zero. */ 1174 if (size == 0) 1175 return 0; 1176 1177 ret = dma_resv_lock_interruptible(bo->base.resv, NULL); 1178 if (ret) 1179 return ret; 1180 1181 /* If there's no pages, there's no point pulling those back, bail out early. */ 1182 if (!bo->backing.pages) { 1183 ret = 0; 1184 goto out_unlock; 1185 } 1186 1187 sgt = panthor_gem_dev_map_get_sgt_locked(bo); 1188 if (IS_ERR(sgt)) { 1189 ret = PTR_ERR(sgt); 1190 goto out_unlock; 1191 } 1192 1193 for_each_sgtable_dma_sg(sgt, sgl, count) { 1194 if (size == 0) 1195 break; 1196 1197 dma_addr_t paddr = sg_dma_address(sgl); 1198 size_t len = sg_dma_len(sgl); 1199 1200 if (len <= offset) { 1201 offset -= len; 1202 continue; 1203 } 1204 1205 paddr += offset; 1206 len -= offset; 1207 len = min_t(size_t, len, size); 1208 size -= len; 1209 offset = 0; 1210 1211 /* It's unclear whether dma_sync_xxx() is the right API to do CPU 1212 * cache maintenance given an IOMMU can register their own 1213 * implementation doing more than just CPU cache flushes/invalidation, 1214 * and what we really care about here is CPU caches only, but that's 1215 * the best we have that is both arch-agnostic and does at least the 1216 * CPU cache maintenance on a <page,offset,size> tuple. 1217 * 1218 * Also, I wish we could do a single 1219 * 1220 * dma_sync_single_for_device(BIDIR) 1221 * 1222 * and get a flush+invalidate, but that's not how it's implemented 1223 * in practice (at least on arm64), so we have to make it 1224 * 1225 * dma_sync_single_for_device(TO_DEVICE) 1226 * dma_sync_single_for_cpu(FROM_DEVICE) 1227 * 1228 * for the flush+invalidate case. 1229 */ 1230 dma_sync_single_for_device(dma_dev, paddr, len, DMA_TO_DEVICE); 1231 if (type == DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE) 1232 dma_sync_single_for_cpu(dma_dev, paddr, len, DMA_FROM_DEVICE); 1233 } 1234 1235 ret = 0; 1236 1237 out_unlock: 1238 dma_resv_unlock(bo->base.resv); 1239 return ret; 1240 } 1241 1242 /** 1243 * panthor_kernel_bo_destroy() - Destroy a kernel buffer object 1244 * @bo: Kernel buffer object to destroy. If NULL or an ERR_PTR(), the destruction 1245 * is skipped. 1246 */ 1247 void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo) 1248 { 1249 struct panthor_device *ptdev; 1250 struct panthor_vm *vm; 1251 1252 if (IS_ERR_OR_NULL(bo)) 1253 return; 1254 1255 ptdev = container_of(bo->obj->dev, struct panthor_device, base); 1256 vm = bo->vm; 1257 panthor_kernel_bo_vunmap(bo); 1258 1259 drm_WARN_ON(bo->obj->dev, 1260 to_panthor_bo(bo->obj)->exclusive_vm_root_gem != panthor_vm_root_gem(vm)); 1261 panthor_vm_unmap_range(vm, bo->va_node.start, bo->va_node.size); 1262 panthor_vm_free_va(vm, &bo->va_node); 1263 if (vm == panthor_fw_vm(ptdev)) 1264 panthor_gem_unpin(to_panthor_bo(bo->obj)); 1265 drm_gem_object_put(bo->obj); 1266 panthor_vm_put(vm); 1267 kfree(bo); 1268 } 1269 1270 /** 1271 * panthor_kernel_bo_create() - Create and map a GEM object to a VM 1272 * @ptdev: Device. 1273 * @vm: VM to map the GEM to. 1274 * @size: Size of the buffer object. 1275 * @bo_flags: Combination of drm_panthor_bo_flags flags. 1276 * @vm_map_flags: Combination of drm_panthor_vm_bind_op_flags (only those 1277 * that are related to map operations). 1278 * @gpu_va: GPU address assigned when mapping to the VM. 1279 * If gpu_va == PANTHOR_VM_KERNEL_AUTO_VA, the virtual address will be 1280 * automatically allocated. 1281 * @name: Descriptive label of the BO's contents 1282 * 1283 * Return: A valid pointer in case of success, an ERR_PTR() otherwise. 1284 */ 1285 struct panthor_kernel_bo * 1286 panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, 1287 size_t size, u32 bo_flags, u32 vm_map_flags, 1288 u64 gpu_va, const char *name) 1289 { 1290 struct panthor_kernel_bo *kbo; 1291 struct panthor_gem_object *bo; 1292 u32 debug_flags = PANTHOR_DEBUGFS_GEM_USAGE_FLAG_KERNEL; 1293 int ret; 1294 1295 if (drm_WARN_ON(&ptdev->base, !vm)) 1296 return ERR_PTR(-EINVAL); 1297 1298 kbo = kzalloc_obj(*kbo); 1299 if (!kbo) 1300 return ERR_PTR(-ENOMEM); 1301 1302 if (vm == panthor_fw_vm(ptdev)) 1303 debug_flags |= PANTHOR_DEBUGFS_GEM_USAGE_FLAG_FW_MAPPED; 1304 1305 bo = panthor_gem_create(&ptdev->base, size, bo_flags, vm, debug_flags); 1306 if (IS_ERR(bo)) { 1307 ret = PTR_ERR(bo); 1308 goto err_free_kbo; 1309 } 1310 1311 kbo->obj = &bo->base; 1312 1313 if (vm == panthor_fw_vm(ptdev)) { 1314 ret = panthor_gem_pin(bo); 1315 if (ret) 1316 goto err_put_obj; 1317 } 1318 1319 panthor_gem_kernel_bo_set_label(kbo, name); 1320 1321 /* The system and GPU MMU page size might differ, which becomes a 1322 * problem for FW sections that need to be mapped at explicit address 1323 * since our PAGE_SIZE alignment might cover a VA range that's 1324 * expected to be used for another section. 1325 * Make sure we never map more than we need. 1326 */ 1327 size = ALIGN(size, panthor_vm_page_size(vm)); 1328 ret = panthor_vm_alloc_va(vm, gpu_va, size, &kbo->va_node); 1329 if (ret) 1330 goto err_unpin; 1331 1332 ret = panthor_vm_map_bo_range(vm, bo, 0, size, kbo->va_node.start, vm_map_flags); 1333 if (ret) 1334 goto err_free_va; 1335 1336 kbo->vm = panthor_vm_get(vm); 1337 return kbo; 1338 1339 err_free_va: 1340 panthor_vm_free_va(vm, &kbo->va_node); 1341 1342 err_unpin: 1343 if (vm == panthor_fw_vm(ptdev)) 1344 panthor_gem_unpin(bo); 1345 1346 err_put_obj: 1347 drm_gem_object_put(&bo->base); 1348 1349 err_free_kbo: 1350 kfree(kbo); 1351 return ERR_PTR(ret); 1352 } 1353 1354 static bool can_swap(void) 1355 { 1356 return get_nr_swap_pages() > 0; 1357 } 1358 1359 static bool can_block(struct shrink_control *sc) 1360 { 1361 /* If direct reclaim is allowed, we can always block. 1362 * If kswapd reclaim is allowed, we can block, but only if we're called 1363 * by the kswapd thread. 1364 */ 1365 return (sc->gfp_mask & __GFP_DIRECT_RECLAIM) || 1366 ((sc->gfp_mask & __GFP_KSWAPD_RECLAIM) && current_is_kswapd()); 1367 } 1368 1369 static unsigned long 1370 panthor_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) 1371 { 1372 struct panthor_device *ptdev = shrinker->private_data; 1373 unsigned long count; 1374 1375 /* We currently don't have a flag to tell when the content of a 1376 * BO can be discarded. 1377 */ 1378 if (!can_swap()) 1379 return 0; 1380 1381 /* This is racy, but that's okay because the returned count is just a 1382 * hint. That's also what MSM is doing (no atomic var, it's relying on 1383 * the fact unsigned long access is usually atomic), so if it's good 1384 * enough for them, it's good enough for us too. 1385 */ 1386 count = ptdev->reclaim.unused.count; 1387 count += ptdev->reclaim.mmapped.count; 1388 1389 if (can_block(sc)) 1390 count += ptdev->reclaim.gpu_mapped_count; 1391 1392 return count ? count : SHRINK_EMPTY; 1393 } 1394 1395 static bool panthor_gem_try_evict_no_resv_wait(struct drm_gem_object *obj, 1396 struct ww_acquire_ctx *ticket) 1397 { 1398 /* 1399 * Track last locked entry for unwinding locks in error and 1400 * success paths 1401 */ 1402 struct panthor_gem_object *bo = to_panthor_bo(obj); 1403 struct drm_gpuvm_bo *vm_bo, *last_locked = NULL; 1404 enum panthor_gem_reclaim_state old_state; 1405 int ret = 0; 1406 1407 /* To avoid potential lock ordering issue between bo_gpuva and 1408 * mapping->i_mmap_rwsem, unmap the pages from CPU side before 1409 * acquring the bo_gpuva lock. As the bo_resv lock is held, CPU 1410 * page fault handler won't be able to map in the pages whilst 1411 * eviction is in progress. 1412 */ 1413 drm_vma_node_unmap(&bo->base.vma_node, bo->base.dev->anon_inode->i_mapping); 1414 1415 /* We take this lock when walking the list to prevent 1416 * insertion/deletion. 1417 */ 1418 /* We can only trylock in that path, because 1419 * - allocation might happen while some of these locks are held 1420 * - lock ordering is different in other paths 1421 * vm_resv -> bo_resv -> bo_gpuva 1422 * vs 1423 * bo_resv -> bo_gpuva -> vm_resv 1424 * 1425 * If we fail to lock that's fine, we back off and will get 1426 * back to it later. 1427 */ 1428 if (!mutex_trylock(&bo->base.gpuva.lock)) 1429 return false; 1430 1431 drm_gem_for_each_gpuvm_bo(vm_bo, obj) { 1432 struct dma_resv *resv = drm_gpuvm_resv(vm_bo->vm); 1433 1434 if (resv == obj->resv) 1435 continue; 1436 1437 if (!dma_resv_trylock(resv)) { 1438 ret = -EDEADLK; 1439 goto out_unlock; 1440 } 1441 1442 last_locked = vm_bo; 1443 } 1444 1445 /* Update the state before trying to evict the buffer, if the state was 1446 * updated to something that's harder to reclaim (higher value in the 1447 * enum), skip it (will be processed when the relevant LRU is). 1448 */ 1449 panthor_gem_update_reclaim_state_locked(bo, &old_state); 1450 if (old_state < bo->reclaim_state) { 1451 ret = -EAGAIN; 1452 goto out_unlock; 1453 } 1454 1455 /* Couldn't teardown the GPU mappings? Skip. */ 1456 ret = panthor_vm_evict_bo_mappings_locked(bo); 1457 if (ret) 1458 goto out_unlock; 1459 1460 /* If everything went fine, evict the object. */ 1461 panthor_gem_evict_locked(bo); 1462 1463 out_unlock: 1464 if (last_locked) { 1465 drm_gem_for_each_gpuvm_bo(vm_bo, obj) { 1466 struct dma_resv *resv = drm_gpuvm_resv(vm_bo->vm); 1467 1468 if (resv == obj->resv) 1469 continue; 1470 1471 dma_resv_unlock(resv); 1472 1473 if (last_locked == vm_bo) 1474 break; 1475 } 1476 } 1477 mutex_unlock(&bo->base.gpuva.lock); 1478 1479 return ret == 0; 1480 } 1481 1482 static bool panthor_gem_try_evict(struct drm_gem_object *obj, 1483 struct ww_acquire_ctx *ticket) 1484 { 1485 struct panthor_gem_object *bo = to_panthor_bo(obj); 1486 1487 /* Wait was too long, skip. */ 1488 if (dma_resv_wait_timeout(obj->resv, DMA_RESV_USAGE_BOOKKEEP, false, 10) <= 0) 1489 return false; 1490 1491 return panthor_gem_try_evict_no_resv_wait(&bo->base, ticket); 1492 } 1493 1494 static unsigned long 1495 panthor_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) 1496 { 1497 struct panthor_device *ptdev = shrinker->private_data; 1498 unsigned long remaining = 0; 1499 unsigned long freed = 0; 1500 1501 if (!can_swap()) 1502 goto out; 1503 1504 freed += drm_gem_lru_scan(&ptdev->base, &ptdev->reclaim.unused, 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 freed += drm_gem_lru_scan(&ptdev->base, &ptdev->reclaim.mmapped, 1511 sc->nr_to_scan - freed, &remaining, 1512 panthor_gem_try_evict_no_resv_wait, NULL); 1513 if (freed >= sc->nr_to_scan) 1514 goto out; 1515 1516 if (!can_block(sc)) 1517 goto out; 1518 1519 freed += panthor_mmu_reclaim_priv_bos(ptdev, sc->nr_to_scan - freed, 1520 &remaining, panthor_gem_try_evict); 1521 if (freed >= sc->nr_to_scan) 1522 goto out; 1523 1524 freed += drm_gem_lru_scan(&ptdev->base, &ptdev->reclaim.gpu_mapped_shared, 1525 sc->nr_to_scan - freed, &remaining, 1526 panthor_gem_try_evict, NULL); 1527 1528 out: 1529 #ifdef CONFIG_DEBUG_FS 1530 /* This is racy, but that's okay, because this is just debugfs 1531 * reporting and doesn't need to be accurate. 1532 */ 1533 ptdev->reclaim.nr_pages_reclaimed_on_last_scan = freed; 1534 #endif 1535 1536 /* If there are things to reclaim, try a couple times before giving up. */ 1537 if (!freed && remaining > 0 && 1538 atomic_inc_return(&ptdev->reclaim.retry_count) < 2) 1539 return 0; 1540 1541 atomic_set(&ptdev->reclaim.retry_count, 0); 1542 1543 if (freed) 1544 return freed; 1545 1546 /* There's nothing left to reclaim, or the resources are contended. Give up now. */ 1547 return SHRINK_STOP; 1548 } 1549 1550 int panthor_gem_shrinker_init(struct panthor_device *ptdev) 1551 { 1552 struct shrinker *shrinker; 1553 1554 INIT_LIST_HEAD(&ptdev->reclaim.vms); 1555 drm_gem_lru_init(&ptdev->reclaim.unused); 1556 drm_gem_lru_init(&ptdev->reclaim.mmapped); 1557 drm_gem_lru_init(&ptdev->reclaim.gpu_mapped_shared); 1558 ptdev->reclaim.gpu_mapped_count = 0; 1559 1560 /* Teach lockdep about lock ordering wrt. shrinker: */ 1561 fs_reclaim_acquire(GFP_KERNEL); 1562 might_lock(&ptdev->base.gem_lru_mutex); 1563 fs_reclaim_release(GFP_KERNEL); 1564 1565 shrinker = shrinker_alloc(0, "drm-panthor-gem"); 1566 if (!shrinker) 1567 return -ENOMEM; 1568 1569 shrinker->count_objects = panthor_gem_shrinker_count; 1570 shrinker->scan_objects = panthor_gem_shrinker_scan; 1571 shrinker->private_data = ptdev; 1572 ptdev->reclaim.shrinker = shrinker; 1573 1574 shrinker_register(shrinker); 1575 return 0; 1576 } 1577 1578 void panthor_gem_shrinker_unplug(struct panthor_device *ptdev) 1579 { 1580 if (ptdev->reclaim.shrinker) 1581 shrinker_free(ptdev->reclaim.shrinker); 1582 } 1583 1584 #ifdef CONFIG_DEBUG_FS 1585 struct gem_size_totals { 1586 size_t size; 1587 size_t resident; 1588 size_t reclaimable; 1589 }; 1590 1591 static void panthor_gem_debugfs_print_flag_names(struct seq_file *m) 1592 { 1593 int len; 1594 int i; 1595 1596 static const char * const gem_state_flags_names[] = { 1597 [PANTHOR_DEBUGFS_GEM_STATE_IMPORTED_BIT] = "imported", 1598 [PANTHOR_DEBUGFS_GEM_STATE_EXPORTED_BIT] = "exported", 1599 [PANTHOR_DEBUGFS_GEM_STATE_EVICTED_BIT] = "evicted", 1600 }; 1601 1602 static const char * const gem_usage_flags_names[] = { 1603 [PANTHOR_DEBUGFS_GEM_USAGE_KERNEL_BIT] = "kernel", 1604 [PANTHOR_DEBUGFS_GEM_USAGE_FW_MAPPED_BIT] = "fw-mapped", 1605 }; 1606 1607 seq_puts(m, "GEM state flags: "); 1608 for (i = 0, len = ARRAY_SIZE(gem_state_flags_names); i < len; i++) { 1609 if (!gem_state_flags_names[i]) 1610 continue; 1611 seq_printf(m, "%s (0x%x)%s", gem_state_flags_names[i], 1612 (u32)BIT(i), (i < len - 1) ? ", " : "\n"); 1613 } 1614 1615 seq_puts(m, "GEM usage flags: "); 1616 for (i = 0, len = ARRAY_SIZE(gem_usage_flags_names); i < len; i++) { 1617 if (!gem_usage_flags_names[i]) 1618 continue; 1619 seq_printf(m, "%s (0x%x)%s", gem_usage_flags_names[i], 1620 (u32)BIT(i), (i < len - 1) ? ", " : "\n\n"); 1621 } 1622 } 1623 1624 static void panthor_gem_debugfs_bo_print(struct panthor_gem_object *bo, 1625 struct seq_file *m, 1626 struct gem_size_totals *totals) 1627 { 1628 enum panthor_gem_reclaim_state reclaim_state = bo->reclaim_state; 1629 unsigned int refcount = kref_read(&bo->base.refcount); 1630 int reclaimed_count = atomic_read(&bo->reclaimed_count); 1631 char creator_info[32] = {}; 1632 size_t resident_size; 1633 u32 gem_usage_flags = bo->debugfs.flags; 1634 u32 gem_state_flags = 0; 1635 1636 /* Skip BOs being destroyed. */ 1637 if (!refcount) 1638 return; 1639 1640 resident_size = bo->backing.pages ? bo->base.size : 0; 1641 1642 snprintf(creator_info, sizeof(creator_info), 1643 "%s/%d", bo->debugfs.creator.process_name, bo->debugfs.creator.tgid); 1644 seq_printf(m, "%-32s%-16d%-11d%-11d%-16zd%-16zd0x%-16lx", 1645 creator_info, 1646 bo->base.name, 1647 refcount, 1648 reclaimed_count, 1649 bo->base.size, 1650 resident_size, 1651 drm_vma_node_start(&bo->base.vma_node)); 1652 1653 if (drm_gem_is_imported(&bo->base)) 1654 gem_state_flags |= PANTHOR_DEBUGFS_GEM_STATE_FLAG_IMPORTED; 1655 else if (!resident_size && reclaimed_count) 1656 gem_state_flags |= PANTHOR_DEBUGFS_GEM_STATE_FLAG_EVICTED; 1657 1658 if (bo->base.dma_buf) 1659 gem_state_flags |= PANTHOR_DEBUGFS_GEM_STATE_FLAG_EXPORTED; 1660 1661 seq_printf(m, "0x%-8x 0x%-10x", gem_state_flags, gem_usage_flags); 1662 1663 scoped_guard(mutex, &bo->label.lock) { 1664 seq_printf(m, "%s\n", bo->label.str ? : ""); 1665 } 1666 1667 totals->size += bo->base.size; 1668 totals->resident += resident_size; 1669 if (reclaim_state != PANTHOR_GEM_UNRECLAIMABLE) 1670 totals->reclaimable += resident_size; 1671 } 1672 1673 static void panthor_gem_debugfs_print_bos(struct panthor_device *ptdev, 1674 struct seq_file *m) 1675 { 1676 struct gem_size_totals totals = {0}; 1677 struct panthor_gem_object *bo; 1678 1679 panthor_gem_debugfs_print_flag_names(m); 1680 1681 seq_puts(m, "created-by global-name refcount evictions size resident-size file-offset state usage label\n"); 1682 seq_puts(m, "----------------------------------------------------------------------------------------------------------------------------------------------------\n"); 1683 1684 scoped_guard(mutex, &ptdev->gems.lock) { 1685 list_for_each_entry(bo, &ptdev->gems.node, debugfs.node) { 1686 panthor_gem_debugfs_bo_print(bo, m, &totals); 1687 } 1688 } 1689 1690 seq_puts(m, "====================================================================================================================================================\n"); 1691 seq_printf(m, "Total size: %zd, Total resident: %zd, Total reclaimable: %zd\n", 1692 totals.size, totals.resident, totals.reclaimable); 1693 } 1694 1695 static int panthor_gem_show_bos(struct seq_file *m, void *data) 1696 { 1697 struct drm_info_node *node = m->private; 1698 struct drm_device *dev = node->minor->dev; 1699 struct panthor_device *ptdev = 1700 container_of(dev, struct panthor_device, base); 1701 1702 panthor_gem_debugfs_print_bos(ptdev, m); 1703 1704 return 0; 1705 } 1706 1707 static struct drm_info_list panthor_gem_debugfs_list[] = { 1708 { "gems", panthor_gem_show_bos, 0, NULL }, 1709 }; 1710 1711 static int shrink_get(void *data, u64 *val) 1712 { 1713 struct panthor_device *ptdev = 1714 container_of(data, struct panthor_device, base); 1715 1716 *val = ptdev->reclaim.nr_pages_reclaimed_on_last_scan; 1717 return 0; 1718 } 1719 1720 static int shrink_set(void *data, u64 val) 1721 { 1722 struct panthor_device *ptdev = 1723 container_of(data, struct panthor_device, base); 1724 struct shrink_control sc = { 1725 .gfp_mask = GFP_KERNEL, 1726 .nr_to_scan = val, 1727 }; 1728 1729 fs_reclaim_acquire(GFP_KERNEL); 1730 if (ptdev->reclaim.shrinker) 1731 panthor_gem_shrinker_scan(ptdev->reclaim.shrinker, &sc); 1732 fs_reclaim_release(GFP_KERNEL); 1733 1734 return 0; 1735 } 1736 1737 DEFINE_DEBUGFS_ATTRIBUTE(panthor_gem_debugfs_shrink_fops, 1738 shrink_get, shrink_set, 1739 "0x%08llx\n"); 1740 1741 void panthor_gem_debugfs_init(struct drm_minor *minor) 1742 { 1743 drm_debugfs_create_files(panthor_gem_debugfs_list, 1744 ARRAY_SIZE(panthor_gem_debugfs_list), 1745 minor->debugfs_root, minor); 1746 debugfs_create_file("shrink", 0600, minor->debugfs_root, 1747 minor->dev, &panthor_gem_debugfs_shrink_fops); 1748 } 1749 #endif 1750