summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/channel_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/channel_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/channel_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index 73cc18d2..c09539ff 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -1234,7 +1234,7 @@ int gk20a_channel_release(struct inode *inode, struct file *filp)
1234 err = gk20a_busy(g->dev); 1234 err = gk20a_busy(g->dev);
1235 if (err) { 1235 if (err) {
1236 gk20a_err(dev_from_gk20a(g), "failed to release a channel!"); 1236 gk20a_err(dev_from_gk20a(g), "failed to release a channel!");
1237 return err; 1237 goto channel_release;
1238 } 1238 }
1239 1239
1240 trace_gk20a_channel_release(dev_name(g->dev)); 1240 trace_gk20a_channel_release(dev_name(g->dev));
@@ -1242,6 +1242,8 @@ int gk20a_channel_release(struct inode *inode, struct file *filp)
1242 gk20a_channel_close(ch); 1242 gk20a_channel_close(ch);
1243 gk20a_idle(g->dev); 1243 gk20a_idle(g->dev);
1244 1244
1245channel_release:
1246 gk20a_put(g);
1245 kfree(filp->private_data); 1247 kfree(filp->private_data);
1246 filp->private_data = NULL; 1248 filp->private_data = NULL;
1247 return 0; 1249 return 0;
@@ -1382,11 +1384,17 @@ static int __gk20a_channel_open(struct gk20a *g, struct file *filp, s32 runlist_
1382 1384
1383 gk20a_dbg_fn(""); 1385 gk20a_dbg_fn("");
1384 1386
1387 g = gk20a_get(g);
1388 if (!g)
1389 return -ENODEV;
1390
1385 trace_gk20a_channel_open(dev_name(g->dev)); 1391 trace_gk20a_channel_open(dev_name(g->dev));
1386 1392
1387 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 1393 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1388 if (!priv) 1394 if (!priv) {
1389 return -ENOMEM; 1395 err = -ENOMEM;
1396 goto free_ref;
1397 }
1390 1398
1391 err = gk20a_busy(g->dev); 1399 err = gk20a_busy(g->dev);
1392 if (err) { 1400 if (err) {
@@ -1414,6 +1422,8 @@ static int __gk20a_channel_open(struct gk20a *g, struct file *filp, s32 runlist_
1414 1422
1415fail_busy: 1423fail_busy:
1416 kfree(priv); 1424 kfree(priv);
1425free_ref:
1426 gk20a_put(g);
1417 return err; 1427 return err;
1418} 1428}
1419 1429
@@ -3509,6 +3519,7 @@ static int gk20a_event_id_release(struct inode *inode, struct file *filp)
3509 } 3519 }
3510 3520
3511 nvgpu_mutex_destroy(&event_id_data->lock); 3521 nvgpu_mutex_destroy(&event_id_data->lock);
3522 gk20a_put(g);
3512 kfree(event_id_data); 3523 kfree(event_id_data);
3513 filp->private_data = NULL; 3524 filp->private_data = NULL;
3514 3525
@@ -3573,20 +3584,28 @@ static int gk20a_channel_event_id_enable(struct channel_gk20a *ch,
3573 int event_id, 3584 int event_id,
3574 int *fd) 3585 int *fd)
3575{ 3586{
3587 struct gk20a *g;
3576 int err = 0; 3588 int err = 0;
3577 int local_fd; 3589 int local_fd;
3578 struct file *file; 3590 struct file *file;
3579 char *name; 3591 char *name;
3580 struct gk20a_event_id_data *event_id_data; 3592 struct gk20a_event_id_data *event_id_data;
3581 3593
3594 g = gk20a_get(ch->g);
3595 if (!g)
3596 return -ENODEV;
3597
3582 err = gk20a_channel_get_event_data_from_id(ch, 3598 err = gk20a_channel_get_event_data_from_id(ch,
3583 event_id, &event_id_data); 3599 event_id, &event_id_data);
3584 if (err == 0) /* We already have event enabled */ 3600 if (err == 0) {
3585 return -EINVAL; 3601 /* We already have event enabled */
3602 err = -EINVAL;
3603 goto free_ref;
3604 }
3586 3605
3587 err = get_unused_fd_flags(O_RDWR); 3606 err = get_unused_fd_flags(O_RDWR);
3588 if (err < 0) 3607 if (err < 0)
3589 return err; 3608 goto free_ref;
3590 local_fd = err; 3609 local_fd = err;
3591 3610
3592 name = kasprintf(GFP_KERNEL, "nvgpu-event%d-fd%d", 3611 name = kasprintf(GFP_KERNEL, "nvgpu-event%d-fd%d",
@@ -3605,7 +3624,7 @@ static int gk20a_channel_event_id_enable(struct channel_gk20a *ch,
3605 err = -ENOMEM; 3624 err = -ENOMEM;
3606 goto clean_up_file; 3625 goto clean_up_file;
3607 } 3626 }
3608 event_id_data->g = ch->g; 3627 event_id_data->g = g;
3609 event_id_data->id = ch->hw_chid; 3628 event_id_data->id = ch->hw_chid;
3610 event_id_data->is_tsg = false; 3629 event_id_data->is_tsg = false;
3611 event_id_data->event_id = event_id; 3630 event_id_data->event_id = event_id;
@@ -3633,6 +3652,8 @@ clean_up_file:
3633 fput(file); 3652 fput(file);
3634clean_up: 3653clean_up:
3635 put_unused_fd(local_fd); 3654 put_unused_fd(local_fd);
3655free_ref:
3656 gk20a_put(g);
3636 return err; 3657 return err;
3637} 3658}
3638 3659