diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 157 |
1 files changed, 106 insertions, 51 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index eeaa56c8d129..b4ab309bf08a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -163,7 +163,8 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo, } static struct dma_fence * -amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_job *job, u32 num_dw) +amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_ttm_buffer_entity *entity, + struct amdgpu_job *job, u32 num_dw) { struct amdgpu_ring *ring; @@ -171,6 +172,8 @@ amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_job *job, u32 nu amdgpu_ring_pad_ib(ring, &job->ibs[0]); WARN_ON(job->ibs[0].length_dw > num_dw); + lockdep_assert_held(&entity->lock); + return amdgpu_job_submit(job); } @@ -228,9 +231,7 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity, *size = min(*size, (uint64_t)num_pages * PAGE_SIZE - offset); - *addr = adev->gmc.gart_start; - *addr += (u64)window * AMDGPU_GTT_MAX_TRANSFER_SIZE * - AMDGPU_GPU_PAGE_SIZE; + *addr = amdgpu_compute_gart_address(&adev->gmc, entity, window); *addr += offset; num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8); @@ -248,7 +249,7 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity, src_addr += job->ibs[0].gpu_addr; dst_addr = amdgpu_bo_gpu_offset(adev->gart.bo); - dst_addr += window * AMDGPU_GTT_MAX_TRANSFER_SIZE * 8; + dst_addr += (entity->gart_window_offs[window] >> AMDGPU_GPU_PAGE_SHIFT) * 8; amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr, dst_addr, num_bytes, 0); @@ -269,7 +270,7 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity, amdgpu_gart_map_vram_range(adev, pa, 0, num_pages, flags, cpu_addr); } - dma_fence_put(amdgpu_ttm_job_submit(adev, job, num_dw)); + dma_fence_put(amdgpu_ttm_job_submit(adev, entity, job, num_dw)); return 0; } @@ -313,7 +314,7 @@ static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev, amdgpu_res_first(src->mem, src->offset, size, &src_mm); amdgpu_res_first(dst->mem, dst->offset, size, &dst_mm); - mutex_lock(&adev->mman.gtt_window_lock); + mutex_lock(&entity->lock); while (src_mm.remaining) { uint64_t from, to, cur_size, tiling_flags; uint32_t num_type, data_format, max_com, write_compress_disable; @@ -368,7 +369,7 @@ static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev, amdgpu_res_next(&dst_mm, cur_size); } error: - mutex_unlock(&adev->mman.gtt_window_lock); + mutex_unlock(&entity->lock); *f = fence; return r; } @@ -1580,7 +1581,7 @@ static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo, if (r) goto out; - mutex_lock(&adev->mman.gtt_window_lock); + mutex_lock(&adev->mman.default_entity.lock); amdgpu_res_first(abo->tbo.resource, offset, len, &src_mm); src_addr = amdgpu_ttm_domain_start(adev, bo->resource->mem_type) + src_mm.start; @@ -1591,8 +1592,8 @@ static int amdgpu_ttm_access_memory_sdma(struct ttm_buffer_object *bo, amdgpu_emit_copy_buffer(adev, &job->ibs[0], src_addr, dst_addr, PAGE_SIZE, 0); - fence = amdgpu_ttm_job_submit(adev, job, num_dw); - mutex_unlock(&adev->mman.gtt_window_lock); + fence = amdgpu_ttm_job_submit(adev, &adev->mman.default_entity, job, num_dw); + mutex_unlock(&adev->mman.default_entity.lock); if (!dma_fence_wait_timeout(fence, false, adev->sdma_timeout)) r = -ETIMEDOUT; @@ -1908,7 +1909,7 @@ static void amdgpu_ttm_pools_fini(struct amdgpu_device *adev) } /** - * amdgpu_ttm_mmio_remap_bo_init - Allocate the singleton MMIO_REMAP BO + * amdgpu_ttm_alloc_mmio_remap_bo - Allocate the singleton MMIO_REMAP BO * @adev: amdgpu device * * Allocates a global BO with backing AMDGPU_PL_MMIO_REMAP when the @@ -2013,6 +2014,50 @@ static void amdgpu_ttm_free_mmio_remap_bo(struct amdgpu_device *adev) adev->rmmio_remap.bo = NULL; } +static int amdgpu_ttm_buffer_entity_init(struct amdgpu_gtt_mgr *mgr, + struct amdgpu_ttm_buffer_entity *entity, + enum drm_sched_priority prio, + struct drm_gpu_scheduler **scheds, + int num_schedulers, + u32 num_gart_windows) +{ + int i, r, num_pages; + + r = drm_sched_entity_init(&entity->base, prio, scheds, num_schedulers, NULL); + if (r) + return r; + + mutex_init(&entity->lock); + + if (ARRAY_SIZE(entity->gart_window_offs) < num_gart_windows) + return -EINVAL; + if (num_gart_windows == 0) + return 0; + + num_pages = num_gart_windows * AMDGPU_GTT_MAX_TRANSFER_SIZE; + r = amdgpu_gtt_mgr_alloc_entries(mgr, &entity->gart_node, num_pages, + DRM_MM_INSERT_BEST); + if (r) { + drm_sched_entity_destroy(&entity->base); + return r; + } + + for (i = 0; i < num_gart_windows; i++) { + entity->gart_window_offs[i] = + amdgpu_gtt_node_to_byte_offset(&entity->gart_node) + + i * AMDGPU_GTT_MAX_TRANSFER_SIZE * PAGE_SIZE; + } + + return 0; +} + +static void amdgpu_ttm_buffer_entity_fini(struct amdgpu_gtt_mgr *mgr, + struct amdgpu_ttm_buffer_entity *entity) +{ + amdgpu_gtt_mgr_free_entries(mgr, &entity->gart_node); + drm_sched_entity_destroy(&entity->base); +} + /* * amdgpu_ttm_init - Init the memory management (ttm) as well as various * gtt/vram related fields. @@ -2027,8 +2072,6 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) uint64_t gtt_size; int r; - mutex_init(&adev->mman.gtt_window_lock); - dma_set_max_seg_size(adev->dev, UINT_MAX); /* No others user of address space so set it to 0 */ r = ttm_device_init(&adev->mman.bdev, &amdgpu_bo_driver, adev->dev, @@ -2313,42 +2356,49 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable) struct amdgpu_ring *ring; struct drm_gpu_scheduler *sched; + if (!adev->mman.buffer_funcs_ring || !adev->mman.buffer_funcs_ring->sched.ready) { + dev_warn(adev->dev, "Not enabling DMA transfers for in kernel use"); + return; + } + ring = adev->mman.buffer_funcs_ring; sched = &ring->sched; - r = drm_sched_entity_init(&adev->mman.default_entity.base, - DRM_SCHED_PRIORITY_KERNEL, &sched, - 1, NULL); - if (r) { + r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr, + &adev->mman.default_entity, + DRM_SCHED_PRIORITY_KERNEL, + &sched, 1, 0); + if (r < 0) { dev_err(adev->dev, - "Failed setting up TTM BO move entity (%d)\n", - r); + "Failed setting up TTM entity (%d)\n", r); return; } - r = drm_sched_entity_init(&adev->mman.clear_entity.base, - DRM_SCHED_PRIORITY_NORMAL, &sched, - 1, NULL); - if (r) { + r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr, + &adev->mman.clear_entity, + DRM_SCHED_PRIORITY_NORMAL, + &sched, 1, 1); + if (r < 0) { dev_err(adev->dev, - "Failed setting up TTM BO clear entity (%d)\n", - r); - goto error_free_entity; + "Failed setting up TTM BO clear entity (%d)\n", r); + goto error_free_default_entity; } - r = drm_sched_entity_init(&adev->mman.move_entity.base, - DRM_SCHED_PRIORITY_NORMAL, &sched, - 1, NULL); - if (r) { + r = amdgpu_ttm_buffer_entity_init(&adev->mman.gtt_mgr, + &adev->mman.move_entity, + DRM_SCHED_PRIORITY_NORMAL, + &sched, 1, 2); + if (r < 0) { dev_err(adev->dev, - "Failed setting up TTM BO move entity (%d)\n", - r); - drm_sched_entity_destroy(&adev->mman.clear_entity.base); - goto error_free_entity; + "Failed setting up TTM BO move entity (%d)\n", r); + goto error_free_clear_entity; } } else { - drm_sched_entity_destroy(&adev->mman.default_entity.base); - drm_sched_entity_destroy(&adev->mman.clear_entity.base); - drm_sched_entity_destroy(&adev->mman.move_entity.base); + amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr, + &adev->mman.default_entity); + amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr, + &adev->mman.clear_entity); + amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr, + &adev->mman.move_entity); /* Drop all the old fences since re-creating the scheduler entities * will allocate new contexts. */ @@ -2365,8 +2415,12 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable) return; -error_free_entity: - drm_sched_entity_destroy(&adev->mman.default_entity.base); +error_free_clear_entity: + amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr, + &adev->mman.clear_entity); +error_free_default_entity: + amdgpu_ttm_buffer_entity_fini(&adev->mman.gtt_mgr, + &adev->mman.default_entity); } static int amdgpu_ttm_prepare_job(struct amdgpu_device *adev, @@ -2440,7 +2494,7 @@ int amdgpu_copy_buffer(struct amdgpu_device *adev, byte_count -= cur_size_in_bytes; } - *fence = amdgpu_ttm_job_submit(adev, job, num_dw); + *fence = amdgpu_ttm_job_submit(adev, entity, job, num_dw); return 0; @@ -2483,7 +2537,7 @@ static int amdgpu_ttm_fill_mem(struct amdgpu_device *adev, byte_count -= cur_size; } - *fence = amdgpu_ttm_job_submit(adev, job, num_dw); + *fence = amdgpu_ttm_job_submit(adev, entity, job, num_dw); return 0; } @@ -2503,6 +2557,7 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo, struct dma_fence **fence) { struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); + struct amdgpu_ttm_buffer_entity *entity; struct amdgpu_res_cursor cursor; u64 addr; int r = 0; @@ -2513,11 +2568,12 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo, if (!fence) return -EINVAL; + entity = &adev->mman.clear_entity; *fence = dma_fence_get_stub(); amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor); - mutex_lock(&adev->mman.gtt_window_lock); + mutex_lock(&entity->lock); while (cursor.remaining) { struct dma_fence *next = NULL; u64 size; @@ -2530,13 +2586,12 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo, /* Never clear more than 256MiB at once to avoid timeouts */ size = min(cursor.size, 256ULL << 20); - r = amdgpu_ttm_map_buffer(&adev->mman.clear_entity, - &bo->tbo, bo->tbo.resource, &cursor, - 1, false, &size, &addr); + r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &cursor, + 0, false, &size, &addr); if (r) goto err; - r = amdgpu_ttm_fill_mem(adev, &adev->mman.clear_entity, 0, addr, size, resv, + r = amdgpu_ttm_fill_mem(adev, entity, 0, addr, size, resv, &next, true, AMDGPU_KERNEL_JOB_ID_TTM_CLEAR_BUFFER); if (r) @@ -2548,7 +2603,7 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo, amdgpu_res_next(&cursor, size); } err: - mutex_unlock(&adev->mman.gtt_window_lock); + mutex_unlock(&entity->lock); return r; } @@ -2573,7 +2628,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity, amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &dst); - mutex_lock(&adev->mman.gtt_window_lock); + mutex_lock(&entity->lock); while (dst.remaining) { struct dma_fence *next; uint64_t cur_size, to; @@ -2582,7 +2637,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity, cur_size = min(dst.size, 256ULL << 20); r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &dst, - 1, false, &cur_size, &to); + 0, false, &cur_size, &to); if (r) goto error; @@ -2598,7 +2653,7 @@ int amdgpu_fill_buffer(struct amdgpu_ttm_buffer_entity *entity, amdgpu_res_next(&dst, cur_size); } error: - mutex_unlock(&adev->mman.gtt_window_lock); + mutex_unlock(&entity->lock); if (f) *f = dma_fence_get(fence); dma_fence_put(fence); |
