summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
diff options
context:
space:
mode:
authorDebarshi Dutta <ddutta@nvidia.com>2018-03-23 06:02:27 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-04-23 00:04:48 -0400
commitd0e4dfd6efd651abc431aba9cfae5907638f8172 (patch)
tree1a412eaa4636ff2e2862c1623bad3a5ea6883d4e /drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
parentc918c42a4a3651f757c6966aead4b07eb4b56697 (diff)
gpu: nvgpu: sync_framework cleanups
This patch deals with cleanups meant to make things simpler for the upcoming os abstraction patches for the sync framework. This patch causes some substantial changes which are listed out as follows. 1) sync_timeline is moved out of gk20a_fence into struct nvgpu_channel_linux. New function pointers are created to facilitate os independent methods for enabling/disabling timeline and are now named as os_fence_framework. These function pointers are located in the struct os_channel under struct gk20a. 2) construction of the channel_sync require nvgpu_finalize_poweron_linux() to be invoked before invocations to nvgpu_init_mm_ce_context(). Hence, these methods are now moved away from gk20a_finalize_poweron() and invoked after nvgpu_finalize_poweron_linux(). 3) sync_fence creation is now delinked from fence construction and move to the channel_sync_gk20a's channel_incr methods. These sync_fences are mainly associated with post_fences. 4) In case userspace requires the sync_fences to be constructed, we try to obtain an fd before the gk20a_channel_submit_gpfifo() instead of trying to do that later. This is used to avoid potential after effects of duplicate work submission due to failure to obtain an unused fd. JIRA NVGPU-66 Change-Id: I42a3e4e2e692a113b1b36d2b48ab107ae4444dfa Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1678400 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c102
1 files changed, 65 insertions, 37 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
index bf467210..c0e035ea 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
@@ -183,6 +183,7 @@ static int __gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s,
183 struct gk20a_channel_syncpt *sp = 183 struct gk20a_channel_syncpt *sp =
184 container_of(s, struct gk20a_channel_syncpt, ops); 184 container_of(s, struct gk20a_channel_syncpt, ops);
185 struct channel_gk20a *c = sp->c; 185 struct channel_gk20a *c = sp->c;
186 struct sync_fence *sync_fence = NULL;
186 187
187 err = gk20a_channel_alloc_priv_cmdbuf(c, 188 err = gk20a_channel_alloc_priv_cmdbuf(c,
188 c->g->ops.fifo.get_syncpt_incr_cmd_size(wfi_cmd), 189 c->g->ops.fifo.get_syncpt_incr_cmd_size(wfi_cmd),
@@ -224,10 +225,28 @@ static int __gk20a_channel_syncpt_incr(struct gk20a_channel_sync *s,
224 } 225 }
225 } 226 }
226 227
227 err = gk20a_fence_from_syncpt(fence, sp->nvhost_dev, sp->id, thresh, 228#ifdef CONFIG_SYNC
228 need_sync_fence); 229 if (need_sync_fence) {
229 if (err) 230 sync_fence = nvgpu_nvhost_sync_create_fence(sp->nvhost_dev,
231 sp->id, thresh, "fence");
232
233 if (IS_ERR(sync_fence)) {
234 err = PTR_ERR(sync_fence);
235 goto clean_up_priv_cmd;
236 }
237 }
238#endif
239
240 err = gk20a_fence_from_syncpt(fence, sp->nvhost_dev,
241 sp->id, thresh, sync_fence);
242
243 if (err) {
244#ifdef CONFIG_SYNC
245 if (sync_fence)
246 sync_fence_put(sync_fence);
247#endif
230 goto clean_up_priv_cmd; 248 goto clean_up_priv_cmd;
249 }
231 250
232 return 0; 251 return 0;
233 252
@@ -290,12 +309,6 @@ static void gk20a_channel_syncpt_set_safe_state(struct gk20a_channel_sync *s)
290 nvgpu_nvhost_syncpt_set_safe_state(sp->nvhost_dev, sp->id); 309 nvgpu_nvhost_syncpt_set_safe_state(sp->nvhost_dev, sp->id);
291} 310}
292 311
293static void gk20a_channel_syncpt_signal_timeline(
294 struct gk20a_channel_sync *s)
295{
296 /* Nothing to do. */
297}
298
299static int gk20a_channel_syncpt_id(struct gk20a_channel_sync *s) 312static int gk20a_channel_syncpt_id(struct gk20a_channel_sync *s)
300{ 313{
301 struct gk20a_channel_syncpt *sp = 314 struct gk20a_channel_syncpt *sp =
@@ -368,7 +381,6 @@ gk20a_channel_syncpt_create(struct channel_gk20a *c, bool user_managed)
368 sp->ops.incr_user = gk20a_channel_syncpt_incr_user; 381 sp->ops.incr_user = gk20a_channel_syncpt_incr_user;
369 sp->ops.set_min_eq_max = gk20a_channel_syncpt_set_min_eq_max; 382 sp->ops.set_min_eq_max = gk20a_channel_syncpt_set_min_eq_max;
370 sp->ops.set_safe_state = gk20a_channel_syncpt_set_safe_state; 383 sp->ops.set_safe_state = gk20a_channel_syncpt_set_safe_state;
371 sp->ops.signal_timeline = gk20a_channel_syncpt_signal_timeline;
372 sp->ops.syncpt_id = gk20a_channel_syncpt_id; 384 sp->ops.syncpt_id = gk20a_channel_syncpt_id;
373 sp->ops.syncpt_address = gk20a_channel_syncpt_address; 385 sp->ops.syncpt_address = gk20a_channel_syncpt_address;
374 sp->ops.destroy = gk20a_channel_syncpt_destroy; 386 sp->ops.destroy = gk20a_channel_syncpt_destroy;
@@ -383,9 +395,6 @@ struct gk20a_channel_semaphore {
383 395
384 /* A semaphore pool owned by this channel. */ 396 /* A semaphore pool owned by this channel. */
385 struct nvgpu_semaphore_pool *pool; 397 struct nvgpu_semaphore_pool *pool;
386
387 /* A sync timeline that advances when gpu completes work. */
388 struct sync_timeline *timeline;
389}; 398};
390 399
391static void add_sema_cmd(struct gk20a *g, struct channel_gk20a *c, 400static void add_sema_cmd(struct gk20a *g, struct channel_gk20a *c,
@@ -560,6 +569,7 @@ static int __gk20a_channel_semaphore_incr(
560 struct channel_gk20a *c = sp->c; 569 struct channel_gk20a *c = sp->c;
561 struct nvgpu_semaphore *semaphore; 570 struct nvgpu_semaphore *semaphore;
562 int err = 0; 571 int err = 0;
572 struct sync_fence *sync_fence = NULL;
563 573
564 semaphore = nvgpu_semaphore_alloc(c); 574 semaphore = nvgpu_semaphore_alloc(c);
565 if (!semaphore) { 575 if (!semaphore) {
@@ -579,12 +589,31 @@ static int __gk20a_channel_semaphore_incr(
579 /* Release the completion semaphore. */ 589 /* Release the completion semaphore. */
580 add_sema_cmd(c->g, c, semaphore, incr_cmd, 0, false, wfi_cmd); 590 add_sema_cmd(c->g, c, semaphore, incr_cmd, 0, false, wfi_cmd);
581 591
582 err = gk20a_fence_from_semaphore(c->g, fence, 592#ifdef CONFIG_SYNC
583 sp->timeline, semaphore, 593 if (need_sync_fence) {
584 &c->semaphore_wq, 594 sync_fence = gk20a_sync_fence_create(c,
585 need_sync_fence); 595 semaphore, "f-gk20a-0x%04x",
586 if (err) 596 nvgpu_semaphore_gpu_ro_va(semaphore));
597
598 if (!sync_fence) {
599 err = -ENOMEM;
600 goto clean_up_sema;
601 }
602 }
603#endif
604
605 err = gk20a_fence_from_semaphore(fence,
606 semaphore,
607 &c->semaphore_wq,
608 sync_fence);
609
610 if (err) {
611#ifdef CONFIG_SYNC
612 if (sync_fence)
613 sync_fence_put(sync_fence);
614#endif
587 goto clean_up_sema; 615 goto clean_up_sema;
616 }
588 617
589 return 0; 618 return 0;
590 619
@@ -665,14 +694,6 @@ static void gk20a_channel_semaphore_set_safe_state(struct gk20a_channel_sync *s)
665 /* Nothing to do. */ 694 /* Nothing to do. */
666} 695}
667 696
668static void gk20a_channel_semaphore_signal_timeline(
669 struct gk20a_channel_sync *s)
670{
671 struct gk20a_channel_semaphore *sp =
672 container_of(s, struct gk20a_channel_semaphore, ops);
673 gk20a_sync_timeline_signal(sp->timeline);
674}
675
676static int gk20a_channel_semaphore_syncpt_id(struct gk20a_channel_sync *s) 697static int gk20a_channel_semaphore_syncpt_id(struct gk20a_channel_sync *s)
677{ 698{
678 return -EINVAL; 699 return -EINVAL;
@@ -687,8 +708,13 @@ static void gk20a_channel_semaphore_destroy(struct gk20a_channel_sync *s)
687{ 708{
688 struct gk20a_channel_semaphore *sema = 709 struct gk20a_channel_semaphore *sema =
689 container_of(s, struct gk20a_channel_semaphore, ops); 710 container_of(s, struct gk20a_channel_semaphore, ops);
690 if (sema->timeline) 711
691 gk20a_sync_timeline_destroy(sema->timeline); 712 struct channel_gk20a *c = sema->c;
713 struct gk20a *g = c->g;
714
715 if (c->has_os_fence_framework_support &&
716 g->os_channel.os_fence_framework_inst_exists(c))
717 g->os_channel.destroy_os_fence_framework(c);
692 718
693 /* The sema pool is cleaned up by the VM destroy. */ 719 /* The sema pool is cleaned up by the VM destroy. */
694 sema->pool = NULL; 720 sema->pool = NULL;
@@ -700,10 +726,10 @@ static struct gk20a_channel_sync *
700gk20a_channel_semaphore_create(struct channel_gk20a *c, bool user_managed) 726gk20a_channel_semaphore_create(struct channel_gk20a *c, bool user_managed)
701{ 727{
702 struct gk20a_channel_semaphore *sema; 728 struct gk20a_channel_semaphore *sema;
729 struct gk20a *g = c->g;
703 char pool_name[20]; 730 char pool_name[20];
704#ifdef CONFIG_SYNC
705 int asid = -1; 731 int asid = -1;
706#endif 732 int err;
707 733
708 if (WARN_ON(!c->vm)) 734 if (WARN_ON(!c->vm))
709 return NULL; 735 return NULL;
@@ -716,17 +742,20 @@ gk20a_channel_semaphore_create(struct channel_gk20a *c, bool user_managed)
716 sprintf(pool_name, "semaphore_pool-%d", c->chid); 742 sprintf(pool_name, "semaphore_pool-%d", c->chid);
717 sema->pool = c->vm->sema_pool; 743 sema->pool = c->vm->sema_pool;
718 744
719#ifdef CONFIG_SYNC
720 if (c->vm->as_share) 745 if (c->vm->as_share)
721 asid = c->vm->as_share->id; 746 asid = c->vm->as_share->id;
722 747
723 sema->timeline = gk20a_sync_timeline_create( 748 if (c->has_os_fence_framework_support) {
749 /*Init the sync_timeline for this channel */
750 err = g->os_channel.init_os_fence_framework(c,
724 "gk20a_ch%d_as%d", c->chid, asid); 751 "gk20a_ch%d_as%d", c->chid, asid);
725 if (!sema->timeline) { 752
726 gk20a_channel_semaphore_destroy(&sema->ops); 753 if (err) {
727 return NULL; 754 nvgpu_kfree(g, sema);
755 return NULL;
756 }
728 } 757 }
729#endif 758
730 nvgpu_atomic_set(&sema->ops.refcount, 0); 759 nvgpu_atomic_set(&sema->ops.refcount, 0);
731 sema->ops.wait_syncpt = gk20a_channel_semaphore_wait_syncpt; 760 sema->ops.wait_syncpt = gk20a_channel_semaphore_wait_syncpt;
732 sema->ops.wait_fd = gk20a_channel_semaphore_wait_fd; 761 sema->ops.wait_fd = gk20a_channel_semaphore_wait_fd;
@@ -735,7 +764,6 @@ gk20a_channel_semaphore_create(struct channel_gk20a *c, bool user_managed)
735 sema->ops.incr_user = gk20a_channel_semaphore_incr_user; 764 sema->ops.incr_user = gk20a_channel_semaphore_incr_user;
736 sema->ops.set_min_eq_max = gk20a_channel_semaphore_set_min_eq_max; 765 sema->ops.set_min_eq_max = gk20a_channel_semaphore_set_min_eq_max;
737 sema->ops.set_safe_state = gk20a_channel_semaphore_set_safe_state; 766 sema->ops.set_safe_state = gk20a_channel_semaphore_set_safe_state;
738 sema->ops.signal_timeline = gk20a_channel_semaphore_signal_timeline;
739 sema->ops.syncpt_id = gk20a_channel_semaphore_syncpt_id; 767 sema->ops.syncpt_id = gk20a_channel_semaphore_syncpt_id;
740 sema->ops.syncpt_address = gk20a_channel_semaphore_syncpt_address; 768 sema->ops.syncpt_address = gk20a_channel_semaphore_syncpt_address;
741 sema->ops.destroy = gk20a_channel_semaphore_destroy; 769 sema->ops.destroy = gk20a_channel_semaphore_destroy;