diff options
author | David Nieto <dmartineznie@nvidia.com> | 2017-02-13 14:22:59 -0500 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-03-20 19:39:55 -0400 |
commit | 74fe1caa2b56aab24c17ad4dd2524128fc237894 (patch) | |
tree | 0793bb92b67d64690658f3f7cd1a8e1ea93206ba /drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |
parent | 469308becaff326da02fcf791e803e812e1cf9f8 (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.c | 35 |
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 | ||
1245 | channel_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 | ||
1415 | fail_busy: | 1423 | fail_busy: |
1416 | kfree(priv); | 1424 | kfree(priv); |
1425 | free_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); |
3634 | clean_up: | 3653 | clean_up: |
3635 | put_unused_fd(local_fd); | 3654 | put_unused_fd(local_fd); |
3655 | free_ref: | ||
3656 | gk20a_put(g); | ||
3636 | return err; | 3657 | return err; |
3637 | } | 3658 | } |
3638 | 3659 | ||