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 <kholtta@nvidia.com>
Reviewed-on: http://git-master/r/601719
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Konsta Holtta
2014-11-12 14:05:02 +02:00
committed by Dan Willemsen
parent 1d9fba8804
commit cd072a192b

View File

@@ -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;