From cd072a192b0de73c512dfa3ca9ed4b5c25f10119 Mon Sep 17 00:00:00 2001 From: Konsta Holtta Date: Wed, 12 Nov 2014 14:05:02 +0200 Subject: gpu: nvgpu: cde: restrict context count Add an upper limit for cde contexts, and wait for a while if a new context is queried and the limit has been exceeded. This happens only under very high load. If the timeout is exceeded, report -EAGAIN. Change-Id: I1fa47ad6cddf620eae00cea16ecea36cf4151cab Signed-off-by: Konsta Holtta Reviewed-on: http://git-master/r/601719 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/cde_gk20a.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/nvgpu/gk20a/cde_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c index 65d6dd4d..c96225c7 100644 --- a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c @@ -39,6 +39,9 @@ static struct gk20a_cde_ctx *gk20a_cde_allocate_context(struct gk20a *g); #define CTX_DELETE_TIME 1000 +#define MAX_CTX_USE_COUNT 42 +#define MAX_CTX_RETRY_TIME 2000 + static void gk20a_deinit_cde_img(struct gk20a_cde_ctx *cde_ctx) { struct device *dev = &cde_ctx->pdev->dev; @@ -782,12 +785,17 @@ out: gk20a_idle(pdev); } -static struct gk20a_cde_ctx *gk20a_cde_get_context(struct gk20a *g) +static struct gk20a_cde_ctx *gk20a_cde_do_get_context(struct gk20a *g) __must_hold(&cde_app->mutex) { struct gk20a_cde_app *cde_app = &g->cde_app; struct gk20a_cde_ctx *cde_ctx; + /* exhausted? */ + + if (cde_app->ctx_usecount >= MAX_CTX_USE_COUNT) + return ERR_PTR(-EAGAIN); + /* idle context available? */ if (!list_empty(&cde_app->free_contexts)) { @@ -834,6 +842,28 @@ __must_hold(&cde_app->mutex) return cde_ctx; } +static struct gk20a_cde_ctx *gk20a_cde_get_context(struct gk20a *g) +__releases(&cde_app->mutex) +__acquires(&cde_app->mutex) +{ + struct gk20a_cde_app *cde_app = &g->cde_app; + struct gk20a_cde_ctx *cde_ctx = NULL; + unsigned long end = jiffies + msecs_to_jiffies(MAX_CTX_RETRY_TIME); + + do { + cde_ctx = gk20a_cde_do_get_context(g); + if (PTR_ERR(cde_ctx) != -EAGAIN) + break; + + /* exhausted, retry */ + mutex_unlock(&cde_app->mutex); + cond_resched(); + mutex_lock(&cde_app->mutex); + } while (time_before(jiffies, end)); + + return cde_ctx; +} + static struct gk20a_cde_ctx *gk20a_cde_allocate_context(struct gk20a *g) { struct gk20a_cde_ctx *cde_ctx; -- cgit v1.2.2