summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c20
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c6
-rw-r--r--drivers/gpu/nvgpu/gk20a/fifo_gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/gk20a/platform_gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/vgpu/fifo_vgpu.c2
5 files changed, 22 insertions, 10 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 6015ab5e..8db885e3 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -42,6 +42,8 @@
42 42
43#define NVMAP_HANDLE_PARAM_SIZE 1 43#define NVMAP_HANDLE_PARAM_SIZE 1
44 44
45#define NVGPU_BEGIN_AGGRESSIVE_SYNC_DESTROY_LIMIT 64 /* channels */
46
45static struct channel_gk20a *allocate_channel(struct fifo_gk20a *f); 47static struct channel_gk20a *allocate_channel(struct fifo_gk20a *f);
46static void free_channel(struct fifo_gk20a *f, struct channel_gk20a *c); 48static void free_channel(struct fifo_gk20a *f, struct channel_gk20a *c);
47 49
@@ -64,6 +66,7 @@ static void gk20a_free_error_notifiers(struct channel_gk20a *ch);
64static struct channel_gk20a *allocate_channel(struct fifo_gk20a *f) 66static struct channel_gk20a *allocate_channel(struct fifo_gk20a *f)
65{ 67{
66 struct channel_gk20a *ch = NULL; 68 struct channel_gk20a *ch = NULL;
69 struct gk20a_platform *platform = gk20a_get_platform(f->g->dev);
67 70
68 mutex_lock(&f->free_chs_mutex); 71 mutex_lock(&f->free_chs_mutex);
69 if (!list_empty(&f->free_chs)) { 72 if (!list_empty(&f->free_chs)) {
@@ -72,21 +75,31 @@ static struct channel_gk20a *allocate_channel(struct fifo_gk20a *f)
72 list_del(&ch->free_chs); 75 list_del(&ch->free_chs);
73 WARN_ON(atomic_read(&ch->ref_count)); 76 WARN_ON(atomic_read(&ch->ref_count));
74 WARN_ON(ch->referenceable); 77 WARN_ON(ch->referenceable);
78 f->used_channels++;
75 } 79 }
76 mutex_unlock(&f->free_chs_mutex); 80 mutex_unlock(&f->free_chs_mutex);
77 81
82 if (f->used_channels > NVGPU_BEGIN_AGGRESSIVE_SYNC_DESTROY_LIMIT)
83 platform->aggressive_sync_destroy = true;
84
78 return ch; 85 return ch;
79} 86}
80 87
81static void free_channel(struct fifo_gk20a *f, 88static void free_channel(struct fifo_gk20a *f,
82 struct channel_gk20a *ch) 89 struct channel_gk20a *ch)
83{ 90{
91 struct gk20a_platform *platform = gk20a_get_platform(f->g->dev);
92
84 trace_gk20a_release_used_channel(ch->hw_chid); 93 trace_gk20a_release_used_channel(ch->hw_chid);
85 /* refcount is zero here and channel is in a freed/dead state */ 94 /* refcount is zero here and channel is in a freed/dead state */
86 mutex_lock(&f->free_chs_mutex); 95 mutex_lock(&f->free_chs_mutex);
87 /* add to head to increase visibility of timing-related bugs */ 96 /* add to head to increase visibility of timing-related bugs */
88 list_add(&ch->free_chs, &f->free_chs); 97 list_add(&ch->free_chs, &f->free_chs);
98 f->used_channels--;
89 mutex_unlock(&f->free_chs_mutex); 99 mutex_unlock(&f->free_chs_mutex);
100
101 if (f->used_channels < NVGPU_BEGIN_AGGRESSIVE_SYNC_DESTROY_LIMIT)
102 platform->aggressive_sync_destroy = false;
90} 103}
91 104
92int channel_gk20a_commit_va(struct channel_gk20a *c) 105int channel_gk20a_commit_va(struct channel_gk20a *c)
@@ -311,6 +324,7 @@ static void channel_gk20a_bind(struct channel_gk20a *ch_gk20a)
311void channel_gk20a_unbind(struct channel_gk20a *ch_gk20a) 324void channel_gk20a_unbind(struct channel_gk20a *ch_gk20a)
312{ 325{
313 struct gk20a *g = ch_gk20a->g; 326 struct gk20a *g = ch_gk20a->g;
327 struct gk20a_platform *platform = gk20a_get_platform(g->dev);
314 328
315 gk20a_dbg_fn(""); 329 gk20a_dbg_fn("");
316 330
@@ -327,8 +341,7 @@ void channel_gk20a_unbind(struct channel_gk20a *ch_gk20a)
327 * if not, then it will be destroyed at channel_free() 341 * if not, then it will be destroyed at channel_free()
328 */ 342 */
329 mutex_lock(&ch_gk20a->sync_lock); 343 mutex_lock(&ch_gk20a->sync_lock);
330 if (ch_gk20a->sync && ch_gk20a->sync->aggressive_destroy) { 344 if (ch_gk20a->sync && platform->aggressive_sync_destroy) {
331
332 ch_gk20a->sync->destroy(ch_gk20a->sync); 345 ch_gk20a->sync->destroy(ch_gk20a->sync);
333 ch_gk20a->sync = NULL; 346 ch_gk20a->sync = NULL;
334 } 347 }
@@ -1715,6 +1728,7 @@ void gk20a_channel_update(struct channel_gk20a *c, int nr_completed)
1715{ 1728{
1716 struct vm_gk20a *vm = c->vm; 1729 struct vm_gk20a *vm = c->vm;
1717 struct channel_gk20a_job *job, *n; 1730 struct channel_gk20a_job *job, *n;
1731 struct gk20a_platform *platform = gk20a_get_platform(c->g->dev);
1718 1732
1719 trace_gk20a_channel_update(c->hw_chid); 1733 trace_gk20a_channel_update(c->hw_chid);
1720 1734
@@ -1769,7 +1783,7 @@ void gk20a_channel_update(struct channel_gk20a *c, int nr_completed)
1769 */ 1783 */
1770 if (list_empty(&c->jobs)) { 1784 if (list_empty(&c->jobs)) {
1771 mutex_lock(&c->sync_lock); 1785 mutex_lock(&c->sync_lock);
1772 if (c->sync && c->sync->aggressive_destroy && 1786 if (c->sync && platform->aggressive_sync_destroy &&
1773 gk20a_fence_is_expired(c->last_submit.post_fence)) { 1787 gk20a_fence_is_expired(c->last_submit.post_fence)) {
1774 c->sync->destroy(c->sync); 1788 c->sync->destroy(c->sync);
1775 c->sync = NULL; 1789 c->sync = NULL;
diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
index 7f70d347..95647774 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c
@@ -345,8 +345,6 @@ gk20a_channel_syncpt_create(struct channel_gk20a *c)
345 sp->ops.syncpt_id = gk20a_channel_syncpt_id; 345 sp->ops.syncpt_id = gk20a_channel_syncpt_id;
346 sp->ops.destroy = gk20a_channel_syncpt_destroy; 346 sp->ops.destroy = gk20a_channel_syncpt_destroy;
347 347
348 sp->ops.aggressive_destroy = true;
349
350 return &sp->ops; 348 return &sp->ops;
351} 349}
352#endif /* CONFIG_TEGRA_GK20A */ 350#endif /* CONFIG_TEGRA_GK20A */
@@ -690,10 +688,6 @@ gk20a_channel_semaphore_create(struct channel_gk20a *c)
690 sema->ops.syncpt_id = gk20a_channel_semaphore_syncpt_id; 688 sema->ops.syncpt_id = gk20a_channel_semaphore_syncpt_id;
691 sema->ops.destroy = gk20a_channel_semaphore_destroy; 689 sema->ops.destroy = gk20a_channel_semaphore_destroy;
692 690
693 /* Aggressively destroying the semaphore sync would cause overhead
694 * since the pool needs to be mapped to GMMU. */
695 sema->ops.aggressive_destroy = false;
696
697 return &sema->ops; 691 return &sema->ops;
698clean_up: 692clean_up:
699 gk20a_channel_semaphore_destroy(&sema->ops); 693 gk20a_channel_semaphore_destroy(&sema->ops);
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
index 3f9fac54..1b47677b 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.h
@@ -105,6 +105,7 @@ struct fifo_gk20a {
105 struct mem_desc userd; 105 struct mem_desc userd;
106 u32 userd_entry_size; 106 u32 userd_entry_size;
107 107
108 int used_channels;
108 struct channel_gk20a *channel; 109 struct channel_gk20a *channel;
109 /* zero-kref'd channels here */ 110 /* zero-kref'd channels here */
110 struct list_head free_chs; 111 struct list_head free_chs;
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
index b7a28ea5..84b3fcaf 100644
--- a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
@@ -47,6 +47,9 @@ struct gk20a_platform {
47 /* Should be populated at probe. */ 47 /* Should be populated at probe. */
48 bool has_syncpoints; 48 bool has_syncpoints;
49 49
50 /* flag to set sync destroy aggressiveness */
51 bool aggressive_sync_destroy;
52
50 /* Should be populated by probe. */ 53 /* Should be populated by probe. */
51 struct dentry *debugfs; 54 struct dentry *debugfs;
52 struct dentry *debugfs_alias; 55 struct dentry *debugfs_alias;
diff --git a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
index 664f8c5b..dd6630a7 100644
--- a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
@@ -63,7 +63,7 @@ static void vgpu_channel_unbind(struct channel_gk20a *ch)
63 * resource at this point 63 * resource at this point
64 * if not, then it will be destroyed at channel_free() 64 * if not, then it will be destroyed at channel_free()
65 */ 65 */
66 if (ch->sync && ch->sync->aggressive_destroy) { 66 if (ch->sync && platform->aggressive_sync_destroy) {
67 ch->sync->destroy(ch->sync); 67 ch->sync->destroy(ch->sync);
68 ch->sync = NULL; 68 ch->sync = NULL;
69 } 69 }