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