From 6500ce7581b7fa2360657a8e58d327e0cf311f25 Mon Sep 17 00:00:00 2001 From: Vedashree Vidwans Date: Fri, 23 Aug 2019 14:28:21 -0700 Subject: gpu: nvgpu: fix race for channel sync read/write CTS test dEQP-VK.api.object_management.max_concurrent.device_group crashes with invalid userspace memory access. Currently, nvgpu_submit_prepare_syncs() races with gk20a_channel_clean_up_jobs() and this race condition is exposed when aggressive_sync_destroy_thresh is set to non-zero value. nvgpu_submit_prepare_syncs() gets ref for c->sync to submit job and releases channel sync_lock immediately. Meanwhile, gk20a_channel_worker_process() triggers gk20a_channel_clean_up_jobs(), which destroys ref'd c->sync pointer. Channel sync is deleted by gk20a_channel_clean_up_jobs() only if aggressive_sync_destroy_thresh is non-zero. So, gk20a_channel_clean_up_jobs() and nvgpu_submit_prepare_syncs() will race only in this scenario. Hence, if aggressive_sync_destroy_thresh value is non-zero, this patch protects channel's sync pointer by holding channel sync_lock during complete execution of nvgpu_submit_prepare_syncs(). Bug 2613870 Change-Id: I6f3d48aff361d1cb38c30d2ce5de276d0c55fb6f Signed-off-by: Vedashree Vidwans Reviewed-on: https://git-master.nvidia.com/r/2180550 Reviewed-by: Seema Khowala GVS: Gerrit_Virtual_Submit Reviewed-by: Seshendra Gadagottu Reviewed-by: Vinod Gopalakrishnakurup Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/fifo/submit.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/nvgpu') diff --git a/drivers/gpu/nvgpu/common/fifo/submit.c b/drivers/gpu/nvgpu/common/fifo/submit.c index 599539cd..4effc663 100644 --- a/drivers/gpu/nvgpu/common/fifo/submit.c +++ b/drivers/gpu/nvgpu/common/fifo/submit.c @@ -59,13 +59,11 @@ static int nvgpu_submit_prepare_syncs(struct channel_gk20a *c, c->sync = nvgpu_channel_sync_create(c, false); if (!c->sync) { err = -ENOMEM; - nvgpu_mutex_release(&c->sync_lock); goto fail; } new_sync_created = true; } nvgpu_atomic_inc(&c->sync->refcount); - nvgpu_mutex_release(&c->sync_lock); } if (g->ops.fifo.resetup_ramfc && new_sync_created) { @@ -151,6 +149,9 @@ static int nvgpu_submit_prepare_syncs(struct channel_gk20a *c, goto clean_up_incr_cmd; } + if (g->aggressive_sync_destroy_thresh) { + nvgpu_mutex_release(&c->sync_lock); + } return 0; clean_up_incr_cmd: @@ -169,6 +170,9 @@ clean_up_wait_cmd: job->wait_cmd = NULL; } fail: + if (g->aggressive_sync_destroy_thresh) { + nvgpu_mutex_release(&c->sync_lock); + } *wait_cmd = NULL; return err; } -- cgit v1.2.2