diff options
author | Richard Zhao <rizhao@nvidia.com> | 2016-01-04 13:28:04 -0500 |
---|---|---|
committer | Vladislav Buzov <vbuzov@nvidia.com> | 2016-01-10 23:07:53 -0500 |
commit | a9c6f595399074e88c16f3557e5acb29db1d52d5 (patch) | |
tree | 2d2665668bac915b5598d83881a1efec892be435 /drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |
parent | 3484fd0d1365c6f97723d97cb45664aa75c45f32 (diff) |
gpu: nvgpu: enable semaphore acquire timeout
It'll detect dead semaphore acquire. The worst case is when
ACQUIRE_SWITCH is disabled, semaphore acquire will poll and
consume full gpu timeslicees.
The timeout value is set to half of channel WDT.
Bug 1636800
Change-Id: Ida6ccc534006a191513edf47e7b82d4b5b758684
Signed-off-by: Richard Zhao <rizhao@nvidia.com>
Reviewed-on: http://git-master/r/928827
GVS: Gerrit_Virtual_Submit
Reviewed-by: Vladislav Buzov <vbuzov@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index b480c80a..a5c2efb3 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * GK20A Graphics channel | 2 | * GK20A Graphics channel |
3 | * | 3 | * |
4 | * Copyright (c) 2011-2015, NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms and conditions of the GNU General Public License, | 7 | * under the terms and conditions of the GNU General Public License, |
@@ -62,6 +62,8 @@ static int channel_gk20a_update_runlist(struct channel_gk20a *c, | |||
62 | bool add); | 62 | bool add); |
63 | static void gk20a_free_error_notifiers(struct channel_gk20a *ch); | 63 | static void gk20a_free_error_notifiers(struct channel_gk20a *ch); |
64 | 64 | ||
65 | static u32 gk20a_get_channel_watchdog_timeout(struct channel_gk20a *ch); | ||
66 | |||
65 | /* allocate GPU channel */ | 67 | /* allocate GPU channel */ |
66 | static struct channel_gk20a *allocate_channel(struct fifo_gk20a *f) | 68 | static struct channel_gk20a *allocate_channel(struct fifo_gk20a *f) |
67 | { | 69 | { |
@@ -204,6 +206,38 @@ static int channel_gk20a_set_schedule_params(struct channel_gk20a *c, | |||
204 | return 0; | 206 | return 0; |
205 | } | 207 | } |
206 | 208 | ||
209 | u32 channel_gk20a_pbdma_acquire_val(struct channel_gk20a *c) | ||
210 | { | ||
211 | u32 val, exp, man; | ||
212 | u64 timeout; | ||
213 | int val_len; | ||
214 | |||
215 | timeout = gk20a_get_channel_watchdog_timeout(c); | ||
216 | do_div(timeout, 2); /* set acquire timeout to half of channel wdt */ | ||
217 | timeout *= 1000000UL; /* ms -> ns */ | ||
218 | do_div(timeout, 1024); /* in unit of 1024ns */ | ||
219 | val_len = fls(timeout >> 32) + 32; | ||
220 | if (val_len == 32) | ||
221 | val_len = fls(timeout); | ||
222 | if (val_len > 16 + pbdma_acquire_timeout_exp_max_v()) { /* man: 16bits */ | ||
223 | exp = pbdma_acquire_timeout_exp_max_v(); | ||
224 | man = pbdma_acquire_timeout_man_max_v(); | ||
225 | } else if (val_len > 16) { | ||
226 | exp = val_len - 16; | ||
227 | man = timeout >> exp; | ||
228 | } else { | ||
229 | exp = 0; | ||
230 | man = timeout; | ||
231 | } | ||
232 | |||
233 | val = pbdma_acquire_retry_man_2_f() | | ||
234 | pbdma_acquire_retry_exp_2_f() | | ||
235 | pbdma_acquire_timeout_exp_f(exp) | | ||
236 | pbdma_acquire_timeout_man_f(man) | | ||
237 | pbdma_acquire_timeout_en_enable_f(); | ||
238 | return val; | ||
239 | } | ||
240 | |||
207 | int channel_gk20a_setup_ramfc(struct channel_gk20a *c, | 241 | int channel_gk20a_setup_ramfc(struct channel_gk20a *c, |
208 | u64 gpfifo_base, u32 gpfifo_entries, u32 flags) | 242 | u64 gpfifo_base, u32 gpfifo_entries, u32 flags) |
209 | { | 243 | { |
@@ -249,11 +283,7 @@ int channel_gk20a_setup_ramfc(struct channel_gk20a *c, | |||
249 | gk20a_mem_wr32(inst_ptr, ram_fc_target_w(), pbdma_target_engine_sw_f()); | 283 | gk20a_mem_wr32(inst_ptr, ram_fc_target_w(), pbdma_target_engine_sw_f()); |
250 | 284 | ||
251 | gk20a_mem_wr32(inst_ptr, ram_fc_acquire_w(), | 285 | gk20a_mem_wr32(inst_ptr, ram_fc_acquire_w(), |
252 | pbdma_acquire_retry_man_2_f() | | 286 | channel_gk20a_pbdma_acquire_val(c)); |
253 | pbdma_acquire_retry_exp_2_f() | | ||
254 | pbdma_acquire_timeout_exp_max_f() | | ||
255 | pbdma_acquire_timeout_man_max_f() | | ||
256 | pbdma_acquire_timeout_en_disable_f()); | ||
257 | 287 | ||
258 | gk20a_mem_wr32(inst_ptr, ram_fc_runlist_timeslice_w(), | 288 | gk20a_mem_wr32(inst_ptr, ram_fc_runlist_timeslice_w(), |
259 | fifo_runlist_timeslice_timeout_128_f() | | 289 | fifo_runlist_timeslice_timeout_128_f() | |