summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2016-01-12 08:21:37 -0500
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-02-05 11:07:10 -0500
commit8b665ac6b2984e07a290d5ecbcec2c93ec973c65 (patch)
treed830257de402437766711d7c0dddcb358dde1668 /drivers/gpu/nvgpu/gk20a/channel_gk20a.c
parent2ca20e14ba1358b1ca32329bfb16a98de631642e (diff)
gpu: nvgpu: move clean up of jobs to separate worker
We currently clean up the jobs in gk20a_channel_update() which is called from nvhost worker thread Instead of doing this, schedule another delayed worker thread clean_up_work to clean up the jobs (with delay of 1 jiffies) Keep update_gp_get() in channel_update() and not in delayed worker since this will help in better book keeping of gp_get Also, this scheduling will help delay job clean-up so that more number of jobs are batched for clean up and hence less time is consumed by worker Bug 1718092 Change-Id: If3b94b6aab93c92da4cf0d1c74aaba756f4cd838 Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/931701 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c67
1 files changed, 61 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 5e5bbcb0..1f63bbd8 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -64,6 +64,8 @@ static void gk20a_free_error_notifiers(struct channel_gk20a *ch);
64 64
65static u32 gk20a_get_channel_watchdog_timeout(struct channel_gk20a *ch); 65static u32 gk20a_get_channel_watchdog_timeout(struct channel_gk20a *ch);
66 66
67static void gk20a_channel_clean_up_jobs(struct work_struct *work);
68
67/* allocate GPU channel */ 69/* allocate GPU channel */
68static struct channel_gk20a *allocate_channel(struct fifo_gk20a *f) 70static struct channel_gk20a *allocate_channel(struct fifo_gk20a *f)
69{ 71{
@@ -1144,6 +1146,7 @@ struct channel_gk20a *gk20a_open_new_channel(struct gk20a *g)
1144 ch->wdt_enabled = true; 1146 ch->wdt_enabled = true;
1145 ch->obj_class = 0; 1147 ch->obj_class = 0;
1146 ch->interleave = false; 1148 ch->interleave = false;
1149 ch->clean_up.scheduled = false;
1147 gk20a_fifo_set_channel_priority( 1150 gk20a_fifo_set_channel_priority(
1148 ch->g, 0, ch->hw_chid, ch->interleave); 1151 ch->g, 0, ch->hw_chid, ch->interleave);
1149 1152
@@ -1771,6 +1774,32 @@ static int gk20a_free_priv_cmdbuf(struct channel_gk20a *c,
1771 return 0; 1774 return 0;
1772} 1775}
1773 1776
1777static void gk20a_channel_schedule_job_clean_up(struct channel_gk20a *c)
1778{
1779 mutex_lock(&c->clean_up.lock);
1780
1781 if (c->clean_up.scheduled) {
1782 mutex_unlock(&c->clean_up.lock);
1783 return;
1784 }
1785
1786 c->clean_up.scheduled = true;
1787 schedule_delayed_work(&c->clean_up.wq, 1);
1788
1789 mutex_unlock(&c->clean_up.lock);
1790}
1791
1792static void gk20a_channel_cancel_job_clean_up(struct channel_gk20a *c,
1793 bool wait_for_completion)
1794{
1795 if (wait_for_completion)
1796 cancel_delayed_work_sync(&c->clean_up.wq);
1797
1798 mutex_lock(&c->clean_up.lock);
1799 c->clean_up.scheduled = false;
1800 mutex_unlock(&c->clean_up.lock);
1801}
1802
1774static int gk20a_channel_add_job(struct channel_gk20a *c, 1803static int gk20a_channel_add_job(struct channel_gk20a *c,
1775 struct gk20a_fence *pre_fence, 1804 struct gk20a_fence *pre_fence,
1776 struct gk20a_fence *post_fence, 1805 struct gk20a_fence *post_fence,
@@ -1832,22 +1861,28 @@ err_put_vm:
1832 return err; 1861 return err;
1833} 1862}
1834 1863
1835void gk20a_channel_update(struct channel_gk20a *c, int nr_completed) 1864static void gk20a_channel_clean_up_jobs(struct work_struct *work)
1836{ 1865{
1837 struct vm_gk20a *vm = c->vm; 1866 struct channel_gk20a *c = container_of(to_delayed_work(work),
1867 struct channel_gk20a, clean_up.wq);
1868 struct vm_gk20a *vm;
1838 struct channel_gk20a_job *job, *n; 1869 struct channel_gk20a_job *job, *n;
1839 struct gk20a_platform *platform = gk20a_get_platform(c->g->dev); 1870 struct gk20a_platform *platform;
1840 1871
1841 trace_gk20a_channel_update(c->hw_chid); 1872 c = gk20a_channel_get(c);
1873 if (!c)
1874 return;
1842 1875
1843 update_gp_get(c->g, c); 1876 vm = c->vm;
1844 wake_up(&c->submit_wq); 1877 platform = gk20a_get_platform(c->g->dev);
1845 1878
1846 mutex_lock(&c->submit_lock); 1879 mutex_lock(&c->submit_lock);
1847 1880
1848 /* gp_put check needs to be done inside submit lock */ 1881 /* gp_put check needs to be done inside submit lock */
1849 check_gp_put(c->g, c); 1882 check_gp_put(c->g, c);
1850 1883
1884 gk20a_channel_cancel_job_clean_up(c, false);
1885
1851 mutex_lock(&c->jobs_lock); 1886 mutex_lock(&c->jobs_lock);
1852 list_for_each_entry_safe(job, n, &c->jobs, list) { 1887 list_for_each_entry_safe(job, n, &c->jobs, list) {
1853 struct gk20a *g = c->g; 1888 struct gk20a *g = c->g;
@@ -1908,6 +1943,23 @@ void gk20a_channel_update(struct channel_gk20a *c, int nr_completed)
1908 1943
1909 if (c->update_fn) 1944 if (c->update_fn)
1910 schedule_work(&c->update_fn_work); 1945 schedule_work(&c->update_fn_work);
1946
1947 gk20a_channel_put(c);
1948}
1949
1950void gk20a_channel_update(struct channel_gk20a *c, int nr_completed)
1951{
1952 c = gk20a_channel_get(c);
1953 if (!c)
1954 return;
1955
1956 update_gp_get(c->g, c);
1957 wake_up(&c->submit_wq);
1958
1959 trace_gk20a_channel_update(c->hw_chid);
1960 gk20a_channel_schedule_job_clean_up(c);
1961
1962 gk20a_channel_put(c);
1911} 1963}
1912 1964
1913int gk20a_submit_channel_gpfifo(struct channel_gk20a *c, 1965int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
@@ -2249,6 +2301,8 @@ int gk20a_init_channel_support(struct gk20a *g, u32 chid)
2249 mutex_init(&c->timeout.lock); 2301 mutex_init(&c->timeout.lock);
2250 mutex_init(&c->sync_lock); 2302 mutex_init(&c->sync_lock);
2251 INIT_DELAYED_WORK(&c->timeout.wq, gk20a_channel_timeout_handler); 2303 INIT_DELAYED_WORK(&c->timeout.wq, gk20a_channel_timeout_handler);
2304 INIT_DELAYED_WORK(&c->clean_up.wq, gk20a_channel_clean_up_jobs);
2305 mutex_init(&c->clean_up.lock);
2252 INIT_LIST_HEAD(&c->jobs); 2306 INIT_LIST_HEAD(&c->jobs);
2253#if defined(CONFIG_GK20A_CYCLE_STATS) 2307#if defined(CONFIG_GK20A_CYCLE_STATS)
2254 mutex_init(&c->cyclestate.cyclestate_buffer_mutex); 2308 mutex_init(&c->cyclestate.cyclestate_buffer_mutex);
@@ -2612,6 +2666,7 @@ int gk20a_channel_suspend(struct gk20a *g)
2612 if (ch->update_fn && 2666 if (ch->update_fn &&
2613 work_pending(&ch->update_fn_work)) 2667 work_pending(&ch->update_fn_work))
2614 flush_work(&ch->update_fn_work); 2668 flush_work(&ch->update_fn_work);
2669 gk20a_channel_cancel_job_clean_up(ch, true);
2615 2670
2616 channels_in_use = true; 2671 channels_in_use = true;
2617 2672