diff options
| author | Tejun Heo <tj@kernel.org> | 2015-12-07 10:09:03 -0500 | 
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2015-12-07 10:09:03 -0500 | 
| commit | 0b98f0c04245877ae0b625a7f0aa55b8ff98e0c4 (patch) | |
| tree | 486ebe0d76217a4f7781e28fbd96facb0b66f9da /drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |
| parent | 67cde9c4938945b9510730c64e68d2f1dd7bc0aa (diff) | |
| parent | 527e9316f8ec44bd53d90fb9f611fa7ffff52bb9 (diff) | |
Merge branch 'master' into for-4.4-fixes
The following commit which went into mainline through networking tree
  3b13758f51de ("cgroups: Allow dynamically changing net_classid")
conflicts in net/core/netclassid_cgroup.c with the following pending
fix in cgroup/for-4.4-fixes.
  1f7dd3e5a6e4 ("cgroup: fix handling of multi-destination migration from subtree_control enabling")
The former separates out update_classid() from cgrp_attach() and
updates it to walk all fds of all tasks in the target css so that it
can be used from both migration and config change paths.  The latter
drops @css from cgrp_attach().
Resolve the conflict by making cgrp_attach() call update_classid()
with the css from the first task.  We can revive @tset walking in
cgrp_attach() but given that net_cls is v1 only where there always is
only one target css during migration, this is fine.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Nina Schiff <ninasc@fb.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 185 | 
1 files changed, 75 insertions, 110 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index dfc4d02c7a38..4f352ec9dec4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -127,30 +127,6 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type,  	return 0;  } -struct amdgpu_cs_parser *amdgpu_cs_parser_create(struct amdgpu_device *adev, -                                               struct drm_file *filp, -                                               struct amdgpu_ctx *ctx, -                                               struct amdgpu_ib *ibs, -                                               uint32_t num_ibs) -{ -	struct amdgpu_cs_parser *parser; -	int i; - -	parser = kzalloc(sizeof(struct amdgpu_cs_parser), GFP_KERNEL); -	if (!parser) -		return NULL; - -	parser->adev = adev; -	parser->filp = filp; -	parser->ctx = ctx; -	parser->ibs = ibs; -	parser->num_ibs = num_ibs; -	for (i = 0; i < num_ibs; i++) -		ibs[i].ctx = ctx; - -	return parser; -} -  int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)  {  	union drm_amdgpu_cs *cs = data; @@ -246,6 +222,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)  				}  				p->uf.bo = gem_to_amdgpu_bo(gobj); +				amdgpu_bo_ref(p->uf.bo); +				drm_gem_object_unreference_unlocked(gobj);  				p->uf.offset = fence_data->offset;  			} else {  				ret = -EINVAL; @@ -463,8 +441,18 @@ static int cmp_size_smaller_first(void *priv, struct list_head *a,  	return (int)la->robj->tbo.num_pages - (int)lb->robj->tbo.num_pages;  } -static void amdgpu_cs_parser_fini_early(struct amdgpu_cs_parser *parser, int error, bool backoff) +/** + * cs_parser_fini() - clean parser states + * @parser:	parser structure holding parsing context. + * @error:	error number + * + * If error is set than unvalidate buffer, otherwise just free memory + * used by parsing context. + **/ +static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bool backoff)  { +	unsigned i; +  	if (!error) {  		/* Sort the buffer list from the smallest to largest buffer,  		 * which affects the order of buffers in the LRU list. @@ -479,17 +467,14 @@ static void amdgpu_cs_parser_fini_early(struct amdgpu_cs_parser *parser, int err  		list_sort(NULL, &parser->validated, cmp_size_smaller_first);  		ttm_eu_fence_buffer_objects(&parser->ticket, -				&parser->validated, -				&parser->ibs[parser->num_ibs-1].fence->base); +					    &parser->validated, +					    parser->fence);  	} else if (backoff) {  		ttm_eu_backoff_reservation(&parser->ticket,  					   &parser->validated);  	} -} +	fence_put(parser->fence); -static void amdgpu_cs_parser_fini_late(struct amdgpu_cs_parser *parser) -{ -	unsigned i;  	if (parser->ctx)  		amdgpu_ctx_put(parser->ctx);  	if (parser->bo_list) @@ -499,31 +484,12 @@ static void amdgpu_cs_parser_fini_late(struct amdgpu_cs_parser *parser)  	for (i = 0; i < parser->nchunks; i++)  		drm_free_large(parser->chunks[i].kdata);  	kfree(parser->chunks); -	if (!amdgpu_enable_scheduler) -	{ -		if (parser->ibs) -			for (i = 0; i < parser->num_ibs; i++) -				amdgpu_ib_free(parser->adev, &parser->ibs[i]); -		kfree(parser->ibs); -		if (parser->uf.bo) -			drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base); -	} - -	kfree(parser); -} - -/** - * cs_parser_fini() - clean parser states - * @parser:	parser structure holding parsing context. - * @error:	error number - * - * If error is set than unvalidate buffer, otherwise just free memory - * used by parsing context. - **/ -static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bool backoff) -{ -       amdgpu_cs_parser_fini_early(parser, error, backoff); -       amdgpu_cs_parser_fini_late(parser); +	if (parser->ibs) +		for (i = 0; i < parser->num_ibs; i++) +			amdgpu_ib_free(parser->adev, &parser->ibs[i]); +	kfree(parser->ibs); +	if (parser->uf.bo) +		amdgpu_bo_unref(&parser->uf.bo);  }  static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, @@ -610,15 +576,9 @@ static int amdgpu_cs_ib_vm_chunk(struct amdgpu_device *adev,  	}  	r = amdgpu_bo_vm_update_pte(parser, vm); -	if (r) { -		goto out; -	} -	amdgpu_cs_sync_rings(parser); -	if (!amdgpu_enable_scheduler) -		r = amdgpu_ib_schedule(adev, parser->num_ibs, parser->ibs, -				       parser->filp); +	if (!r) +		amdgpu_cs_sync_rings(parser); -out:  	return r;  } @@ -818,7 +778,7 @@ static int amdgpu_cs_free_job(struct amdgpu_job *job)  			amdgpu_ib_free(job->adev, &job->ibs[i]);  	kfree(job->ibs);  	if (job->uf.bo) -		drm_gem_object_unreference_unlocked(&job->uf.bo->gem_base); +		amdgpu_bo_unref(&job->uf.bo);  	return 0;  } @@ -826,38 +786,35 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  {  	struct amdgpu_device *adev = dev->dev_private;  	union drm_amdgpu_cs *cs = data; -	struct amdgpu_fpriv *fpriv = filp->driver_priv; -	struct amdgpu_vm *vm = &fpriv->vm; -	struct amdgpu_cs_parser *parser; +	struct amdgpu_cs_parser parser = {};  	bool reserved_buffers = false;  	int i, r;  	if (!adev->accel_working)  		return -EBUSY; -	parser = amdgpu_cs_parser_create(adev, filp, NULL, NULL, 0); -	if (!parser) -		return -ENOMEM; -	r = amdgpu_cs_parser_init(parser, data); +	parser.adev = adev; +	parser.filp = filp; + +	r = amdgpu_cs_parser_init(&parser, data);  	if (r) {  		DRM_ERROR("Failed to initialize parser !\n"); -		amdgpu_cs_parser_fini(parser, r, false); +		amdgpu_cs_parser_fini(&parser, r, false);  		r = amdgpu_cs_handle_lockup(adev, r);  		return r;  	} -	mutex_lock(&vm->mutex); -	r = amdgpu_cs_parser_relocs(parser); +	r = amdgpu_cs_parser_relocs(&parser);  	if (r == -ENOMEM)  		DRM_ERROR("Not enough memory for command submission!\n");  	else if (r && r != -ERESTARTSYS)  		DRM_ERROR("Failed to process the buffer list %d!\n", r);  	else if (!r) {  		reserved_buffers = true; -		r = amdgpu_cs_ib_fill(adev, parser); +		r = amdgpu_cs_ib_fill(adev, &parser);  	}  	if (!r) { -		r = amdgpu_cs_dependencies(adev, parser); +		r = amdgpu_cs_dependencies(adev, &parser);  		if (r)  			DRM_ERROR("Failed in the dependencies handling %d!\n", r);  	} @@ -865,63 +822,71 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)  	if (r)  		goto out; -	for (i = 0; i < parser->num_ibs; i++) -		trace_amdgpu_cs(parser, i); +	for (i = 0; i < parser.num_ibs; i++) +		trace_amdgpu_cs(&parser, i); -	r = amdgpu_cs_ib_vm_chunk(adev, parser); +	r = amdgpu_cs_ib_vm_chunk(adev, &parser);  	if (r)  		goto out; -	if (amdgpu_enable_scheduler && parser->num_ibs) { +	if (amdgpu_enable_scheduler && parser.num_ibs) { +		struct amdgpu_ring * ring = parser.ibs->ring; +		struct amd_sched_fence *fence;  		struct amdgpu_job *job; -		struct amdgpu_ring * ring =  parser->ibs->ring; +  		job = kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL);  		if (!job) {  			r = -ENOMEM;  			goto out;  		} +  		job->base.sched = &ring->sched; -		job->base.s_entity = &parser->ctx->rings[ring->idx].entity; -		job->adev = parser->adev; -		job->ibs = parser->ibs; -		job->num_ibs = parser->num_ibs; -		job->base.owner = parser->filp; -		mutex_init(&job->job_lock); +		job->base.s_entity = &parser.ctx->rings[ring->idx].entity; +		job->adev = parser.adev; +		job->owner = parser.filp; +		job->free_job = amdgpu_cs_free_job; + +		job->ibs = parser.ibs; +		job->num_ibs = parser.num_ibs; +		parser.ibs = NULL; +		parser.num_ibs = 0; +  		if (job->ibs[job->num_ibs - 1].user) { -			memcpy(&job->uf,  &parser->uf, -			       sizeof(struct amdgpu_user_fence)); +			job->uf = parser.uf;  			job->ibs[job->num_ibs - 1].user = &job->uf; +			parser.uf.bo = NULL;  		} -		job->free_job = amdgpu_cs_free_job; -		mutex_lock(&job->job_lock); -		r = amd_sched_entity_push_job(&job->base); -		if (r) { -			mutex_unlock(&job->job_lock); +		fence = amd_sched_fence_create(job->base.s_entity, +					       parser.filp); +		if (!fence) { +			r = -ENOMEM;  			amdgpu_cs_free_job(job);  			kfree(job);  			goto out;  		} -		cs->out.handle = -			amdgpu_ctx_add_fence(parser->ctx, ring, -					     &job->base.s_fence->base); -		parser->ibs[parser->num_ibs - 1].sequence = cs->out.handle; +		job->base.s_fence = fence; +		parser.fence = fence_get(&fence->base); -		list_sort(NULL, &parser->validated, cmp_size_smaller_first); -		ttm_eu_fence_buffer_objects(&parser->ticket, -				&parser->validated, -				&job->base.s_fence->base); +		cs->out.handle = amdgpu_ctx_add_fence(parser.ctx, ring, +						      &fence->base); +		job->ibs[job->num_ibs - 1].sequence = cs->out.handle; -		mutex_unlock(&job->job_lock); -		amdgpu_cs_parser_fini_late(parser); -		mutex_unlock(&vm->mutex); -		return 0; +		trace_amdgpu_cs_ioctl(job); +		amd_sched_entity_push_job(&job->base); + +	} else { +		struct amdgpu_fence *fence; + +		r = amdgpu_ib_schedule(adev, parser.num_ibs, parser.ibs, +				       parser.filp); +		fence = parser.ibs[parser.num_ibs - 1].fence; +		parser.fence = fence_get(&fence->base); +		cs->out.handle = parser.ibs[parser.num_ibs - 1].sequence;  	} -	cs->out.handle = parser->ibs[parser->num_ibs - 1].sequence;  out: -	amdgpu_cs_parser_fini(parser, r, reserved_buffers); -	mutex_unlock(&vm->mutex); +	amdgpu_cs_parser_fini(&parser, r, reserved_buffers);  	r = amdgpu_cs_handle_lockup(adev, r);  	return r;  } | 
