Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amdgpu: add UMA allocation interfaces to sysfs

Add a uma/ directory containing two sysfs files as interfaces to
inspect or change UMA carveout size. These files are:

- uma/carveout_options: a read-only file listing all the available
UMA allocation options and their index.

- uma/carveout: a file that is both readable and writable. On read,
it shows the index of the current setting. Writing a valid index
into this file allows users to change the UMA carveout size to that
option on the next boot.

Co-developed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Mario Limonciello (AMD) <superm1@kernel.org>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Yo-Jung Leo Lin (AMD) <Leo.Lin@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Yo-Jung Leo Lin (AMD) and committed by
Alex Deucher
19ba61ac 379a3160

+143
+143
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
··· 36 36 #include <linux/pci.h> 37 37 #include <linux/pci-p2pdma.h> 38 38 #include <linux/apple-gmux.h> 39 + #include <linux/nospec.h> 39 40 40 41 #include <drm/drm_atomic_helper.h> 41 42 #include <drm/drm_client_event.h> ··· 381 380 .attrs = amdgpu_board_attrs, 382 381 .is_visible = amdgpu_board_attrs_is_visible 383 382 }; 383 + 384 + static ssize_t carveout_options_show(struct device *dev, 385 + struct device_attribute *attr, 386 + char *buf) 387 + { 388 + struct drm_device *ddev = dev_get_drvdata(dev); 389 + struct amdgpu_device *adev = drm_to_adev(ddev); 390 + struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info; 391 + uint32_t memory_carved; 392 + ssize_t size = 0; 393 + 394 + if (!uma_info || !uma_info->num_entries) 395 + return -ENODEV; 396 + 397 + for (int i = 0; i < uma_info->num_entries; i++) { 398 + memory_carved = uma_info->entries[i].memory_carved_mb; 399 + if (memory_carved >= SZ_1G/SZ_1M) { 400 + size += sysfs_emit_at(buf, size, "%d: %s (%u GB)\n", 401 + i, 402 + uma_info->entries[i].name, 403 + memory_carved >> 10); 404 + } else { 405 + size += sysfs_emit_at(buf, size, "%d: %s (%u MB)\n", 406 + i, 407 + uma_info->entries[i].name, 408 + memory_carved); 409 + } 410 + } 411 + 412 + return size; 413 + } 414 + static DEVICE_ATTR_RO(carveout_options); 415 + 416 + static ssize_t carveout_show(struct device *dev, 417 + struct device_attribute *attr, 418 + char *buf) 419 + { 420 + struct drm_device *ddev = dev_get_drvdata(dev); 421 + struct amdgpu_device *adev = drm_to_adev(ddev); 422 + 423 + return sysfs_emit(buf, "%u\n", adev->uma_info.uma_option_index); 424 + } 425 + 426 + static ssize_t carveout_store(struct device *dev, 427 + struct device_attribute *attr, 428 + const char *buf, size_t count) 429 + { 430 + struct drm_device *ddev = dev_get_drvdata(dev); 431 + struct amdgpu_device *adev = drm_to_adev(ddev); 432 + struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info; 433 + struct amdgpu_uma_carveout_option *opt; 434 + unsigned long val; 435 + uint8_t flags; 436 + int r; 437 + 438 + r = kstrtoul(buf, 10, &val); 439 + if (r) 440 + return r; 441 + 442 + if (val >= uma_info->num_entries) 443 + return -EINVAL; 444 + 445 + val = array_index_nospec(val, uma_info->num_entries); 446 + opt = &uma_info->entries[val]; 447 + 448 + if (!(opt->flags & AMDGPU_UMA_FLAG_AUTO) && 449 + !(opt->flags & AMDGPU_UMA_FLAG_CUSTOM)) { 450 + drm_err_once(ddev, "Option %lu not supported due to lack of Custom/Auto flag", val); 451 + return -EINVAL; 452 + } 453 + 454 + flags = opt->flags; 455 + flags &= ~((flags & AMDGPU_UMA_FLAG_AUTO) >> 1); 456 + 457 + guard(mutex)(&uma_info->update_lock); 458 + 459 + r = amdgpu_acpi_set_uma_allocation_size(adev, val, flags); 460 + if (r) 461 + return r; 462 + 463 + uma_info->uma_option_index = val; 464 + 465 + return count; 466 + } 467 + static DEVICE_ATTR_RW(carveout); 468 + 469 + static struct attribute *amdgpu_uma_attrs[] = { 470 + &dev_attr_carveout.attr, 471 + &dev_attr_carveout_options.attr, 472 + NULL 473 + }; 474 + 475 + const struct attribute_group amdgpu_uma_attr_group = { 476 + .name = "uma", 477 + .attrs = amdgpu_uma_attrs 478 + }; 479 + 480 + static void amdgpu_uma_sysfs_init(struct amdgpu_device *adev) 481 + { 482 + int rc; 483 + 484 + if (!(adev->flags & AMD_IS_APU)) 485 + return; 486 + 487 + if (!amdgpu_acpi_is_set_uma_allocation_size_supported()) 488 + return; 489 + 490 + rc = amdgpu_atomfirmware_get_uma_carveout_info(adev, &adev->uma_info); 491 + if (rc) { 492 + drm_dbg(adev_to_drm(adev), 493 + "Failed to parse UMA carveout info from VBIOS: %d\n", rc); 494 + goto out_info; 495 + } 496 + 497 + mutex_init(&adev->uma_info.update_lock); 498 + 499 + rc = devm_device_add_group(adev->dev, &amdgpu_uma_attr_group); 500 + if (rc) { 501 + drm_dbg(adev_to_drm(adev), "Failed to add UMA carveout sysfs interfaces %d\n", rc); 502 + goto out_attr; 503 + } 504 + 505 + return; 506 + 507 + out_attr: 508 + mutex_destroy(&adev->uma_info.update_lock); 509 + out_info: 510 + return; 511 + } 512 + 513 + static void amdgpu_uma_sysfs_fini(struct amdgpu_device *adev) 514 + { 515 + struct amdgpu_uma_carveout_info *uma_info = &adev->uma_info; 516 + 517 + if (!amdgpu_acpi_is_set_uma_allocation_size_supported()) 518 + return; 519 + 520 + mutex_destroy(&uma_info->update_lock); 521 + uma_info->num_entries = 0; 522 + } 384 523 385 524 static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev); 386 525 ··· 4309 4168 amdgpu_fru_sysfs_init(adev); 4310 4169 amdgpu_reg_state_sysfs_init(adev); 4311 4170 amdgpu_xcp_sysfs_init(adev); 4171 + amdgpu_uma_sysfs_init(adev); 4312 4172 4313 4173 return r; 4314 4174 } ··· 4325 4183 4326 4184 amdgpu_reg_state_sysfs_fini(adev); 4327 4185 amdgpu_xcp_sysfs_fini(adev); 4186 + amdgpu_uma_sysfs_fini(adev); 4328 4187 } 4329 4188 4330 4189 /**