diff options
author | David Nieto <dmartineznie@nvidia.com> | 2017-04-19 00:56:09 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-09-22 18:47:01 -0400 |
commit | 90568a2ce58c03f457bdd4fab6675cd327ed13fd (patch) | |
tree | 4095b7599083ac478dbfbb522f1abcc585dc2801 /drivers/gpu/nvgpu/gp106 | |
parent | 7134e9e852116f86745cd23312bbfba34100bf6d (diff) |
gpu: nvgpu: allow bind to be interrupted
This change solves two problems:
(*) the possibility of a crash due to interrupting the gpu
initialization following a bind
(*) a IOVA memory leak that could prevent the GPU from binding after
about 200 bind/unbind cycles
A detailed list of fixes:
- chek that arbiter is initialized before freeing it.
- do not re-enable interrupts when MSI is enabled on unbind.
- free the semaphore sea on unbind.
- ensure we dont double load the vbios.
- check return value of nvgpu_mutex_init for semaphores.
- add corresponding nvgpu_mutex_destroy calls.
bug 1816516
Change-Id: Ia8af73019e0e1183998855d55bb3eea09672a8b7
Signed-off-by: David Nieto <dmartineznie@nvidia.com>
Reviewed-on: http://git-master/r/1465302
Reviewed-by: Alex Waterman <alexw@nvidia.com>
Reviewed-by: Thomas Fleury <tfleury@nvidia.com>
Reviewed-by: David Jarrett <djarrett@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1563019
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gp106')
-rw-r--r-- | drivers/gpu/nvgpu/gp106/bios_gp106.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/drivers/gpu/nvgpu/gp106/bios_gp106.c b/drivers/gpu/nvgpu/gp106/bios_gp106.c index f772e267..c728433f 100644 --- a/drivers/gpu/nvgpu/gp106/bios_gp106.c +++ b/drivers/gpu/nvgpu/gp106/bios_gp106.c | |||
@@ -177,6 +177,9 @@ int gp106_bios_init(struct gk20a *g) | |||
177 | 177 | ||
178 | gk20a_dbg_fn(""); | 178 | gk20a_dbg_fn(""); |
179 | 179 | ||
180 | if (g->bios_is_init) | ||
181 | return 0; | ||
182 | |||
180 | gk20a_dbg_info("reading bios from EEPROM"); | 183 | gk20a_dbg_info("reading bios from EEPROM"); |
181 | g->bios.size = BIOS_SIZE; | 184 | g->bios.size = BIOS_SIZE; |
182 | g->bios.data = nvgpu_vmalloc(g, BIOS_SIZE); | 185 | g->bios.data = nvgpu_vmalloc(g, BIOS_SIZE); |
@@ -195,12 +198,13 @@ int gp106_bios_init(struct gk20a *g) | |||
195 | 198 | ||
196 | err = nvgpu_bios_parse_rom(g); | 199 | err = nvgpu_bios_parse_rom(g); |
197 | if (err) | 200 | if (err) |
198 | return err; | 201 | goto free_firmware; |
199 | 202 | ||
200 | if (g->gpu_characteristics.vbios_version < g->vbios_min_version) { | 203 | if (g->gpu_characteristics.vbios_version < g->vbios_min_version) { |
201 | nvgpu_err(g, "unsupported VBIOS version %08x", | 204 | nvgpu_err(g, "unsupported VBIOS version %08x", |
202 | g->gpu_characteristics.vbios_version); | 205 | g->gpu_characteristics.vbios_version); |
203 | return -EINVAL; | 206 | err = -EINVAL; |
207 | goto free_firmware; | ||
204 | } | 208 | } |
205 | 209 | ||
206 | /* WAR for HW2.5 RevA (INA3221 is missing) */ | 210 | /* WAR for HW2.5 RevA (INA3221 is missing) */ |
@@ -216,25 +220,37 @@ int gp106_bios_init(struct gk20a *g) | |||
216 | 220 | ||
217 | d = debugfs_create_blob("bios", S_IRUGO, l->debugfs, | 221 | d = debugfs_create_blob("bios", S_IRUGO, l->debugfs, |
218 | &g->bios_blob); | 222 | &g->bios_blob); |
219 | if (!d) | 223 | if (!d) { |
224 | err = -EINVAL; | ||
220 | nvgpu_err(g, "No debugfs?"); | 225 | nvgpu_err(g, "No debugfs?"); |
226 | goto free_firmware; | ||
227 | } | ||
221 | #endif | 228 | #endif |
222 | |||
223 | gk20a_dbg_fn("done"); | 229 | gk20a_dbg_fn("done"); |
224 | 230 | ||
225 | err = gp106_bios_devinit(g); | 231 | err = gp106_bios_devinit(g); |
226 | if (err) { | 232 | if (err) { |
227 | nvgpu_err(g, "devinit failed"); | 233 | nvgpu_err(g, "devinit failed"); |
228 | return err; | 234 | goto free_debugfs; |
229 | } | 235 | } |
230 | 236 | ||
231 | if (nvgpu_is_enabled(g, NVGPU_PMU_RUN_PREOS)) { | 237 | if (nvgpu_is_enabled(g, NVGPU_PMU_RUN_PREOS)) { |
232 | err = gp106_bios_preos(g); | 238 | err = gp106_bios_preos(g); |
233 | if (err) { | 239 | if (err) { |
234 | nvgpu_err(g, "pre-os failed"); | 240 | nvgpu_err(g, "pre-os failed"); |
235 | return err; | 241 | goto free_debugfs; |
236 | } | 242 | } |
237 | } | 243 | } |
244 | g->bios_is_init = true; | ||
238 | 245 | ||
239 | return 0; | 246 | return 0; |
247 | free_debugfs: | ||
248 | #ifdef CONFIG_DEBUG_FS | ||
249 | debugfs_remove(d); | ||
250 | #endif | ||
251 | free_firmware: | ||
252 | if (g->bios.data) | ||
253 | nvgpu_vfree(g, g->bios.data); | ||
254 | return err; | ||
240 | } | 255 | } |
256 | |||