From e153458aad399eedc2c05692226afb000dff4d58 Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Wed, 6 Jan 2016 13:42:23 +0530 Subject: gpu: nvgpu: return ENOSPC if no private command buffer space If we run out of gpfifo space or private command buffer space, we currently return EAGAIN as error code Instead of EAGAIN, return ENOSPC as error code so that caller (user space) can read the error code and do some re-trials As the jobs are processed, it is possible to free up some space. And hence such re-trials could succeed Bug 1715291 Change-Id: I9a2ed7134d2496b383899b3c02c0e70452b26115 Signed-off-by: Deepak Nibade Reviewed-on: http://git-master/r/929402 Reviewed-by: Sachin Nikam Tested-by: Sachin Nikam --- drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 4 +-- drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c | 38 +++++++++++++++------------- 2 files changed, 22 insertions(+), 20 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 2ec1ffe4..f34df520 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c @@ -1327,7 +1327,7 @@ int gk20a_channel_alloc_priv_cmdbuf(struct channel_gk20a *c, u32 orig_size, free_count = (q->size - (q->put - q->get) - 1) % q->size; if (size > free_count) - return -EAGAIN; + return -ENOSPC; e = kzalloc(sizeof(struct priv_cmd_entry), GFP_KERNEL); if (!e) { @@ -2022,7 +2022,7 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c, if (err) { gk20a_err(d, "timeout waiting for gpfifo space"); - err = -EAGAIN; + err = -ENOSPC; goto clean_up; } diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c index c0c8ec6d..952e6e6a 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c @@ -3,7 +3,7 @@ * * GK20A Channel Synchronization Abstraction * - * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -60,6 +60,7 @@ static int gk20a_channel_syncpt_wait_syncpt(struct gk20a_channel_sync *s, struct gk20a_channel_syncpt *sp = container_of(s, struct gk20a_channel_syncpt, ops); struct priv_cmd_entry *wait_cmd = NULL; + int err = 0; if (!nvhost_syncpt_is_valid_pt_ext(sp->host1x_pdev, id)) { dev_warn(dev_from_gk20a(sp->c->g), @@ -70,11 +71,11 @@ static int gk20a_channel_syncpt_wait_syncpt(struct gk20a_channel_sync *s, if (nvhost_syncpt_is_expired_ext(sp->host1x_pdev, id, thresh)) return 0; - gk20a_channel_alloc_priv_cmdbuf(sp->c, 4, &wait_cmd); - if (wait_cmd == NULL) { + err = gk20a_channel_alloc_priv_cmdbuf(sp->c, 4, &wait_cmd); + if (err) { gk20a_err(dev_from_gk20a(sp->c->g), "not enough priv cmd buffer space"); - return -EAGAIN; + return err; } add_wait_cmd(&wait_cmd->ptr[0], id, thresh); @@ -96,6 +97,7 @@ static int gk20a_channel_syncpt_wait_fd(struct gk20a_channel_sync *s, int fd, struct gk20a_channel_syncpt *sp = container_of(s, struct gk20a_channel_syncpt, ops); struct channel_gk20a *c = sp->c; + int err = 0; sync_fence = nvhost_sync_fdget(fd); if (!sync_fence) @@ -116,12 +118,12 @@ static int gk20a_channel_syncpt_wait_fd(struct gk20a_channel_sync *s, int fd, if (num_wait_cmds == 0) return 0; - gk20a_channel_alloc_priv_cmdbuf(c, 4 * num_wait_cmds, &wait_cmd); - if (wait_cmd == NULL) { + err = gk20a_channel_alloc_priv_cmdbuf(c, 4 * num_wait_cmds, &wait_cmd); + if (err) { gk20a_err(dev_from_gk20a(c->g), "not enough priv cmd buffer space"); sync_fence_put(sync_fence); - return -EAGAIN; + return err; } i = 0; @@ -182,11 +184,11 @@ static int __gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s, if (wfi_cmd) incr_cmd_size += 2; - gk20a_channel_alloc_priv_cmdbuf(c, incr_cmd_size, &incr_cmd); - if (incr_cmd == NULL) { + err = gk20a_channel_alloc_priv_cmdbuf(c, incr_cmd_size, &incr_cmd); + if (err) { gk20a_err(dev_from_gk20a(c->g), "not enough priv cmd buffer space"); - return -EAGAIN; + return err; } /* WAR for hw bug 1491360: syncpt needs to be incremented twice */ @@ -471,18 +473,17 @@ static int gk20a_channel_semaphore_wait_fd( w->sema = gk20a_semaphore_alloc(sema->pool); if (!w->sema) { gk20a_err(dev_from_gk20a(c->g), "ran out of semaphores"); - err = -EAGAIN; + err = -ENOMEM; goto fail; } /* worker takes one reference */ gk20a_semaphore_get(w->sema); - gk20a_channel_alloc_priv_cmdbuf(c, 8, &wait_cmd); - if (wait_cmd == NULL) { + err = gk20a_channel_alloc_priv_cmdbuf(c, 8, &wait_cmd); + if (err) { gk20a_err(dev_from_gk20a(c->g), "not enough priv cmd buffer space"); - err = -EAGAIN; goto fail; } @@ -527,21 +528,22 @@ static int __gk20a_channel_semaphore_incr( container_of(s, struct gk20a_channel_semaphore, ops); struct channel_gk20a *c = sp->c; struct gk20a_semaphore *semaphore; + int err = 0; semaphore = gk20a_semaphore_alloc(sp->pool); if (!semaphore) { gk20a_err(dev_from_gk20a(c->g), "ran out of semaphores"); - return -EAGAIN; + return -ENOMEM; } incr_cmd_size = 10; - gk20a_channel_alloc_priv_cmdbuf(c, incr_cmd_size, &incr_cmd); - if (incr_cmd == NULL) { + err = gk20a_channel_alloc_priv_cmdbuf(c, incr_cmd_size, &incr_cmd); + if (err) { gk20a_err(dev_from_gk20a(c->g), "not enough priv cmd buffer space"); gk20a_semaphore_put(semaphore); - return -EAGAIN; + return err; } /* Release the completion semaphore. */ -- cgit v1.2.2