diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2018-05-05 11:10:48 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-05-10 05:13:58 -0400 |
commit | 90b2f780d414d993571dceccafbc01b371068782 (patch) | |
tree | 22eacf1ab70196ab9373ebe903e881bc05d22352 /drivers | |
parent | 6ad9862657469e7dac343d7857f907967f6d4c76 (diff) |
gpu: nvgpu: support TSG IOCTL to unbind channel
We so far do not support unbinding a channel from TSG explicitly through IOCTL
Channel is unbound from TSG when channel fd is closed
But this could create issue in case process is forked and fd is duplicated
In worst case it is possible that duplicate fd is closed sometime later when
TSG is active and that could lead to corruption of TSG state
Fix this by implementing NVGPU_TSG_IOCTL_UNBIND_CHANNEL API
This API will simply call gk20a_tsg_unbind_channel() API to unbind the
channel
Note that we also mark the channel has_timedout since unbound channel does
not have any context of its own and it cannot serve any job
Remove call to gk20a_disable_channel() while closing the channel.
We do not support bare channels without TSG, and if channel is not part of TSG
then it means channel is already unbound from TSG with call to
NVGPU_TSG_IOCTL_UNBIND_CHANNEL, and there is nothing to do while closing the
channel
Bug 200327095
Jira NVGPU-229
Change-Id: Ib7f6710f0dc8125caafabe7bee737622c3dd9fa3
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1708902
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/ioctl_tsg.c | 46 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 6 |
2 files changed, 48 insertions, 4 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_tsg.c b/drivers/gpu/nvgpu/common/linux/ioctl_tsg.c index d0bfd55a..4ef99ded 100644 --- a/drivers/gpu/nvgpu/common/linux/ioctl_tsg.c +++ b/drivers/gpu/nvgpu/common/linux/ioctl_tsg.c | |||
@@ -120,6 +120,33 @@ mutex_release: | |||
120 | return err; | 120 | return err; |
121 | } | 121 | } |
122 | 122 | ||
123 | static int gk20a_tsg_unbind_channel_fd(struct tsg_gk20a *tsg, int ch_fd) | ||
124 | { | ||
125 | struct channel_gk20a *ch; | ||
126 | int err = 0; | ||
127 | |||
128 | ch = gk20a_get_channel_from_file(ch_fd); | ||
129 | if (!ch) | ||
130 | return -EINVAL; | ||
131 | |||
132 | if (ch->tsgid != tsg->tsgid) { | ||
133 | err = -EINVAL; | ||
134 | goto out; | ||
135 | } | ||
136 | |||
137 | err = gk20a_tsg_unbind_channel(ch); | ||
138 | |||
139 | /* | ||
140 | * Mark the channel timedout since channel unbound from TSG | ||
141 | * has no context of its own so it can't serve any job | ||
142 | */ | ||
143 | ch->has_timedout = true; | ||
144 | |||
145 | out: | ||
146 | gk20a_channel_put(ch); | ||
147 | return err; | ||
148 | } | ||
149 | |||
123 | static int gk20a_tsg_get_event_data_from_id(struct tsg_gk20a *tsg, | 150 | static int gk20a_tsg_get_event_data_from_id(struct tsg_gk20a *tsg, |
124 | unsigned int event_id, | 151 | unsigned int event_id, |
125 | struct gk20a_event_id_data **event_id_data) | 152 | struct gk20a_event_id_data **event_id_data) |
@@ -552,10 +579,23 @@ long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, unsigned int cmd, | |||
552 | } | 579 | } |
553 | 580 | ||
554 | case NVGPU_TSG_IOCTL_UNBIND_CHANNEL: | 581 | case NVGPU_TSG_IOCTL_UNBIND_CHANNEL: |
555 | /* We do not support explicitly unbinding channel from TSG. | 582 | { |
556 | * Channel will be unbounded from TSG when it is closed. | 583 | int ch_fd = *(int *)buf; |
557 | */ | 584 | |
585 | if (ch_fd < 0) { | ||
586 | err = -EINVAL; | ||
587 | break; | ||
588 | } | ||
589 | err = gk20a_busy(g); | ||
590 | if (err) { | ||
591 | nvgpu_err(g, | ||
592 | "failed to host gk20a for ioctl cmd: 0x%x", cmd); | ||
593 | break; | ||
594 | } | ||
595 | err = gk20a_tsg_unbind_channel_fd(tsg, ch_fd); | ||
596 | gk20a_idle(g); | ||
558 | break; | 597 | break; |
598 | } | ||
559 | 599 | ||
560 | case NVGPU_IOCTL_TSG_ENABLE: | 600 | case NVGPU_IOCTL_TSG_ENABLE: |
561 | { | 601 | { |
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 21abdf9a..0c199146 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -314,7 +314,11 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force) | |||
314 | "failed to unbind channel %d from TSG", | 314 | "failed to unbind channel %d from TSG", |
315 | ch->chid); | 315 | ch->chid); |
316 | } else { | 316 | } else { |
317 | gk20a_disable_channel(ch); | 317 | /* |
318 | * Channel is already unbound from TSG by User with | ||
319 | * explicit call | ||
320 | * Nothing to do here in that case | ||
321 | */ | ||
318 | } | 322 | } |
319 | } | 323 | } |
320 | /* wait until there's only our ref to the channel */ | 324 | /* wait until there's only our ref to the channel */ |