summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/cde_gk20a.c
diff options
context:
space:
mode:
authorKonsta Holtta <kholtta@nvidia.com>2014-10-15 03:01:33 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:11:51 -0400
commit83f3c09510a70cc046b548eaff006403c986e9f7 (patch)
tree5f06d224f32efe0fb4dc1e3ac501c3350a2561e8 /drivers/gpu/nvgpu/gk20a/cde_gk20a.c
parentb564dc87b66ac6411e5aac0065b7e63db9a96a06 (diff)
gpu: nvgpu: create cde context dynamically as needed
When the preallocated buffer of cde contexts is full, allocate a new temporary one dynamically. This needs to create a totally new command buffer but fixes possible but rare lockups in case of circular dependencies. The temporary is deleted after the channel job has finished. Bug 200040211 Change-Id: Ic18d1441e8574a3e562a22f9b9dfec1acdf72b71 Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: http://git-master/r/552036 GVS: Gerrit_Virtual_Submit Reviewed-by: Arto Merilainen <amerilainen@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/cde_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/cde_gk20a.c69
1 files changed, 56 insertions, 13 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c
index 1c230be6..7931b83f 100644
--- a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c
@@ -34,6 +34,8 @@
34#include "hw_ccsr_gk20a.h" 34#include "hw_ccsr_gk20a.h"
35#include "hw_pbdma_gk20a.h" 35#include "hw_pbdma_gk20a.h"
36 36
37static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx, bool free_after_use);
38
37static void gk20a_deinit_cde_img(struct gk20a_cde_ctx *cde_ctx) 39static void gk20a_deinit_cde_img(struct gk20a_cde_ctx *cde_ctx)
38{ 40{
39 struct device *dev = &cde_ctx->pdev->dev; 41 struct device *dev = &cde_ctx->pdev->dev;
@@ -589,10 +591,11 @@ static int gk20a_cde_execute_buffer(struct gk20a_cde_ctx *cde_ctx,
589 num_entries, flags, fence, fence_out); 591 num_entries, flags, fence, fence_out);
590} 592}
591 593
592static struct gk20a_cde_ctx *gk20a_cde_get_context(struct gk20a_cde_app *cde_app) 594static struct gk20a_cde_ctx *gk20a_cde_get_context(struct gk20a *g)
593{ 595{
596 struct gk20a_cde_app *cde_app = &g->cde_app;
594 struct gk20a_cde_ctx *cde_ctx = cde_app->cde_ctx; 597 struct gk20a_cde_ctx *cde_ctx = cde_app->cde_ctx;
595 int i; 598 int i, ret;
596 599
597 /* try to find a jobless context */ 600 /* try to find a jobless context */
598 601
@@ -608,10 +611,22 @@ static struct gk20a_cde_ctx *gk20a_cde_get_context(struct gk20a_cde_app *cde_app
608 return cde_ctx; 611 return cde_ctx;
609 } 612 }
610 613
611 /* pick just the next cde context, hopefully somewhat in order */ 614 /* could not find a free one, so allocate dynamically */
612 cde_ctx = cde_app->cde_ctx + cde_app->cde_ctx_ptr; 615
613 cde_app->cde_ctx_ptr = (cde_app->cde_ctx_ptr + 1) % 616 gk20a_warn(&g->dev->dev, "cde: no free contexts, allocating temporary");
614 ARRAY_SIZE(cde_app->cde_ctx); 617
618 cde_ctx = kzalloc(sizeof(*cde_ctx), GFP_KERNEL);
619 if (!cde_ctx)
620 return ERR_PTR(-ENOMEM);
621
622 cde_ctx->g = g;
623 cde_ctx->pdev = g->dev;
624
625 ret = gk20a_cde_load(cde_ctx, true);
626 if (ret) {
627 gk20a_err(&g->dev->dev, "cde: cde load failed on temporary");
628 return ERR_PTR(ret);
629 }
615 630
616 return cde_ctx; 631 return cde_ctx;
617} 632}
@@ -637,7 +652,9 @@ int gk20a_cde_convert(struct gk20a *g,
637 652
638 mutex_lock(&cde_app->mutex); 653 mutex_lock(&cde_app->mutex);
639 654
640 cde_ctx = gk20a_cde_get_context(cde_app); 655 cde_ctx = gk20a_cde_get_context(g);
656 if (IS_ERR(cde_ctx))
657 return PTR_ERR(cde_ctx);
641 658
642 /* First, map the buffers to local va */ 659 /* First, map the buffers to local va */
643 660
@@ -747,7 +764,32 @@ exit_unlock:
747 return err; 764 return err;
748} 765}
749 766
750int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx) 767static void gk20a_free_ctx_cb(struct channel_gk20a *ch, void *data)
768{
769 struct gk20a_cde_ctx *cde_ctx = data;
770 bool empty;
771 int err;
772
773 mutex_lock(&ch->jobs_lock);
774 empty = list_empty(&ch->jobs);
775 mutex_unlock(&ch->jobs_lock);
776
777 if (!empty)
778 return;
779
780 /* this should fail only when shutting down the whole device */
781 err = gk20a_busy(cde_ctx->pdev);
782 if (WARN(err, "gk20a cde: cannot set gk20a on, not freeing channel"
783 ", leaking memory"))
784 return;
785
786 gk20a_cde_remove(cde_ctx);
787 gk20a_idle(cde_ctx->pdev);
788
789 kfree(cde_ctx);
790}
791
792static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx, bool free_after_use)
751{ 793{
752 struct gk20a *g = cde_ctx->g; 794 struct gk20a *g = cde_ctx->g;
753 const struct firmware *img; 795 const struct firmware *img;
@@ -762,7 +804,10 @@ int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx)
762 return -ENOSYS; 804 return -ENOSYS;
763 } 805 }
764 806
765 ch = gk20a_open_new_channel(g); 807 if (free_after_use)
808 ch = gk20a_open_new_channel_with_cb(g, gk20a_free_ctx_cb, cde_ctx);
809 else
810 ch = gk20a_open_new_channel(g);
766 if (!ch) { 811 if (!ch) {
767 gk20a_warn(&cde_ctx->pdev->dev, "cde: gk20a channel not available"); 812 gk20a_warn(&cde_ctx->pdev->dev, "cde: gk20a channel not available");
768 err = -ENOMEM; 813 err = -ENOMEM;
@@ -852,10 +897,9 @@ int gk20a_cde_reload(struct gk20a *g)
852 mutex_lock(&cde_app->mutex); 897 mutex_lock(&cde_app->mutex);
853 for (i = 0; i < ARRAY_SIZE(cde_app->cde_ctx); i++, cde_ctx++) { 898 for (i = 0; i < ARRAY_SIZE(cde_app->cde_ctx); i++, cde_ctx++) {
854 gk20a_cde_remove(cde_ctx); 899 gk20a_cde_remove(cde_ctx);
855 err = gk20a_cde_load(cde_ctx); 900 err = gk20a_cde_load(cde_ctx, false);
856 } 901 }
857 902
858 cde_app->cde_ctx_ptr = 0;
859 mutex_unlock(&cde_app->mutex); 903 mutex_unlock(&cde_app->mutex);
860 904
861 gk20a_idle(g->dev); 905 gk20a_idle(g->dev);
@@ -877,7 +921,7 @@ int gk20a_init_cde_support(struct gk20a *g)
877 for (i = 0; i < ARRAY_SIZE(cde_app->cde_ctx); i++, cde_ctx++) { 921 for (i = 0; i < ARRAY_SIZE(cde_app->cde_ctx); i++, cde_ctx++) {
878 cde_ctx->g = g; 922 cde_ctx->g = g;
879 cde_ctx->pdev = g->dev; 923 cde_ctx->pdev = g->dev;
880 ret = gk20a_cde_load(cde_ctx); 924 ret = gk20a_cde_load(cde_ctx, false);
881 if (ret) 925 if (ret)
882 goto err_init_instance; 926 goto err_init_instance;
883 } 927 }
@@ -885,7 +929,6 @@ int gk20a_init_cde_support(struct gk20a *g)
885 /* take shadow to the vm for general usage */ 929 /* take shadow to the vm for general usage */
886 cde_app->vm = cde_app->cde_ctx->vm; 930 cde_app->vm = cde_app->cde_ctx->vm;
887 931
888 cde_app->cde_ctx_ptr = 0;
889 cde_app->initialised = true; 932 cde_app->initialised = true;
890 mutex_unlock(&cde_app->mutex); 933 mutex_unlock(&cde_app->mutex);
891 934