summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
diff options
context:
space:
mode:
authorDavid Nieto <dmartineznie@nvidia.com>2017-02-13 14:22:59 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-03-20 19:39:55 -0400
commit74fe1caa2b56aab24c17ad4dd2524128fc237894 (patch)
tree0793bb92b67d64690658f3f7cd1a8e1ea93206ba /drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
parent469308becaff326da02fcf791e803e812e1cf9f8 (diff)
gpu: nvgpu: Add refcounting to driver fds
The main driver structure is not refcounted properly, so when the driver unload, file desciptors associated to the driver are kept open with dangling references to the main object. This change adds referencing to the gk20a structure. bug 200277762 JIRA: EVLR-1023 Change-Id: Id892e9e1677a344789e99bf649088c076f0bf8de Signed-off-by: David Nieto <dmartineznie@nvidia.com> Reviewed-on: http://git-master/r/1317420 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/tsg_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/tsg_gk20a.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
index e1424f2b..270fed85 100644
--- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
@@ -259,15 +259,23 @@ static int gk20a_tsg_event_id_enable(struct tsg_gk20a *tsg,
259 struct file *file; 259 struct file *file;
260 char *name; 260 char *name;
261 struct gk20a_event_id_data *event_id_data; 261 struct gk20a_event_id_data *event_id_data;
262 struct gk20a *g;
263
264 g = gk20a_get(tsg->g);
265 if (!g)
266 return -ENODEV;
262 267
263 err = gk20a_tsg_get_event_data_from_id(tsg, 268 err = gk20a_tsg_get_event_data_from_id(tsg,
264 event_id, &event_id_data); 269 event_id, &event_id_data);
265 if (err == 0) /* We already have event enabled */ 270 if (err == 0) {
266 return -EINVAL; 271 /* We already have event enabled */
272 err = -EINVAL;
273 goto free_ref;
274 }
267 275
268 err = get_unused_fd_flags(O_RDWR); 276 err = get_unused_fd_flags(O_RDWR);
269 if (err < 0) 277 if (err < 0)
270 return err; 278 goto free_ref;
271 local_fd = err; 279 local_fd = err;
272 280
273 name = kasprintf(GFP_KERNEL, "nvgpu-event%d-fd%d", 281 name = kasprintf(GFP_KERNEL, "nvgpu-event%d-fd%d",
@@ -286,7 +294,7 @@ static int gk20a_tsg_event_id_enable(struct tsg_gk20a *tsg,
286 err = -ENOMEM; 294 err = -ENOMEM;
287 goto clean_up_file; 295 goto clean_up_file;
288 } 296 }
289 event_id_data->g = tsg->g; 297 event_id_data->g = g;
290 event_id_data->id = tsg->tsgid; 298 event_id_data->id = tsg->tsgid;
291 event_id_data->is_tsg = true; 299 event_id_data->is_tsg = true;
292 event_id_data->event_id = event_id; 300 event_id_data->event_id = event_id;
@@ -315,6 +323,8 @@ clean_up_file:
315 fput(file); 323 fput(file);
316clean_up: 324clean_up:
317 put_unused_fd(local_fd); 325 put_unused_fd(local_fd);
326free_ref:
327 gk20a_put(g);
318 return err; 328 return err;
319} 329}
320 330
@@ -410,18 +420,25 @@ int gk20a_tsg_open(struct gk20a *g, struct file *filp)
410 struct device *dev; 420 struct device *dev;
411 int err; 421 int err;
412 422
423 g = gk20a_get(g);
424 if (!g)
425 return -ENODEV;
426
413 dev = dev_from_gk20a(g); 427 dev = dev_from_gk20a(g);
414 428
415 gk20a_dbg(gpu_dbg_fn, "tsg: %s", dev_name(dev)); 429 gk20a_dbg(gpu_dbg_fn, "tsg: %s", dev_name(dev));
416 430
417 priv = kmalloc(sizeof(*priv), GFP_KERNEL); 431 priv = kmalloc(sizeof(*priv), GFP_KERNEL);
418 if (!priv) 432 if (!priv) {
419 return -ENOMEM; 433 err = -ENOMEM;
434 goto free_ref;
435 }
420 436
421 tsg = acquire_unused_tsg(&g->fifo); 437 tsg = acquire_unused_tsg(&g->fifo);
422 if (!tsg) { 438 if (!tsg) {
423 kfree(priv); 439 kfree(priv);
424 return -ENOMEM; 440 err = -ENOMEM;
441 goto free_ref;
425 } 442 }
426 443
427 tsg->g = g; 444 tsg->g = g;
@@ -458,6 +475,8 @@ int gk20a_tsg_open(struct gk20a *g, struct file *filp)
458 475
459clean_up: 476clean_up:
460 kref_put(&tsg->refcount, gk20a_tsg_release); 477 kref_put(&tsg->refcount, gk20a_tsg_release);
478free_ref:
479 gk20a_put(g);
461 return err; 480 return err;
462} 481}
463 482
@@ -505,16 +524,13 @@ void gk20a_tsg_release(struct kref *ref)
505 tsg->runlist_id = ~0; 524 tsg->runlist_id = ~0;
506 525
507 gk20a_dbg(gpu_dbg_fn, "tsg released %d\n", tsg->tsgid); 526 gk20a_dbg(gpu_dbg_fn, "tsg released %d\n", tsg->tsgid);
527 gk20a_put(g);
508} 528}
509 529
510int gk20a_tsg_dev_release(struct inode *inode, struct file *filp) 530int gk20a_tsg_dev_release(struct inode *inode, struct file *filp)
511{ 531{
512 struct tsg_private *priv = filp->private_data; 532 struct tsg_private *priv = filp->private_data;
513 struct tsg_gk20a *tsg = priv->tsg; 533 struct tsg_gk20a *tsg = priv->tsg;
514 struct gk20a *g = priv->g;
515
516 if (g->driver_is_dying)
517 return -ENODEV;
518 534
519 kref_put(&tsg->refcount, gk20a_tsg_release); 535 kref_put(&tsg->refcount, gk20a_tsg_release);
520 kfree(priv); 536 kfree(priv);