gpu: nvgpu: del channel job before fence is closed

In gk20a_channel_clean_up_jobs, move removal of job from channel's job list
to before fences are cleaned up; this will prevent gk20a_channel_abort from
asynchronously trying to dereference an already freed job.

Bug 1844305
JIRA EVLR-849

Change-Id: I1ba05237aa74be1350007630bfa5eba9988f859a
Signed-off-by: Peter Daifuku <pdaifuku@nvidia.com>
(cherry picked from commit 2a9ce58b1b318b95ecfcdf78462f918d090eab99)
Reviewed-on: http://git-master/r/1319026
(cherry picked from commit 990f070b0a363159ce1b21f936b7512f469018ca)
Reviewed-on: http://git-master/r/1322332
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Peter Daifuku
2017-03-07 17:51:42 -08:00
committed by mobile promotions
parent b6a2aa3631
commit 0eb5255e54

View File

@@ -2658,6 +2658,14 @@ static void gk20a_channel_clean_up_jobs(struct channel_gk20a *c,
gk20a_vm_put_buffers(vm, job->mapped_buffers, gk20a_vm_put_buffers(vm, job->mapped_buffers,
job->num_mapped_buffers); job->num_mapped_buffers);
/* Remove job from channel's job list before we close the
* fences, to prevent other callers (gk20a_channel_abort) from
* trying to dereference post_fence when it no longer exists.
*/
channel_gk20a_joblist_lock(c);
channel_gk20a_joblist_delete(c, job);
channel_gk20a_joblist_unlock(c);
/* Close the fences (this will unref the semaphores and release /* Close the fences (this will unref the semaphores and release
* them to the pool). */ * them to the pool). */
gk20a_fence_put(job->pre_fence); gk20a_fence_put(job->pre_fence);
@@ -2673,13 +2681,10 @@ static void gk20a_channel_clean_up_jobs(struct channel_gk20a *c,
gk20a_channel_put(c); gk20a_channel_put(c);
/* /*
* ensure all pending writes complete before deleting the node. * ensure all pending writes complete before freeing up the job.
* see corresponding rmb in channel_gk20a_alloc_job(). * see corresponding rmb in channel_gk20a_alloc_job().
*/ */
wmb(); wmb();
channel_gk20a_joblist_lock(c);
channel_gk20a_joblist_delete(c, job);
channel_gk20a_joblist_unlock(c);
channel_gk20a_free_job(c, job); channel_gk20a_free_job(c, job);
job_finished = 1; job_finished = 1;