diff options
author | Christian König <christian.koenig@amd.com> | 2017-09-18 07:58:30 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-10-09 16:30:18 -0400 |
commit | 9fc8fc709b356c85034cbcb3b84c9d8b77865f52 (patch) | |
tree | 728ab27d8e0919ce0952e166b85ecb38be451d53 | |
parent | 6056a1a565547743c5a87dc3d9c51d086acf9c27 (diff) |
drm/amdgpu: add VM support for huge pages v2
Convert GTT mappings into linear ones for huge page handling.
v2: use fragment size as minimum for linear conversion
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index b500bb6a8491..eb4a01c14eee 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -1699,6 +1699,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, | |||
1699 | struct drm_mm_node *nodes, | 1699 | struct drm_mm_node *nodes, |
1700 | struct dma_fence **fence) | 1700 | struct dma_fence **fence) |
1701 | { | 1701 | { |
1702 | unsigned min_linear_pages = 1 << adev->vm_manager.fragment_size; | ||
1702 | uint64_t pfn, start = mapping->start; | 1703 | uint64_t pfn, start = mapping->start; |
1703 | int r; | 1704 | int r; |
1704 | 1705 | ||
@@ -1733,6 +1734,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, | |||
1733 | } | 1734 | } |
1734 | 1735 | ||
1735 | do { | 1736 | do { |
1737 | dma_addr_t *dma_addr = NULL; | ||
1736 | uint64_t max_entries; | 1738 | uint64_t max_entries; |
1737 | uint64_t addr, last; | 1739 | uint64_t addr, last; |
1738 | 1740 | ||
@@ -1746,15 +1748,32 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, | |||
1746 | } | 1748 | } |
1747 | 1749 | ||
1748 | if (pages_addr) { | 1750 | if (pages_addr) { |
1751 | uint64_t count; | ||
1752 | |||
1749 | max_entries = min(max_entries, 16ull * 1024ull); | 1753 | max_entries = min(max_entries, 16ull * 1024ull); |
1750 | addr = 0; | 1754 | for (count = 1; count < max_entries; ++count) { |
1755 | uint64_t idx = pfn + count; | ||
1756 | |||
1757 | if (pages_addr[idx] != | ||
1758 | (pages_addr[idx - 1] + PAGE_SIZE)) | ||
1759 | break; | ||
1760 | } | ||
1761 | |||
1762 | if (count < min_linear_pages) { | ||
1763 | addr = pfn << PAGE_SHIFT; | ||
1764 | dma_addr = pages_addr; | ||
1765 | } else { | ||
1766 | addr = pages_addr[pfn]; | ||
1767 | max_entries = count; | ||
1768 | } | ||
1769 | |||
1751 | } else if (flags & AMDGPU_PTE_VALID) { | 1770 | } else if (flags & AMDGPU_PTE_VALID) { |
1752 | addr += adev->vm_manager.vram_base_offset; | 1771 | addr += adev->vm_manager.vram_base_offset; |
1772 | addr += pfn << PAGE_SHIFT; | ||
1753 | } | 1773 | } |
1754 | addr += pfn << PAGE_SHIFT; | ||
1755 | 1774 | ||
1756 | last = min((uint64_t)mapping->last, start + max_entries - 1); | 1775 | last = min((uint64_t)mapping->last, start + max_entries - 1); |
1757 | r = amdgpu_vm_bo_update_mapping(adev, exclusive, pages_addr, vm, | 1776 | r = amdgpu_vm_bo_update_mapping(adev, exclusive, dma_addr, vm, |
1758 | start, last, flags, addr, | 1777 | start, last, flags, addr, |
1759 | fence); | 1778 | fence); |
1760 | if (r) | 1779 | if (r) |