public inbox for linux-tegra@vger.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: Mikko Perttunen
	<mperttunen-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH] drm/tegra: Prevent BOs from being freed during job submission
Date: Sat, 12 Aug 2017 18:24:38 +0300	[thread overview]
Message-ID: <984e3c39-ade4-32d8-075b-7ae62e306a57@gmail.com> (raw)
In-Reply-To: <93fa7980-a650-4549-a1ae-1296cc24cf81-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On 11.08.2017 21:16, Dmitry Osipenko wrote:
> On 11.08.2017 20:59, Thierry Reding wrote:
>> From: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>
>> Since DRM IOCTL's are lockless, there is a chance that BOs could be
>> released while a job submission is in progress. To avoid that, keep the
>> GEM reference until the job has been pinned, part of which will be to
>> take another reference.
>>
>> Signed-off-by: Dmitry Osipenko <digetx-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Signed-off-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>> ---
>>  drivers/gpu/drm/tegra/drm.c | 42 +++++++++++++++++++++++++++++++++---------
>>  1 file changed, 33 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
>> index f01db33fa20f..e5d19e1c9bc8 100644
>> --- a/drivers/gpu/drm/tegra/drm.c
>> +++ b/drivers/gpu/drm/tegra/drm.c
>> @@ -320,8 +320,6 @@ host1x_bo_lookup(struct drm_file *file, u32 handle)
>>  	if (!gem)
>>  		return NULL;
>>  
>> -	drm_gem_object_unreference_unlocked(gem);
>> -
>>  	bo = to_tegra_bo(gem);
>>  	return &bo->base;
>>  }
>> @@ -410,8 +408,10 @@ int tegra_drm_submit(struct tegra_drm_context *context,
>>  		(void __user *)(uintptr_t)args->waitchks;
>>  	struct drm_tegra_syncpt syncpt;
>>  	struct host1x *host1x = dev_get_drvdata(drm->dev->parent);
>> +	struct drm_gem_object **refs;
>>  	struct host1x_syncpt *sp;
>>  	struct host1x_job *job;
>> +	unsigned int num_refs;
>>  	int err;
>>  
>>  	/* We don't yet support other than one syncpt_incr struct per submit */
>> @@ -433,6 +433,26 @@ int tegra_drm_submit(struct tegra_drm_context *context,
>>  	job->class = context->client->base.class;
>>  	job->serialize = true;
>>  
>> +	/*
>> +	 * Track referenced BOs so that they can be unreferenced after the
>> +	 * submission is complete.
>> +	 */
>> +	num_refs = num_cmdbufs + num_relocs * 2 + num_waitchks;
>> +
>> +	if (sizeof(*refs) * num_refs > ULONG_MAX) {
> 
> Thierry, since you've omitted (u64) here (comparing to the original patch), I
> think it should be better to write as:
> 
> 	if (num_refs > ULONG_MAX / sizeof(*refs)) {
> 
> To avoid integer overflow in the check.
> 

Moreover, this check isn't needed at all because it duplicates same checking
done by kmalloc_array().

>> +		err = -EINVAL;
>> +		goto fail;
>> +	}
>> +
>> +	refs = kmalloc_array(num_refs, sizeof(*refs), GFP_KERNEL);
>> +	if (!refs) {
>> +		err = -ENOMEM;
>> +		goto fail;
>> +	}
>> +
>> +	/* reuse as an iterator later */
>> +	num_refs = 0;
>> +
>>  	while (num_cmdbufs) {
>>  		struct drm_tegra_cmdbuf cmdbuf;
>>  		struct host1x_bo *bo;
>> @@ -461,6 +481,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
>>  
>>  		offset = (u64)cmdbuf.offset + (u64)cmdbuf.words * sizeof(u32);
>>  		obj = host1x_to_tegra_bo(bo);
>> +		refs[num_refs++] = &obj->gem;
>>  
>>  		/*
>>  		 * Gather buffer base address must be 4-bytes aligned,
>> @@ -490,6 +511,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
>>  
>>  		reloc = &job->relocarray[num_relocs];
>>  		obj = host1x_to_tegra_bo(reloc->cmdbuf.bo);
>> +		refs[num_refs++] = &obj->gem;
>>  
>>  		/*
>>  		 * The unaligned cmdbuf offset will cause an unaligned write
>> @@ -503,6 +525,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
>>  		}
>>  
>>  		obj = host1x_to_tegra_bo(reloc->target.bo);
>> +		refs[num_refs++] = &obj->gem;
>>  
>>  		if (reloc->target.offset >= obj->gem.size) {
>>  			err = -EINVAL;
>> @@ -522,6 +545,7 @@ int tegra_drm_submit(struct tegra_drm_context *context,
>>  			goto fail;
>>  
>>  		obj = host1x_to_tegra_bo(wait->bo);
>> +		refs[num_refs++] = &obj->gem;
>>  
>>  		/*
>>  		 * The unaligned offset will cause an unaligned write during
>> @@ -561,17 +585,17 @@ int tegra_drm_submit(struct tegra_drm_context *context,
>>  		goto fail;
>>  
>>  	err = host1x_job_submit(job);
>> -	if (err)
>> -		goto fail_submit;
>> +	if (err) {
>> +		host1x_job_unpin(job);
>> +		goto fail;
>> +	}
>>  
>>  	args->fence = job->syncpt_end;
>>  
>> -	host1x_job_put(job);
>> -	return 0;
>> -
>> -fail_submit:
>> -	host1x_job_unpin(job);
>>  fail:
>> +	while (num_refs--)
>> +		drm_gem_object_put_unlocked(refs[num_refs]);
>> +
>>  	host1x_job_put(job);
>>  	return err;
>>  }
>>
> 
> 


-- 
Dmitry

  parent reply	other threads:[~2017-08-12 15:24 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-11 17:59 [PATCH] drm/tegra: Prevent BOs from being freed during job submission Thierry Reding
     [not found] ` <20170811175926.24317-1-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-08-11 18:16   ` Dmitry Osipenko
     [not found]     ` <93fa7980-a650-4549-a1ae-1296cc24cf81-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-08-12 15:24       ` Dmitry Osipenko [this message]
2017-08-12 15:48   ` Dmitry Osipenko
2017-08-12 16:01   ` Dmitry Osipenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=984e3c39-ade4-32d8-075b-7ae62e306a57@gmail.com \
    --to=digetx-re5jqeeqqe8avxtiumwx3w@public.gmane.org \
    --cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=mperttunen-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org \
    --cc=thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox