summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c20
1 files changed, 17 insertions, 3 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;