diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 116 | 
1 files changed, 42 insertions, 74 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 94cb91cf93eb..7171968f261e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -49,7 +49,6 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,  				struct drm_gem_object **obj)  {  	struct amdgpu_bo *robj; -	unsigned long max_size;  	int r;  	*obj = NULL; @@ -58,20 +57,9 @@ int amdgpu_gem_object_create(struct amdgpu_device *adev, unsigned long size,  		alignment = PAGE_SIZE;  	} -	if (!(initial_domain & (AMDGPU_GEM_DOMAIN_GDS | AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA))) { -		/* Maximum bo size is the unpinned gtt size since we use the gtt to -		 * handle vram to system pool migrations. -		 */ -		max_size = adev->mc.gtt_size - adev->gart_pin_size; -		if (size > max_size) { -			DRM_DEBUG("Allocation size %ldMb bigger than %ldMb limit\n", -				  size >> 20, max_size >> 20); -			return -ENOMEM; -		} -	}  retry:  	r = amdgpu_bo_create(adev, size, alignment, kernel, initial_domain, -			     flags, NULL, NULL, &robj); +			     flags, NULL, NULL, 0, &robj);  	if (r) {  		if (r != -ERESTARTSYS) {  			if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) { @@ -103,7 +91,7 @@ void amdgpu_gem_force_release(struct amdgpu_device *adev)  		spin_lock(&file->table_lock);  		idr_for_each_entry(&file->object_idr, gobj, handle) {  			WARN_ONCE(1, "And also active allocations!\n"); -			drm_gem_object_unreference_unlocked(gobj); +			drm_gem_object_put_unlocked(gobj);  		}  		idr_destroy(&file->object_idr);  		spin_unlock(&file->table_lock); @@ -219,16 +207,6 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj,  	ttm_eu_backoff_reservation(&ticket, &list);  } -static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r) -{ -	if (r == -EDEADLK) { -		r = amdgpu_gpu_reset(adev); -		if (!r) -			r = -EAGAIN; -	} -	return r; -} -  /*   * GEM ioctls.   */ @@ -247,22 +225,17 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,  	if (args->in.domain_flags & ~(AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |  				      AMDGPU_GEM_CREATE_NO_CPU_ACCESS |  				      AMDGPU_GEM_CREATE_CPU_GTT_USWC | -				      AMDGPU_GEM_CREATE_VRAM_CLEARED| -				      AMDGPU_GEM_CREATE_SHADOW | -				      AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)) { -		r = -EINVAL; -		goto error_unlock; -	} +				      AMDGPU_GEM_CREATE_VRAM_CLEARED)) +		return -EINVAL; +  	/* reject invalid gem domains */  	if (args->in.domains & ~(AMDGPU_GEM_DOMAIN_CPU |  				 AMDGPU_GEM_DOMAIN_GTT |  				 AMDGPU_GEM_DOMAIN_VRAM |  				 AMDGPU_GEM_DOMAIN_GDS |  				 AMDGPU_GEM_DOMAIN_GWS | -				 AMDGPU_GEM_DOMAIN_OA)) { -		r = -EINVAL; -		goto error_unlock; -	} +				 AMDGPU_GEM_DOMAIN_OA)) +		return -EINVAL;  	/* create a gem object to contain this object in */  	if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS | @@ -274,10 +247,8 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,  			size = size << AMDGPU_GWS_SHIFT;  		else if (args->in.domains == AMDGPU_GEM_DOMAIN_OA)  			size = size << AMDGPU_OA_SHIFT; -		else { -			r = -EINVAL; -			goto error_unlock; -		} +		else +			return -EINVAL;  	}  	size = roundup(size, PAGE_SIZE); @@ -286,21 +257,17 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,  				     args->in.domain_flags,  				     kernel, &gobj);  	if (r) -		goto error_unlock; +		return r;  	r = drm_gem_handle_create(filp, gobj, &handle);  	/* drop reference from allocate - handle holds it now */ -	drm_gem_object_unreference_unlocked(gobj); +	drm_gem_object_put_unlocked(gobj);  	if (r) -		goto error_unlock; +		return r;  	memset(args, 0, sizeof(*args));  	args->out.handle = handle;  	return 0; - -error_unlock: -	r = amdgpu_gem_handle_lockup(adev, r); -	return r;  }  int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, @@ -334,10 +301,10 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,  				     AMDGPU_GEM_DOMAIN_CPU, 0,  				     0, &gobj);  	if (r) -		goto handle_lockup; +		return r;  	bo = gem_to_amdgpu_bo(gobj); -	bo->prefered_domains = AMDGPU_GEM_DOMAIN_GTT; +	bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT;  	bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;  	r = amdgpu_ttm_tt_set_userptr(bo->tbo.ttm, args->addr, args->flags);  	if (r) @@ -372,9 +339,9 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,  	r = drm_gem_handle_create(filp, gobj, &handle);  	/* drop reference from allocate - handle holds it now */ -	drm_gem_object_unreference_unlocked(gobj); +	drm_gem_object_put_unlocked(gobj);  	if (r) -		goto handle_lockup; +		return r;  	args->handle = handle;  	return 0; @@ -386,10 +353,7 @@ unlock_mmap_sem:  	up_read(¤t->mm->mmap_sem);  release_object: -	drm_gem_object_unreference_unlocked(gobj); - -handle_lockup: -	r = amdgpu_gem_handle_lockup(adev, r); +	drm_gem_object_put_unlocked(gobj);  	return r;  } @@ -408,11 +372,11 @@ int amdgpu_mode_dumb_mmap(struct drm_file *filp,  	robj = gem_to_amdgpu_bo(gobj);  	if (amdgpu_ttm_tt_get_usermm(robj->tbo.ttm) ||  	    (robj->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)) { -		drm_gem_object_unreference_unlocked(gobj); +		drm_gem_object_put_unlocked(gobj);  		return -EPERM;  	}  	*offset_p = amdgpu_bo_mmap_offset(robj); -	drm_gem_object_unreference_unlocked(gobj); +	drm_gem_object_put_unlocked(gobj);  	return 0;  } @@ -456,7 +420,6 @@ unsigned long amdgpu_gem_timeout(uint64_t timeout_ns)  int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data,  			      struct drm_file *filp)  { -	struct amdgpu_device *adev = dev->dev_private;  	union drm_amdgpu_gem_wait_idle *args = data;  	struct drm_gem_object *gobj;  	struct amdgpu_bo *robj; @@ -483,8 +446,7 @@ int amdgpu_gem_wait_idle_ioctl(struct drm_device *dev, void *data,  	} else  		r = ret; -	drm_gem_object_unreference_unlocked(gobj); -	r = amdgpu_gem_handle_lockup(adev, r); +	drm_gem_object_put_unlocked(gobj);  	return r;  } @@ -527,7 +489,7 @@ int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,  unreserve:  	amdgpu_bo_unreserve(robj);  out: -	drm_gem_object_unreference_unlocked(gobj); +	drm_gem_object_put_unlocked(gobj);  	return r;  } @@ -593,9 +555,6 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,  	uint64_t va_flags;  	int r = 0; -	if (!adev->vm_manager.enabled) -		return -ENOTTY; -  	if (args->va_address < AMDGPU_VA_RESERVED_SIZE) {  		dev_err(&dev->pdev->dev,  			"va_address 0x%lX is in reserved area 0x%X\n", @@ -621,6 +580,11 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,  			args->operation);  		return -EINVAL;  	} +	if ((args->operation == AMDGPU_VA_OP_MAP) || +	    (args->operation == AMDGPU_VA_OP_REPLACE)) { +		if (amdgpu_kms_vram_lost(adev, fpriv)) +			return -ENODEV; +	}  	INIT_LIST_HEAD(&list);  	if ((args->operation != AMDGPU_VA_OP_CLEAR) && @@ -657,7 +621,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,  	switch (args->operation) {  	case AMDGPU_VA_OP_MAP: -		r = amdgpu_vm_alloc_pts(adev, bo_va->vm, args->va_address, +		r = amdgpu_vm_alloc_pts(adev, bo_va->base.vm, args->va_address,  					args->map_size);  		if (r)  			goto error_backoff; @@ -677,7 +641,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,  						args->map_size);  		break;  	case AMDGPU_VA_OP_REPLACE: -		r = amdgpu_vm_alloc_pts(adev, bo_va->vm, args->va_address, +		r = amdgpu_vm_alloc_pts(adev, bo_va->base.vm, args->va_address,  					args->map_size);  		if (r)  			goto error_backoff; @@ -698,7 +662,7 @@ error_backoff:  	ttm_eu_backoff_reservation(&ticket, &list);  error_unref: -	drm_gem_object_unreference_unlocked(gobj); +	drm_gem_object_put_unlocked(gobj);  	return r;  } @@ -723,11 +687,11 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,  	switch (args->op) {  	case AMDGPU_GEM_OP_GET_GEM_CREATE_INFO: {  		struct drm_amdgpu_gem_create_in info; -		void __user *out = (void __user *)(uintptr_t)args->value; +		void __user *out = u64_to_user_ptr(args->value);  		info.bo_size = robj->gem_base.size;  		info.alignment = robj->tbo.mem.page_alignment << PAGE_SHIFT; -		info.domains = robj->prefered_domains; +		info.domains = robj->preferred_domains;  		info.domain_flags = robj->flags;  		amdgpu_bo_unreserve(robj);  		if (copy_to_user(out, &info, sizeof(info))) @@ -745,10 +709,10 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,  			amdgpu_bo_unreserve(robj);  			break;  		} -		robj->prefered_domains = args->value & (AMDGPU_GEM_DOMAIN_VRAM | +		robj->preferred_domains = args->value & (AMDGPU_GEM_DOMAIN_VRAM |  							AMDGPU_GEM_DOMAIN_GTT |  							AMDGPU_GEM_DOMAIN_CPU); -		robj->allowed_domains = robj->prefered_domains; +		robj->allowed_domains = robj->preferred_domains;  		if (robj->allowed_domains == AMDGPU_GEM_DOMAIN_VRAM)  			robj->allowed_domains |= AMDGPU_GEM_DOMAIN_GTT; @@ -760,7 +724,7 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,  	}  out: -	drm_gem_object_unreference_unlocked(gobj); +	drm_gem_object_put_unlocked(gobj);  	return r;  } @@ -788,7 +752,7 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv,  	r = drm_gem_handle_create(file_priv, gobj, &handle);  	/* drop reference from allocate - handle holds it now */ -	drm_gem_object_unreference_unlocked(gobj); +	drm_gem_object_put_unlocked(gobj);  	if (r) {  		return r;  	} @@ -806,6 +770,7 @@ static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)  	unsigned domain;  	const char *placement;  	unsigned pin_count; +	uint64_t offset;  	domain = amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type);  	switch (domain) { @@ -820,9 +785,12 @@ static int amdgpu_debugfs_gem_bo_info(int id, void *ptr, void *data)  		placement = " CPU";  		break;  	} -	seq_printf(m, "\t0x%08x: %12ld byte %s @ 0x%010Lx", -		   id, amdgpu_bo_size(bo), placement, -		   amdgpu_bo_gpu_offset(bo)); +	seq_printf(m, "\t0x%08x: %12ld byte %s", +		   id, amdgpu_bo_size(bo), placement); + +	offset = ACCESS_ONCE(bo->tbo.mem.start); +	if (offset != AMDGPU_BO_INVALID_OFFSET) +		seq_printf(m, " @ 0x%010Lx", offset);  	pin_count = ACCESS_ONCE(bo->pin_count);  	if (pin_count) |