1 /* 2 * Copyright 2016 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: Christian König 23 */ 24 25 #include <linux/dma-mapping.h> 26 #include <drm/ttm/ttm_range_manager.h> 27 28 #include "amdgpu.h" 29 #include "amdgpu_vm.h" 30 #include "amdgpu_res_cursor.h" 31 #include "amdgpu_atomfirmware.h" 32 #include "atom.h" 33 34 #define AMDGPU_MAX_SG_SEGMENT_SIZE (2UL << 30) 35 36 struct amdgpu_vram_reservation { 37 u64 start; 38 u64 size; 39 struct list_head allocated; 40 struct list_head blocks; 41 }; 42 43 static inline struct amdgpu_vram_mgr * 44 to_vram_mgr(struct ttm_resource_manager *man) 45 { 46 return container_of(man, struct amdgpu_vram_mgr, manager); 47 } 48 49 static inline struct amdgpu_device * 50 to_amdgpu_device(struct amdgpu_vram_mgr *mgr) 51 { 52 return container_of(mgr, struct amdgpu_device, mman.vram_mgr); 53 } 54 55 static inline struct drm_buddy_block * 56 amdgpu_vram_mgr_first_block(struct list_head *list) 57 { 58 return list_first_entry_or_null(list, struct drm_buddy_block, link); 59 } 60 61 static inline bool amdgpu_is_vram_mgr_blocks_contiguous(struct list_head *head) 62 { 63 struct drm_buddy_block *block; 64 u64 start, size; 65 66 block = amdgpu_vram_mgr_first_block(head); 67 if (!block) 68 return false; 69 70 while (head != block->link.next) { 71 start = amdgpu_vram_mgr_block_start(block); 72 size = amdgpu_vram_mgr_block_size(block); 73 74 block = list_entry(block->link.next, struct drm_buddy_block, link); 75 if (start + size != amdgpu_vram_mgr_block_start(block)) 76 return false; 77 } 78 79 return true; 80 } 81 82 static inline u64 amdgpu_vram_mgr_blocks_size(struct list_head *head) 83 { 84 struct drm_buddy_block *block; 85 u64 size = 0; 86 87 list_for_each_entry(block, head, link) 88 size += amdgpu_vram_mgr_block_size(block); 89 90 return size; 91 } 92 93 /** 94 * DOC: mem_info_vram_total 95 * 96 * The amdgpu driver provides a sysfs API for reporting current total VRAM 97 * available on the device 98 * The file mem_info_vram_total is used for this and returns the total 99 * amount of VRAM in bytes 100 */ 101 static ssize_t amdgpu_mem_info_vram_total_show(struct device *dev, 102 struct device_attribute *attr, char *buf) 103 { 104 struct drm_device *ddev = dev_get_drvdata(dev); 105 struct amdgpu_device *adev = drm_to_adev(ddev); 106 107 return sysfs_emit(buf, "%llu\n", adev->gmc.real_vram_size); 108 } 109 110 /** 111 * DOC: mem_info_vis_vram_total 112 * 113 * The amdgpu driver provides a sysfs API for reporting current total 114 * visible VRAM available on the device 115 * The file mem_info_vis_vram_total is used for this and returns the total 116 * amount of visible VRAM in bytes 117 */ 118 static ssize_t amdgpu_mem_info_vis_vram_total_show(struct device *dev, 119 struct device_attribute *attr, char *buf) 120 { 121 struct drm_device *ddev = dev_get_drvdata(dev); 122 struct amdgpu_device *adev = drm_to_adev(ddev); 123 124 return sysfs_emit(buf, "%llu\n", adev->gmc.visible_vram_size); 125 } 126 127 /** 128 * DOC: mem_info_vram_used 129 * 130 * The amdgpu driver provides a sysfs API for reporting current total VRAM 131 * available on the device 132 * The file mem_info_vram_used is used for this and returns the total 133 * amount of currently used VRAM in bytes 134 */ 135 static ssize_t amdgpu_mem_info_vram_used_show(struct device *dev, 136 struct device_attribute *attr, 137 char *buf) 138 { 139 struct drm_device *ddev = dev_get_drvdata(dev); 140 struct amdgpu_device *adev = drm_to_adev(ddev); 141 struct ttm_resource_manager *man = &adev->mman.vram_mgr.manager; 142 143 return sysfs_emit(buf, "%llu\n", ttm_resource_manager_usage(man)); 144 } 145 146 /** 147 * DOC: mem_info_vis_vram_used 148 * 149 * The amdgpu driver provides a sysfs API for reporting current total of 150 * used visible VRAM 151 * The file mem_info_vis_vram_used is used for this and returns the total 152 * amount of currently used visible VRAM in bytes 153 */ 154 static ssize_t amdgpu_mem_info_vis_vram_used_show(struct device *dev, 155 struct device_attribute *attr, 156 char *buf) 157 { 158 struct drm_device *ddev = dev_get_drvdata(dev); 159 struct amdgpu_device *adev = drm_to_adev(ddev); 160 161 return sysfs_emit(buf, "%llu\n", 162 amdgpu_vram_mgr_vis_usage(&adev->mman.vram_mgr)); 163 } 164 165 /** 166 * DOC: mem_info_vram_vendor 167 * 168 * The amdgpu driver provides a sysfs API for reporting the vendor of the 169 * installed VRAM 170 * The file mem_info_vram_vendor is used for this and returns the name of the 171 * vendor. 172 */ 173 static ssize_t amdgpu_mem_info_vram_vendor(struct device *dev, 174 struct device_attribute *attr, 175 char *buf) 176 { 177 struct drm_device *ddev = dev_get_drvdata(dev); 178 struct amdgpu_device *adev = drm_to_adev(ddev); 179 180 switch (adev->gmc.vram_vendor) { 181 case SAMSUNG: 182 return sysfs_emit(buf, "samsung\n"); 183 case INFINEON: 184 return sysfs_emit(buf, "infineon\n"); 185 case ELPIDA: 186 return sysfs_emit(buf, "elpida\n"); 187 case ETRON: 188 return sysfs_emit(buf, "etron\n"); 189 case NANYA: 190 return sysfs_emit(buf, "nanya\n"); 191 case HYNIX: 192 return sysfs_emit(buf, "hynix\n"); 193 case MOSEL: 194 return sysfs_emit(buf, "mosel\n"); 195 case WINBOND: 196 return sysfs_emit(buf, "winbond\n"); 197 case ESMT: 198 return sysfs_emit(buf, "esmt\n"); 199 case MICRON: 200 return sysfs_emit(buf, "micron\n"); 201 default: 202 return sysfs_emit(buf, "unknown\n"); 203 } 204 } 205 206 static DEVICE_ATTR(mem_info_vram_total, S_IRUGO, 207 amdgpu_mem_info_vram_total_show, NULL); 208 static DEVICE_ATTR(mem_info_vis_vram_total, S_IRUGO, 209 amdgpu_mem_info_vis_vram_total_show,NULL); 210 static DEVICE_ATTR(mem_info_vram_used, S_IRUGO, 211 amdgpu_mem_info_vram_used_show, NULL); 212 static DEVICE_ATTR(mem_info_vis_vram_used, S_IRUGO, 213 amdgpu_mem_info_vis_vram_used_show, NULL); 214 static DEVICE_ATTR(mem_info_vram_vendor, S_IRUGO, 215 amdgpu_mem_info_vram_vendor, NULL); 216 217 static struct attribute *amdgpu_vram_mgr_attributes[] = { 218 &dev_attr_mem_info_vram_total.attr, 219 &dev_attr_mem_info_vis_vram_total.attr, 220 &dev_attr_mem_info_vram_used.attr, 221 &dev_attr_mem_info_vis_vram_used.attr, 222 &dev_attr_mem_info_vram_vendor.attr, 223 NULL 224 }; 225 226 static umode_t amdgpu_vram_attrs_is_visible(struct kobject *kobj, 227 struct attribute *attr, int i) 228 { 229 struct device *dev = kobj_to_dev(kobj); 230 struct drm_device *ddev = dev_get_drvdata(dev); 231 struct amdgpu_device *adev = drm_to_adev(ddev); 232 233 if (attr == &dev_attr_mem_info_vram_vendor.attr && 234 !adev->gmc.vram_vendor) 235 return 0; 236 237 return attr->mode; 238 } 239 240 const struct attribute_group amdgpu_vram_mgr_attr_group = { 241 .attrs = amdgpu_vram_mgr_attributes, 242 .is_visible = amdgpu_vram_attrs_is_visible 243 }; 244 245 /** 246 * amdgpu_vram_mgr_vis_size - Calculate visible block size 247 * 248 * @adev: amdgpu_device pointer 249 * @block: DRM BUDDY block structure 250 * 251 * Calculate how many bytes of the DRM BUDDY block are inside visible VRAM 252 */ 253 static u64 amdgpu_vram_mgr_vis_size(struct amdgpu_device *adev, 254 struct drm_buddy_block *block) 255 { 256 u64 start = amdgpu_vram_mgr_block_start(block); 257 u64 end = start + amdgpu_vram_mgr_block_size(block); 258 259 if (start >= adev->gmc.visible_vram_size) 260 return 0; 261 262 return (end > adev->gmc.visible_vram_size ? 263 adev->gmc.visible_vram_size : end) - start; 264 } 265 266 /** 267 * amdgpu_vram_mgr_bo_visible_size - CPU visible BO size 268 * 269 * @bo: &amdgpu_bo buffer object (must be in VRAM) 270 * 271 * Returns: 272 * How much of the given &amdgpu_bo buffer object lies in CPU visible VRAM. 273 */ 274 u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo) 275 { 276 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); 277 struct ttm_resource *res = bo->tbo.resource; 278 struct amdgpu_vram_mgr_resource *vres = to_amdgpu_vram_mgr_resource(res); 279 struct drm_buddy_block *block; 280 u64 usage = 0; 281 282 if (amdgpu_gmc_vram_full_visible(&adev->gmc)) 283 return amdgpu_bo_size(bo); 284 285 if (res->start >= adev->gmc.visible_vram_size >> PAGE_SHIFT) 286 return 0; 287 288 list_for_each_entry(block, &vres->blocks, link) 289 usage += amdgpu_vram_mgr_vis_size(adev, block); 290 291 return usage; 292 } 293 294 /* Commit the reservation of VRAM pages */ 295 static void amdgpu_vram_mgr_do_reserve(struct ttm_resource_manager *man) 296 { 297 struct amdgpu_vram_mgr *mgr = to_vram_mgr(man); 298 struct amdgpu_device *adev = to_amdgpu_device(mgr); 299 struct drm_buddy *mm = &mgr->mm; 300 struct amdgpu_vram_reservation *rsv, *temp; 301 struct drm_buddy_block *block; 302 uint64_t vis_usage; 303 304 list_for_each_entry_safe(rsv, temp, &mgr->reservations_pending, blocks) { 305 if (drm_buddy_alloc_blocks(mm, rsv->start, rsv->start + rsv->size, 306 rsv->size, mm->chunk_size, &rsv->allocated, 307 DRM_BUDDY_RANGE_ALLOCATION)) 308 continue; 309 310 block = amdgpu_vram_mgr_first_block(&rsv->allocated); 311 if (!block) 312 continue; 313 314 dev_dbg(adev->dev, "Reservation 0x%llx - %lld, Succeeded\n", 315 rsv->start, rsv->size); 316 317 vis_usage = amdgpu_vram_mgr_vis_size(adev, block); 318 atomic64_add(vis_usage, &mgr->vis_usage); 319 spin_lock(&man->bdev->lru_lock); 320 man->usage += rsv->size; 321 spin_unlock(&man->bdev->lru_lock); 322 list_move(&rsv->blocks, &mgr->reserved_pages); 323 } 324 } 325 326 /** 327 * amdgpu_vram_mgr_reserve_range - Reserve a range from VRAM 328 * 329 * @mgr: amdgpu_vram_mgr pointer 330 * @start: start address of the range in VRAM 331 * @size: size of the range 332 * 333 * Reserve memory from start address with the specified size in VRAM 334 */ 335 int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr *mgr, 336 uint64_t start, uint64_t size) 337 { 338 struct amdgpu_vram_reservation *rsv; 339 340 rsv = kzalloc(sizeof(*rsv), GFP_KERNEL); 341 if (!rsv) 342 return -ENOMEM; 343 344 INIT_LIST_HEAD(&rsv->allocated); 345 INIT_LIST_HEAD(&rsv->blocks); 346 347 rsv->start = start; 348 rsv->size = size; 349 350 mutex_lock(&mgr->lock); 351 list_add_tail(&rsv->blocks, &mgr->reservations_pending); 352 amdgpu_vram_mgr_do_reserve(&mgr->manager); 353 mutex_unlock(&mgr->lock); 354 355 return 0; 356 } 357 358 /** 359 * amdgpu_vram_mgr_query_page_status - query the reservation status 360 * 361 * @mgr: amdgpu_vram_mgr pointer 362 * @start: start address of a page in VRAM 363 * 364 * Returns: 365 * -EBUSY: the page is still hold and in pending list 366 * 0: the page has been reserved 367 * -ENOENT: the input page is not a reservation 368 */ 369 int amdgpu_vram_mgr_query_page_status(struct amdgpu_vram_mgr *mgr, 370 uint64_t start) 371 { 372 struct amdgpu_vram_reservation *rsv; 373 int ret; 374 375 mutex_lock(&mgr->lock); 376 377 list_for_each_entry(rsv, &mgr->reservations_pending, blocks) { 378 if (rsv->start <= start && 379 (start < (rsv->start + rsv->size))) { 380 ret = -EBUSY; 381 goto out; 382 } 383 } 384 385 list_for_each_entry(rsv, &mgr->reserved_pages, blocks) { 386 if (rsv->start <= start && 387 (start < (rsv->start + rsv->size))) { 388 ret = 0; 389 goto out; 390 } 391 } 392 393 ret = -ENOENT; 394 out: 395 mutex_unlock(&mgr->lock); 396 return ret; 397 } 398 399 static void amdgpu_dummy_vram_mgr_debug(struct ttm_resource_manager *man, 400 struct drm_printer *printer) 401 { 402 DRM_DEBUG_DRIVER("Dummy vram mgr debug\n"); 403 } 404 405 static bool amdgpu_dummy_vram_mgr_compatible(struct ttm_resource_manager *man, 406 struct ttm_resource *res, 407 const struct ttm_place *place, 408 size_t size) 409 { 410 DRM_DEBUG_DRIVER("Dummy vram mgr compatible\n"); 411 return false; 412 } 413 414 static bool amdgpu_dummy_vram_mgr_intersects(struct ttm_resource_manager *man, 415 struct ttm_resource *res, 416 const struct ttm_place *place, 417 size_t size) 418 { 419 DRM_DEBUG_DRIVER("Dummy vram mgr intersects\n"); 420 return true; 421 } 422 423 static void amdgpu_dummy_vram_mgr_del(struct ttm_resource_manager *man, 424 struct ttm_resource *res) 425 { 426 DRM_DEBUG_DRIVER("Dummy vram mgr deleted\n"); 427 } 428 429 static int amdgpu_dummy_vram_mgr_new(struct ttm_resource_manager *man, 430 struct ttm_buffer_object *tbo, 431 const struct ttm_place *place, 432 struct ttm_resource **res) 433 { 434 DRM_DEBUG_DRIVER("Dummy vram mgr new\n"); 435 return -ENOSPC; 436 } 437 438 /** 439 * amdgpu_vram_mgr_new - allocate new ranges 440 * 441 * @man: TTM memory type manager 442 * @tbo: TTM BO we need this range for 443 * @place: placement flags and restrictions 444 * @res: the resulting mem object 445 * 446 * Allocate VRAM for the given BO. 447 */ 448 static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man, 449 struct ttm_buffer_object *tbo, 450 const struct ttm_place *place, 451 struct ttm_resource **res) 452 { 453 struct amdgpu_vram_mgr *mgr = to_vram_mgr(man); 454 struct amdgpu_device *adev = to_amdgpu_device(mgr); 455 struct amdgpu_bo *bo = ttm_to_amdgpu_bo(tbo); 456 u64 vis_usage = 0, max_bytes, min_block_size; 457 struct amdgpu_vram_mgr_resource *vres; 458 u64 size, remaining_size, lpfn, fpfn; 459 struct drm_buddy *mm = &mgr->mm; 460 struct drm_buddy_block *block; 461 unsigned long pages_per_block; 462 int r; 463 464 lpfn = (u64)place->lpfn << PAGE_SHIFT; 465 if (!lpfn) 466 lpfn = man->size; 467 468 fpfn = (u64)place->fpfn << PAGE_SHIFT; 469 470 max_bytes = adev->gmc.mc_vram_size; 471 if (tbo->type != ttm_bo_type_kernel) 472 max_bytes -= AMDGPU_VM_RESERVED_VRAM; 473 474 if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS) { 475 pages_per_block = ~0ul; 476 } else { 477 #ifdef CONFIG_TRANSPARENT_HUGEPAGE 478 pages_per_block = HPAGE_PMD_NR; 479 #else 480 /* default to 2MB */ 481 pages_per_block = 2UL << (20UL - PAGE_SHIFT); 482 #endif 483 pages_per_block = max_t(u32, pages_per_block, 484 tbo->page_alignment); 485 } 486 487 vres = kzalloc(sizeof(*vres), GFP_KERNEL); 488 if (!vres) 489 return -ENOMEM; 490 491 ttm_resource_init(tbo, place, &vres->base); 492 493 /* bail out quickly if there's likely not enough VRAM for this BO */ 494 if (ttm_resource_manager_usage(man) > max_bytes) { 495 r = -ENOSPC; 496 goto error_fini; 497 } 498 499 INIT_LIST_HEAD(&vres->blocks); 500 501 if (place->flags & TTM_PL_FLAG_TOPDOWN) 502 vres->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION; 503 504 if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS) 505 vres->flags |= DRM_BUDDY_CONTIGUOUS_ALLOCATION; 506 507 if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CLEARED) 508 vres->flags |= DRM_BUDDY_CLEAR_ALLOCATION; 509 510 if (fpfn || lpfn != mgr->mm.size) 511 /* Allocate blocks in desired range */ 512 vres->flags |= DRM_BUDDY_RANGE_ALLOCATION; 513 514 remaining_size = (u64)vres->base.size; 515 516 mutex_lock(&mgr->lock); 517 while (remaining_size) { 518 if (tbo->page_alignment) 519 min_block_size = (u64)tbo->page_alignment << PAGE_SHIFT; 520 else 521 min_block_size = mgr->default_page_size; 522 523 size = remaining_size; 524 if ((size >= (u64)pages_per_block << PAGE_SHIFT) && 525 !(size & (((u64)pages_per_block << PAGE_SHIFT) - 1))) 526 min_block_size = (u64)pages_per_block << PAGE_SHIFT; 527 528 BUG_ON(min_block_size < mm->chunk_size); 529 530 r = drm_buddy_alloc_blocks(mm, fpfn, 531 lpfn, 532 size, 533 min_block_size, 534 &vres->blocks, 535 vres->flags); 536 537 if (unlikely(r == -ENOSPC) && pages_per_block == ~0ul && 538 !(place->flags & TTM_PL_FLAG_CONTIGUOUS)) { 539 vres->flags &= ~DRM_BUDDY_CONTIGUOUS_ALLOCATION; 540 pages_per_block = max_t(u32, 2UL << (20UL - PAGE_SHIFT), 541 tbo->page_alignment); 542 543 continue; 544 } 545 546 if (unlikely(r)) 547 goto error_free_blocks; 548 549 if (size > remaining_size) 550 remaining_size = 0; 551 else 552 remaining_size -= size; 553 } 554 mutex_unlock(&mgr->lock); 555 556 vres->base.start = 0; 557 size = max_t(u64, amdgpu_vram_mgr_blocks_size(&vres->blocks), 558 vres->base.size); 559 list_for_each_entry(block, &vres->blocks, link) { 560 unsigned long start; 561 562 start = amdgpu_vram_mgr_block_start(block) + 563 amdgpu_vram_mgr_block_size(block); 564 start >>= PAGE_SHIFT; 565 566 if (start > PFN_UP(size)) 567 start -= PFN_UP(size); 568 else 569 start = 0; 570 vres->base.start = max(vres->base.start, start); 571 572 vis_usage += amdgpu_vram_mgr_vis_size(adev, block); 573 } 574 575 if (amdgpu_is_vram_mgr_blocks_contiguous(&vres->blocks)) 576 vres->base.placement |= TTM_PL_FLAG_CONTIGUOUS; 577 578 if (adev->gmc.xgmi.connected_to_cpu) 579 vres->base.bus.caching = ttm_cached; 580 else 581 vres->base.bus.caching = ttm_write_combined; 582 583 atomic64_add(vis_usage, &mgr->vis_usage); 584 *res = &vres->base; 585 return 0; 586 587 error_free_blocks: 588 drm_buddy_free_list(mm, &vres->blocks, 0); 589 mutex_unlock(&mgr->lock); 590 error_fini: 591 ttm_resource_fini(man, &vres->base); 592 kfree(vres); 593 594 return r; 595 } 596 597 /** 598 * amdgpu_vram_mgr_del - free ranges 599 * 600 * @man: TTM memory type manager 601 * @res: TTM memory object 602 * 603 * Free the allocated VRAM again. 604 */ 605 static void amdgpu_vram_mgr_del(struct ttm_resource_manager *man, 606 struct ttm_resource *res) 607 { 608 struct amdgpu_vram_mgr_resource *vres = to_amdgpu_vram_mgr_resource(res); 609 struct amdgpu_vram_mgr *mgr = to_vram_mgr(man); 610 struct amdgpu_device *adev = to_amdgpu_device(mgr); 611 struct drm_buddy *mm = &mgr->mm; 612 struct drm_buddy_block *block; 613 uint64_t vis_usage = 0; 614 615 mutex_lock(&mgr->lock); 616 list_for_each_entry(block, &vres->blocks, link) 617 vis_usage += amdgpu_vram_mgr_vis_size(adev, block); 618 619 amdgpu_vram_mgr_do_reserve(man); 620 621 drm_buddy_free_list(mm, &vres->blocks, vres->flags); 622 mutex_unlock(&mgr->lock); 623 624 atomic64_sub(vis_usage, &mgr->vis_usage); 625 626 ttm_resource_fini(man, res); 627 kfree(vres); 628 } 629 630 /** 631 * amdgpu_vram_mgr_alloc_sgt - allocate and fill a sg table 632 * 633 * @adev: amdgpu device pointer 634 * @res: TTM memory object 635 * @offset: byte offset from the base of VRAM BO 636 * @length: number of bytes to export in sg_table 637 * @dev: the other device 638 * @dir: dma direction 639 * @sgt: resulting sg table 640 * 641 * Allocate and fill a sg table from a VRAM allocation. 642 */ 643 int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev, 644 struct ttm_resource *res, 645 u64 offset, u64 length, 646 struct device *dev, 647 enum dma_data_direction dir, 648 struct sg_table **sgt) 649 { 650 struct amdgpu_res_cursor cursor; 651 struct scatterlist *sg; 652 int num_entries = 0; 653 int i, r; 654 655 *sgt = kmalloc(sizeof(**sgt), GFP_KERNEL); 656 if (!*sgt) 657 return -ENOMEM; 658 659 /* Determine the number of DRM_BUDDY blocks to export */ 660 amdgpu_res_first(res, offset, length, &cursor); 661 while (cursor.remaining) { 662 num_entries++; 663 amdgpu_res_next(&cursor, min(cursor.size, AMDGPU_MAX_SG_SEGMENT_SIZE)); 664 } 665 666 r = sg_alloc_table(*sgt, num_entries, GFP_KERNEL); 667 if (r) 668 goto error_free; 669 670 /* Initialize scatterlist nodes of sg_table */ 671 for_each_sgtable_sg((*sgt), sg, i) 672 sg->length = 0; 673 674 /* 675 * Walk down DRM_BUDDY blocks to populate scatterlist nodes 676 * @note: Use iterator api to get first the DRM_BUDDY block 677 * and the number of bytes from it. Access the following 678 * DRM_BUDDY block(s) if more buffer needs to exported 679 */ 680 amdgpu_res_first(res, offset, length, &cursor); 681 for_each_sgtable_sg((*sgt), sg, i) { 682 phys_addr_t phys = cursor.start + adev->gmc.aper_base; 683 unsigned long size = min(cursor.size, AMDGPU_MAX_SG_SEGMENT_SIZE); 684 dma_addr_t addr; 685 686 addr = dma_map_resource(dev, phys, size, dir, 687 DMA_ATTR_SKIP_CPU_SYNC); 688 r = dma_mapping_error(dev, addr); 689 if (r) 690 goto error_unmap; 691 692 sg_set_page(sg, NULL, size, 0); 693 sg_dma_address(sg) = addr; 694 sg_dma_len(sg) = size; 695 696 amdgpu_res_next(&cursor, size); 697 } 698 699 return 0; 700 701 error_unmap: 702 for_each_sgtable_sg((*sgt), sg, i) { 703 if (!sg->length) 704 continue; 705 706 dma_unmap_resource(dev, sg->dma_address, 707 sg->length, dir, 708 DMA_ATTR_SKIP_CPU_SYNC); 709 } 710 sg_free_table(*sgt); 711 712 error_free: 713 kfree(*sgt); 714 return r; 715 } 716 717 /** 718 * amdgpu_vram_mgr_free_sgt - allocate and fill a sg table 719 * 720 * @dev: device pointer 721 * @dir: data direction of resource to unmap 722 * @sgt: sg table to free 723 * 724 * Free a previously allocate sg table. 725 */ 726 void amdgpu_vram_mgr_free_sgt(struct device *dev, 727 enum dma_data_direction dir, 728 struct sg_table *sgt) 729 { 730 struct scatterlist *sg; 731 int i; 732 733 for_each_sgtable_sg(sgt, sg, i) 734 dma_unmap_resource(dev, sg->dma_address, 735 sg->length, dir, 736 DMA_ATTR_SKIP_CPU_SYNC); 737 sg_free_table(sgt); 738 kfree(sgt); 739 } 740 741 /** 742 * amdgpu_vram_mgr_vis_usage - how many bytes are used in the visible part 743 * 744 * @mgr: amdgpu_vram_mgr pointer 745 * 746 * Returns how many bytes are used in the visible part of VRAM 747 */ 748 uint64_t amdgpu_vram_mgr_vis_usage(struct amdgpu_vram_mgr *mgr) 749 { 750 return atomic64_read(&mgr->vis_usage); 751 } 752 753 /** 754 * amdgpu_vram_mgr_intersects - test each drm buddy block for intersection 755 * 756 * @man: TTM memory type manager 757 * @res: The resource to test 758 * @place: The place to test against 759 * @size: Size of the new allocation 760 * 761 * Test each drm buddy block for intersection for eviction decision. 762 */ 763 static bool amdgpu_vram_mgr_intersects(struct ttm_resource_manager *man, 764 struct ttm_resource *res, 765 const struct ttm_place *place, 766 size_t size) 767 { 768 struct amdgpu_vram_mgr_resource *mgr = to_amdgpu_vram_mgr_resource(res); 769 struct drm_buddy_block *block; 770 771 /* Check each drm buddy block individually */ 772 list_for_each_entry(block, &mgr->blocks, link) { 773 unsigned long fpfn = 774 amdgpu_vram_mgr_block_start(block) >> PAGE_SHIFT; 775 unsigned long lpfn = fpfn + 776 (amdgpu_vram_mgr_block_size(block) >> PAGE_SHIFT); 777 778 if (place->fpfn < lpfn && 779 (!place->lpfn || place->lpfn > fpfn)) 780 return true; 781 } 782 783 return false; 784 } 785 786 /** 787 * amdgpu_vram_mgr_compatible - test each drm buddy block for compatibility 788 * 789 * @man: TTM memory type manager 790 * @res: The resource to test 791 * @place: The place to test against 792 * @size: Size of the new allocation 793 * 794 * Test each drm buddy block for placement compatibility. 795 */ 796 static bool amdgpu_vram_mgr_compatible(struct ttm_resource_manager *man, 797 struct ttm_resource *res, 798 const struct ttm_place *place, 799 size_t size) 800 { 801 struct amdgpu_vram_mgr_resource *mgr = to_amdgpu_vram_mgr_resource(res); 802 struct drm_buddy_block *block; 803 804 /* Check each drm buddy block individually */ 805 list_for_each_entry(block, &mgr->blocks, link) { 806 unsigned long fpfn = 807 amdgpu_vram_mgr_block_start(block) >> PAGE_SHIFT; 808 unsigned long lpfn = fpfn + 809 (amdgpu_vram_mgr_block_size(block) >> PAGE_SHIFT); 810 811 if (fpfn < place->fpfn || 812 (place->lpfn && lpfn > place->lpfn)) 813 return false; 814 } 815 816 return true; 817 } 818 819 /** 820 * amdgpu_vram_mgr_debug - dump VRAM table 821 * 822 * @man: TTM memory type manager 823 * @printer: DRM printer to use 824 * 825 * Dump the table content using printk. 826 */ 827 static void amdgpu_vram_mgr_debug(struct ttm_resource_manager *man, 828 struct drm_printer *printer) 829 { 830 struct amdgpu_vram_mgr *mgr = to_vram_mgr(man); 831 struct drm_buddy *mm = &mgr->mm; 832 struct amdgpu_vram_reservation *rsv; 833 834 drm_printf(printer, " vis usage:%llu\n", 835 amdgpu_vram_mgr_vis_usage(mgr)); 836 837 mutex_lock(&mgr->lock); 838 drm_printf(printer, "default_page_size: %lluKiB\n", 839 mgr->default_page_size >> 10); 840 841 drm_buddy_print(mm, printer); 842 843 drm_printf(printer, "reserved:\n"); 844 list_for_each_entry(rsv, &mgr->reserved_pages, blocks) 845 drm_printf(printer, "%#018llx-%#018llx: %llu\n", 846 rsv->start, rsv->start + rsv->size, rsv->size); 847 mutex_unlock(&mgr->lock); 848 } 849 850 static const struct ttm_resource_manager_func amdgpu_dummy_vram_mgr_func = { 851 .alloc = amdgpu_dummy_vram_mgr_new, 852 .free = amdgpu_dummy_vram_mgr_del, 853 .intersects = amdgpu_dummy_vram_mgr_intersects, 854 .compatible = amdgpu_dummy_vram_mgr_compatible, 855 .debug = amdgpu_dummy_vram_mgr_debug 856 }; 857 858 static const struct ttm_resource_manager_func amdgpu_vram_mgr_func = { 859 .alloc = amdgpu_vram_mgr_new, 860 .free = amdgpu_vram_mgr_del, 861 .intersects = amdgpu_vram_mgr_intersects, 862 .compatible = amdgpu_vram_mgr_compatible, 863 .debug = amdgpu_vram_mgr_debug 864 }; 865 866 /** 867 * amdgpu_vram_mgr_init - init VRAM manager and DRM MM 868 * 869 * @adev: amdgpu_device pointer 870 * 871 * Allocate and initialize the VRAM manager. 872 */ 873 int amdgpu_vram_mgr_init(struct amdgpu_device *adev) 874 { 875 struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr; 876 struct ttm_resource_manager *man = &mgr->manager; 877 int err; 878 879 ttm_resource_manager_init(man, &adev->mman.bdev, 880 adev->gmc.real_vram_size); 881 882 mutex_init(&mgr->lock); 883 INIT_LIST_HEAD(&mgr->reservations_pending); 884 INIT_LIST_HEAD(&mgr->reserved_pages); 885 mgr->default_page_size = PAGE_SIZE; 886 887 if (!adev->gmc.is_app_apu) { 888 man->func = &amdgpu_vram_mgr_func; 889 890 err = drm_buddy_init(&mgr->mm, man->size, PAGE_SIZE); 891 if (err) 892 return err; 893 } else { 894 man->func = &amdgpu_dummy_vram_mgr_func; 895 DRM_INFO("Setup dummy vram mgr\n"); 896 } 897 898 ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_VRAM, &mgr->manager); 899 ttm_resource_manager_set_used(man, true); 900 return 0; 901 } 902 903 /** 904 * amdgpu_vram_mgr_fini - free and destroy VRAM manager 905 * 906 * @adev: amdgpu_device pointer 907 * 908 * Destroy and free the VRAM manager, returns -EBUSY if ranges are still 909 * allocated inside it. 910 */ 911 void amdgpu_vram_mgr_fini(struct amdgpu_device *adev) 912 { 913 struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr; 914 struct ttm_resource_manager *man = &mgr->manager; 915 int ret; 916 struct amdgpu_vram_reservation *rsv, *temp; 917 918 ttm_resource_manager_set_used(man, false); 919 920 ret = ttm_resource_manager_evict_all(&adev->mman.bdev, man); 921 if (ret) 922 return; 923 924 mutex_lock(&mgr->lock); 925 list_for_each_entry_safe(rsv, temp, &mgr->reservations_pending, blocks) 926 kfree(rsv); 927 928 list_for_each_entry_safe(rsv, temp, &mgr->reserved_pages, blocks) { 929 drm_buddy_free_list(&mgr->mm, &rsv->allocated, 0); 930 kfree(rsv); 931 } 932 if (!adev->gmc.is_app_apu) 933 drm_buddy_fini(&mgr->mm); 934 mutex_unlock(&mgr->lock); 935 936 ttm_resource_manager_cleanup(man); 937 ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_VRAM, NULL); 938 } 939