diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gem_submit.c')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gem_submit.c | 78 | 
1 files changed, 29 insertions, 49 deletions
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index c9e4aeb14f4a..5599d93ec0d2 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -26,6 +26,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev,  		struct msm_gpu_submitqueue *queue, uint32_t nr_bos,  		uint32_t nr_cmds)  { +	static atomic_t ident = ATOMIC_INIT(0);  	struct msm_gem_submit *submit;  	uint64_t sz;  	int ret; @@ -36,7 +37,7 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev,  	if (sz > SIZE_MAX)  		return ERR_PTR(-ENOMEM); -	submit = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); +	submit = kzalloc(sz, GFP_KERNEL);  	if (!submit)  		return ERR_PTR(-ENOMEM); @@ -52,9 +53,13 @@ static struct msm_gem_submit *submit_create(struct drm_device *dev,  	submit->gpu = gpu;  	submit->cmd = (void *)&submit->bos[nr_bos];  	submit->queue = queue; +	submit->pid = get_pid(task_pid(current));  	submit->ring = gpu->rb[queue->ring_nr];  	submit->fault_dumped = false; +	/* Get a unique identifier for the submission for logging purposes */ +	submit->ident = atomic_inc_return(&ident) - 1; +  	INIT_LIST_HEAD(&submit->node);  	return submit; @@ -67,9 +72,9 @@ void __msm_gem_submit_destroy(struct kref *kref)  	unsigned i;  	if (submit->fence_id) { -		mutex_lock(&submit->queue->lock); +		mutex_lock(&submit->queue->idr_lock);  		idr_remove(&submit->queue->fence_idr, submit->fence_id); -		mutex_unlock(&submit->queue->lock); +		mutex_unlock(&submit->queue->idr_lock);  	}  	dma_fence_put(submit->user_fence); @@ -238,17 +243,13 @@ static void submit_cleanup_bo(struct msm_gem_submit *submit, int i,  	if (flags & BO_OBJ_PINNED)  		msm_gem_unpin_locked(obj); -	if (flags & BO_ACTIVE) -		msm_gem_active_put(obj); -  	if (flags & BO_LOCKED)  		dma_resv_unlock(obj->resv);  }  static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i)  { -	unsigned cleanup_flags = BO_VMA_PINNED | BO_OBJ_PINNED | -				 BO_ACTIVE | BO_LOCKED; +	unsigned cleanup_flags = BO_VMA_PINNED | BO_OBJ_PINNED | BO_LOCKED;  	submit_cleanup_bo(submit, i, cleanup_flags);  	if (!(submit->bos[i].flags & BO_VALID)) @@ -353,18 +354,6 @@ static int submit_pin_objects(struct msm_gem_submit *submit)  	submit->valid = true; -	/* -	 * Increment active_count first, so if under memory pressure, we -	 * don't inadvertently evict a bo needed by the submit in order -	 * to pin an earlier bo in the same submit. -	 */ -	for (i = 0; i < submit->nr_bos; i++) { -		struct drm_gem_object *obj = &submit->bos[i].obj->base; - -		msm_gem_active_get(obj, submit->gpu); -		submit->bos[i].flags |= BO_ACTIVE; -	} -  	for (i = 0; i < submit->nr_bos; i++) {  		struct drm_gem_object *obj = &submit->bos[i].obj->base;  		struct msm_gem_vma *vma; @@ -512,11 +501,11 @@ out:   */  static void submit_cleanup(struct msm_gem_submit *submit, bool error)  { -	unsigned cleanup_flags = BO_LOCKED; +	unsigned cleanup_flags = BO_LOCKED | BO_OBJ_PINNED;  	unsigned i;  	if (error) -		cleanup_flags |= BO_VMA_PINNED | BO_OBJ_PINNED | BO_ACTIVE; +		cleanup_flags |= BO_VMA_PINNED;  	for (i = 0; i < submit->nr_bos; i++) {  		struct msm_gem_object *msm_obj = submit->bos[i].obj; @@ -533,10 +522,6 @@ void msm_submit_retire(struct msm_gem_submit *submit)  	for (i = 0; i < submit->nr_bos; i++) {  		struct drm_gem_object *obj = &submit->bos[i].obj->base; -		msm_gem_lock(obj); -		/* Note, VMA already fence-unpinned before submit: */ -		submit_cleanup_bo(submit, i, BO_OBJ_PINNED | BO_ACTIVE); -		msm_gem_unlock(obj);  		drm_gem_object_put(obj);  	}  } @@ -718,7 +703,6 @@ static void msm_process_post_deps(struct msm_submit_post_dep *post_deps,  int msm_ioctl_gem_submit(struct drm_device *dev, void *data,  		struct drm_file *file)  { -	static atomic_t ident = ATOMIC_INIT(0);  	struct msm_drm_private *priv = dev->dev_private;  	struct drm_msm_gem_submit *args = data;  	struct msm_file_private *ctx = file->driver_priv; @@ -729,10 +713,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,  	struct msm_submit_post_dep *post_deps = NULL;  	struct drm_syncobj **syncobjs_to_reset = NULL;  	int out_fence_fd = -1; -	struct pid *pid = get_pid(task_pid(current));  	bool has_ww_ticket = false;  	unsigned i; -	int ret, submitid; +	int ret;  	if (!gpu)  		return -ENXIO; @@ -764,35 +747,26 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,  	if (!queue)  		return -ENOENT; -	/* Get a unique identifier for the submission for logging purposes */ -	submitid = atomic_inc_return(&ident) - 1; -  	ring = gpu->rb[queue->ring_nr]; -	trace_msm_gpu_submit(pid_nr(pid), ring->id, submitid, -		args->nr_bos, args->nr_cmds); - -	ret = mutex_lock_interruptible(&queue->lock); -	if (ret) -		goto out_post_unlock;  	if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) {  		out_fence_fd = get_unused_fd_flags(O_CLOEXEC);  		if (out_fence_fd < 0) {  			ret = out_fence_fd; -			goto out_unlock; +			return ret;  		}  	} -	submit = submit_create(dev, gpu, queue, args->nr_bos, -		args->nr_cmds); -	if (IS_ERR(submit)) { -		ret = PTR_ERR(submit); -		submit = NULL; -		goto out_unlock; -	} +	submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds); +	if (IS_ERR(submit)) +		return PTR_ERR(submit); + +	trace_msm_gpu_submit(pid_nr(submit->pid), ring->id, submit->ident, +		args->nr_bos, args->nr_cmds); -	submit->pid = pid; -	submit->ident = submitid; +	ret = mutex_lock_interruptible(&queue->lock); +	if (ret) +		goto out_post_unlock;  	if (args->flags & MSM_SUBMIT_SUDO)  		submit->in_rb = true; @@ -887,6 +861,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,  	submit->nr_cmds = i; +	mutex_lock(&queue->idr_lock); +  	/*  	 * If using userspace provided seqno fence, validate that the id  	 * is available before arming sched job.  Since access to fence_idr @@ -895,6 +871,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,  	 */  	if ((args->flags & MSM_SUBMIT_FENCE_SN_IN) &&  			idr_find(&queue->fence_idr, args->fence)) { +		mutex_unlock(&queue->idr_lock);  		ret = -EINVAL;  		goto out;  	} @@ -927,6 +904,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,  						    submit->user_fence, 1,  						    INT_MAX, GFP_KERNEL);  	} + +	mutex_unlock(&queue->idr_lock); +  	if (submit->fence_id < 0) {  		ret = submit->fence_id;  		submit->fence_id = 0; @@ -965,9 +945,9 @@ out_unlock:  	if (ret && (out_fence_fd >= 0))  		put_unused_fd(out_fence_fd);  	mutex_unlock(&queue->lock); +out_post_unlock:  	if (submit)  		msm_gem_submit_put(submit); -out_post_unlock:  	if (!IS_ERR_OR_NULL(post_deps)) {  		for (i = 0; i < args->nr_out_syncobjs; ++i) {  			kfree(post_deps[i].chain);  |