From e22d0082ec96864c0689848945f6c41a5f1419af Mon Sep 17 00:00:00 2001 From: Konsta Holtta Date: Mon, 17 Nov 2014 17:37:35 +0200 Subject: gpu: nvgpu: cde: wait for ctx deletion before get Wait for possible temp context deletion to finish properly before passing contexts around later, to prevent situations where the context deleter scheduling would have been completed, but running it would not, and a new one could have been scheduled again. When finished, schedule the deleter before freeing the context back to use to prevent races. Warn in impossible situations when these double deletions would happen. Bug 200054186 Bug 200052943 Change-Id: I23ca0d1081eea77d0e453b9038adc914909b5f48 Signed-off-by: Konsta Holtta Reviewed-on: http://git-master/r/603439 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/cde_gk20a.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c index 24c28029..f4ddc02e 100644 --- a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c @@ -816,7 +816,9 @@ __releases(&cde_app->mutex) cde_ctx); goto out; } - cde_ctx->in_use = true; + + WARN(delayed_work_pending(&cde_ctx->ctx_deleter_work), + "double pending %p", cde_ctx); gk20a_cde_remove_ctx(cde_ctx); gk20a_dbg(gpu_dbg_fn | gpu_dbg_cde_ctx, @@ -858,8 +860,7 @@ __must_hold(&cde_app->mutex) cde_app->ctx_usecount++; /* cancel any deletions now that ctx is in use */ - if (delayed_work_pending(&cde_ctx->ctx_deleter_work)) - gk20a_cde_cancel_deleter(cde_ctx, false); + gk20a_cde_cancel_deleter(cde_ctx, true); return cde_ctx; } @@ -1108,14 +1109,17 @@ __releases(&cde_app->mutex) } mutex_unlock(&cde_app->mutex); } - } else { - gk20a_cde_ctx_release(cde_ctx); } /* delete temporary contexts later */ - if (cde_ctx->is_temporary) + if (cde_ctx->is_temporary) { + WARN_ON(delayed_work_pending(&cde_ctx->ctx_deleter_work)); schedule_delayed_work(&cde_ctx->ctx_deleter_work, msecs_to_jiffies(CTX_DELETE_TIME)); + } + + if (!ch->has_timedout) + gk20a_cde_ctx_release(cde_ctx); } static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx) -- cgit v1.2.2