diff options
author | Debarshi Dutta <ddutta@nvidia.com> | 2018-03-23 06:02:27 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-04-23 00:04:48 -0400 |
commit | d0e4dfd6efd651abc431aba9cfae5907638f8172 (patch) | |
tree | 1a412eaa4636ff2e2862c1623bad3a5ea6883d4e /drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c | |
parent | c918c42a4a3651f757c6966aead4b07eb4b56697 (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.c | 102 |
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 | ||
293 | static void gk20a_channel_syncpt_signal_timeline( | ||
294 | struct gk20a_channel_sync *s) | ||
295 | { | ||
296 | /* Nothing to do. */ | ||
297 | } | ||
298 | |||
299 | static int gk20a_channel_syncpt_id(struct gk20a_channel_sync *s) | 312 | static 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 | ||
391 | static void add_sema_cmd(struct gk20a *g, struct channel_gk20a *c, | 400 | static 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 | ||
668 | static 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 | |||
676 | static int gk20a_channel_semaphore_syncpt_id(struct gk20a_channel_sync *s) | 697 | static 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 * | |||
700 | gk20a_channel_semaphore_create(struct channel_gk20a *c, bool user_managed) | 726 | gk20a_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; |