summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDavid Nieto <dmartineznie@nvidia.com>2017-04-19 00:56:09 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-09-22 18:47:01 -0400
commit90568a2ce58c03f457bdd4fab6675cd327ed13fd (patch)
tree4095b7599083ac478dbfbb522f1abcc585dc2801 /drivers/gpu
parent7134e9e852116f86745cd23312bbfba34100bf6d (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')
-rw-r--r--drivers/gpu/nvgpu/clk/clk_arb.c4
-rw-r--r--drivers/gpu/nvgpu/common/semaphore.c3
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h1
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c2
-rw-r--r--drivers/gpu/nvgpu/gp106/bios_gp106.c28
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/semaphore.h2
6 files changed, 29 insertions, 11 deletions
diff --git a/drivers/gpu/nvgpu/clk/clk_arb.c b/drivers/gpu/nvgpu/clk/clk_arb.c
index 4f09da74..0df9545a 100644
--- a/drivers/gpu/nvgpu/clk/clk_arb.c
+++ b/drivers/gpu/nvgpu/clk/clk_arb.c
@@ -490,9 +490,9 @@ void nvgpu_clk_arb_cleanup_arbiter(struct gk20a *g)
490 nvgpu_kfree(g, arb->vf_table_pool[index].mclk_points); 490 nvgpu_kfree(g, arb->vf_table_pool[index].mclk_points);
491 } 491 }
492 nvgpu_mutex_destroy(&g->clk_arb->pstate_lock); 492 nvgpu_mutex_destroy(&g->clk_arb->pstate_lock);
493 nvgpu_kfree(g, g->clk_arb);
494 g->clk_arb = NULL;
493 } 495 }
494 nvgpu_kfree(g, g->clk_arb);
495 g->clk_arb = NULL;
496} 496}
497 497
498static int nvgpu_clk_arb_install_fd(struct gk20a *g, 498static int nvgpu_clk_arb_install_fd(struct gk20a *g,
diff --git a/drivers/gpu/nvgpu/common/semaphore.c b/drivers/gpu/nvgpu/common/semaphore.c
index 5496f5ec..0d512e8f 100644
--- a/drivers/gpu/nvgpu/common/semaphore.c
+++ b/drivers/gpu/nvgpu/common/semaphore.c
@@ -66,11 +66,12 @@ out:
66 return ret; 66 return ret;
67} 67}
68 68
69void gk20a_semaphore_sea_destroy(struct gk20a *g) 69void nvgpu_semaphore_sea_destroy(struct gk20a *g)
70{ 70{
71 if (!g->sema_sea) 71 if (!g->sema_sea)
72 return; 72 return;
73 73
74 nvgpu_dma_free(g, &g->sema_sea->sea_mem);
74 nvgpu_mutex_destroy(&g->sema_sea->sea_lock); 75 nvgpu_mutex_destroy(&g->sema_sea->sea_lock);
75 nvgpu_kfree(g, g->sema_sea); 76 nvgpu_kfree(g, g->sema_sea);
76 g->sema_sea = NULL; 77 g->sema_sea = NULL;
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 13c62691..0cd77d1e 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -1233,6 +1233,7 @@ struct gk20a {
1233#ifdef CONFIG_DEBUG_FS 1233#ifdef CONFIG_DEBUG_FS
1234 struct debugfs_blob_wrapper bios_blob; 1234 struct debugfs_blob_wrapper bios_blob;
1235#endif 1235#endif
1236 bool bios_is_init;
1236 1237
1237 struct nvgpu_clk_arb *clk_arb; 1238 struct nvgpu_clk_arb *clk_arb;
1238 1239
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 0e0326dd..dd8b900d 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -393,7 +393,7 @@ static void gk20a_remove_mm_support(struct mm_gk20a *mm)
393 nvgpu_vm_put(mm->pmu.vm); 393 nvgpu_vm_put(mm->pmu.vm);
394 nvgpu_vm_put(mm->cde.vm); 394 nvgpu_vm_put(mm->cde.vm);
395 395
396 gk20a_semaphore_sea_destroy(g); 396 nvgpu_semaphore_sea_destroy(g);
397 gk20a_vidmem_destroy(g); 397 gk20a_vidmem_destroy(g);
398 nvgpu_pd_cache_fini(g); 398 nvgpu_pd_cache_fini(g);
399} 399}
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;
247free_debugfs:
248#ifdef CONFIG_DEBUG_FS
249 debugfs_remove(d);
250#endif
251free_firmware:
252 if (g->bios.data)
253 nvgpu_vfree(g, g->bios.data);
254 return err;
240} 255}
256
diff --git a/drivers/gpu/nvgpu/include/nvgpu/semaphore.h b/drivers/gpu/nvgpu/include/nvgpu/semaphore.h
index 5c0019ae..8915b722 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/semaphore.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/semaphore.h
@@ -160,7 +160,7 @@ struct nvgpu_semaphore_sea {
160 * Semaphore sea functions. 160 * Semaphore sea functions.
161 */ 161 */
162struct nvgpu_semaphore_sea *nvgpu_semaphore_sea_create(struct gk20a *gk20a); 162struct nvgpu_semaphore_sea *nvgpu_semaphore_sea_create(struct gk20a *gk20a);
163void gk20a_semaphore_sea_destroy(struct gk20a *g); 163void nvgpu_semaphore_sea_destroy(struct gk20a *g);
164int nvgpu_semaphore_sea_map(struct nvgpu_semaphore_pool *sea, 164int nvgpu_semaphore_sea_map(struct nvgpu_semaphore_pool *sea,
165 struct vm_gk20a *vm); 165 struct vm_gk20a *vm);
166void nvgpu_semaphore_sea_unmap(struct nvgpu_semaphore_pool *sea, 166void nvgpu_semaphore_sea_unmap(struct nvgpu_semaphore_pool *sea,