From 38d90b60922e6de6b795694d3e3cdf66d4ddae5f Mon Sep 17 00:00:00 2001 From: Peter Daifuku Date: Tue, 7 Mar 2017 17:51:42 -0800 Subject: 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 (cherry picked from commit 2a9ce58b1b318b95ecfcdf78462f918d090eab99) Reviewed-on: http://git-master/r/1319026 (cherry picked from commit 990f070b0a363159ce1b21f936b7512f469018ca) Reviewed-on: http://git-master/r/1321624 Reviewed-by: svccoveritychecker GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 8a9729ab..73cc18d2 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -2658,6 +2658,14 @@ static void gk20a_channel_clean_up_jobs(struct channel_gk20a *c, gk20a_vm_put_buffers(vm, job->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 * them to the pool). */ 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); /* - * 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(). */ wmb(); - channel_gk20a_joblist_lock(c); - channel_gk20a_joblist_delete(c, job); - channel_gk20a_joblist_unlock(c); channel_gk20a_free_job(c, job); job_finished = 1; -- cgit v1.2.2