diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_gem.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gem.c | 65 |
1 files changed, 57 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 05ea2f39f626..458f92a70887 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -44,6 +44,42 @@ void radeon_gem_prime_unpin(struct drm_gem_object *obj); const struct drm_gem_object_funcs radeon_gem_object_funcs; +static vm_fault_t radeon_gem_fault(struct vm_fault *vmf) +{ + struct ttm_buffer_object *bo = vmf->vma->vm_private_data; + struct radeon_device *rdev = radeon_get_rdev(bo->bdev); + vm_fault_t ret; + + down_read(&rdev->pm.mclk_lock); + + ret = ttm_bo_vm_reserve(bo, vmf); + if (ret) + goto unlock_mclk; + + ret = radeon_bo_fault_reserve_notify(bo); + if (ret) + goto unlock_resv; + + ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot, + TTM_BO_VM_NUM_PREFAULT, 1); + if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) + goto unlock_mclk; + +unlock_resv: + dma_resv_unlock(bo->base.resv); + +unlock_mclk: + up_read(&rdev->pm.mclk_lock); + return ret; +} + +static const struct vm_operations_struct radeon_gem_vm_ops = { + .fault = radeon_gem_fault, + .open = ttm_bo_vm_open, + .close = ttm_bo_vm_close, + .access = ttm_bo_vm_access +}; + static void radeon_gem_object_free(struct drm_gem_object *gobj) { struct radeon_bo *robj = gem_to_radeon_bo(gobj); @@ -125,7 +161,7 @@ static int radeon_gem_set_domain(struct drm_gem_object *gobj, } if (domain == RADEON_GEM_DOMAIN_CPU) { /* Asking for cpu access wait for object idle */ - r = dma_resv_wait_timeout_rcu(robj->tbo.base.resv, true, true, 30 * HZ); + r = dma_resv_wait_timeout(robj->tbo.base.resv, true, true, 30 * HZ); if (!r) r = -EBUSY; @@ -226,6 +262,17 @@ static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r) return r; } +static int radeon_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) +{ + struct radeon_bo *bo = gem_to_radeon_bo(obj); + struct radeon_device *rdev = radeon_get_rdev(bo->tbo.bdev); + + if (radeon_ttm_tt_has_userptr(rdev, bo->tbo.ttm)) + return -EPERM; + + return drm_gem_ttm_mmap(obj, vma); +} + const struct drm_gem_object_funcs radeon_gem_object_funcs = { .free = radeon_gem_object_free, .open = radeon_gem_object_open, @@ -236,6 +283,8 @@ const struct drm_gem_object_funcs radeon_gem_object_funcs = { .get_sg_table = radeon_gem_prime_get_sg_table, .vmap = drm_gem_ttm_vmap, .vunmap = drm_gem_ttm_vunmap, + .mmap = radeon_gem_object_mmap, + .vm_ops = &radeon_gem_vm_ops, }; /* @@ -474,13 +523,13 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, } robj = gem_to_radeon_bo(gobj); - r = dma_resv_test_signaled_rcu(robj->tbo.base.resv, true); + r = dma_resv_test_signaled(robj->tbo.base.resv, true); if (r == 0) r = -EBUSY; else r = 0; - cur_placement = READ_ONCE(robj->tbo.mem.mem_type); + cur_placement = READ_ONCE(robj->tbo.resource->mem_type); args->domain = radeon_mem_type_to_domain(cur_placement); drm_gem_object_put(gobj); return r; @@ -503,14 +552,14 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, } robj = gem_to_radeon_bo(gobj); - ret = dma_resv_wait_timeout_rcu(robj->tbo.base.resv, true, true, 30 * HZ); + ret = dma_resv_wait_timeout(robj->tbo.base.resv, true, true, 30 * HZ); if (ret == 0) r = -EBUSY; else if (ret < 0) r = ret; /* Flush HDP cache via MMIO if necessary */ - cur_placement = READ_ONCE(robj->tbo.mem.mem_type); + cur_placement = READ_ONCE(robj->tbo.resource->mem_type); if (rdev->asic->mmio_hdp_flush && radeon_mem_type_to_domain(cur_placement) == RADEON_GEM_DOMAIN_VRAM) robj->rdev->asic->mmio_hdp_flush(rdev); @@ -594,7 +643,7 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, goto error_free; list_for_each_entry(entry, &list, head) { - domain = radeon_mem_type_to_domain(entry->bo->mem.mem_type); + domain = radeon_mem_type_to_domain(entry->bo->resource->mem_type); /* if anything is swapped out don't swap it in here, just abort and wait for the next CS */ if (domain == RADEON_GEM_DOMAIN_CPU) @@ -607,7 +656,7 @@ static void radeon_gem_va_update_vm(struct radeon_device *rdev, goto error_unlock; if (bo_va->it.start) - r = radeon_vm_bo_update(rdev, bo_va, &bo_va->bo->tbo.mem); + r = radeon_vm_bo_update(rdev, bo_va, bo_va->bo->tbo.resource); error_unlock: mutex_unlock(&bo_va->vm->mutex); @@ -811,7 +860,7 @@ static int radeon_debugfs_gem_info_show(struct seq_file *m, void *unused) unsigned domain; const char *placement; - domain = radeon_mem_type_to_domain(rbo->tbo.mem.mem_type); + domain = radeon_mem_type_to_domain(rbo->tbo.resource->mem_type); switch (domain) { case RADEON_GEM_DOMAIN_VRAM: placement = "VRAM"; |