aboutsummaryrefslogtreecommitdiffstats
path: root/include/os/linux/ioctl_tsg.c
diff options
context:
space:
mode:
Diffstat (limited to 'include/os/linux/ioctl_tsg.c')
-rw-r--r--include/os/linux/ioctl_tsg.c750
1 files changed, 0 insertions, 750 deletions
diff --git a/include/os/linux/ioctl_tsg.c b/include/os/linux/ioctl_tsg.c
deleted file mode 100644
index 296b02b..0000000
--- a/include/os/linux/ioctl_tsg.c
+++ /dev/null
@@ -1,750 +0,0 @@
1/*
2 * Copyright (c) 2014-2021, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <linux/fs.h>
18#include <linux/file.h>
19#include <linux/cdev.h>
20#include <linux/uaccess.h>
21#include <linux/poll.h>
22#include <uapi/linux/nvgpu.h>
23#include <linux/anon_inodes.h>
24
25#include <nvgpu/kmem.h>
26#include <nvgpu/log.h>
27#include <nvgpu/os_sched.h>
28#include <nvgpu/gk20a.h>
29#include <nvgpu/channel.h>
30#include <nvgpu/tsg.h>
31
32#include "gv11b/fifo_gv11b.h"
33#include "platform_gk20a.h"
34#include "ioctl_tsg.h"
35#include "ioctl_channel.h"
36#include "os_linux.h"
37
38struct tsg_private {
39 struct gk20a *g;
40 struct tsg_gk20a *tsg;
41};
42
43static int gk20a_tsg_bind_channel_fd(struct tsg_gk20a *tsg, int ch_fd)
44{
45 struct channel_gk20a *ch;
46 int err;
47
48 ch = gk20a_get_channel_from_file(ch_fd);
49 if (!ch)
50 return -EINVAL;
51
52 err = ch->g->ops.fifo.tsg_bind_channel(tsg, ch);
53
54 gk20a_channel_put(ch);
55 return err;
56}
57
58static int gk20a_tsg_ioctl_bind_channel_ex(struct gk20a *g,
59 struct tsg_gk20a *tsg, struct nvgpu_tsg_bind_channel_ex_args *arg)
60{
61 struct nvgpu_sched_ctrl *sched = &g->sched_ctrl;
62 struct channel_gk20a *ch;
63 struct gr_gk20a *gr = &g->gr;
64 int err = 0;
65
66 nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u", tsg->tsgid);
67
68 nvgpu_mutex_acquire(&sched->control_lock);
69 if (sched->control_locked) {
70 err = -EPERM;
71 goto mutex_release;
72 }
73 err = gk20a_busy(g);
74 if (err) {
75 nvgpu_err(g, "failed to power on gpu");
76 goto mutex_release;
77 }
78
79 ch = gk20a_get_channel_from_file(arg->channel_fd);
80 if (!ch) {
81 err = -EINVAL;
82 goto idle;
83 }
84
85 if (arg->tpc_pg_enabled && (!tsg->tpc_num_initialized)) {
86 if ((arg->num_active_tpcs > gr->max_tpc_count) ||
87 !(arg->num_active_tpcs)) {
88 nvgpu_err(g, "Invalid num of active TPCs");
89 err = -EINVAL;
90 goto ch_put;
91 }
92 tsg->tpc_num_initialized = true;
93 tsg->num_active_tpcs = arg->num_active_tpcs;
94 tsg->tpc_pg_enabled = true;
95 } else {
96 tsg->tpc_pg_enabled = false; nvgpu_log(g, gpu_dbg_info, "dynamic TPC-PG not enabled");
97 }
98
99 if (arg->subcontext_id < g->fifo.max_subctx_count) {
100 ch->subctx_id = arg->subcontext_id;
101 } else {
102 err = -EINVAL;
103 goto ch_put;
104 }
105
106 nvgpu_log(g, gpu_dbg_info, "channel id : %d : subctx: %d",
107 ch->chid, ch->subctx_id);
108
109 /* Use runqueue selector 1 for all ASYNC ids */
110 if (ch->subctx_id > CHANNEL_INFO_VEID0)
111 ch->runqueue_sel = 1;
112
113 err = ch->g->ops.fifo.tsg_bind_channel(tsg, ch);
114ch_put:
115 gk20a_channel_put(ch);
116idle:
117 gk20a_idle(g);
118mutex_release:
119 nvgpu_mutex_release(&sched->control_lock);
120 return err;
121}
122
123static 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, false);
138 if (err == -EAGAIN) {
139 goto out;
140 }
141
142 /*
143 * Mark the channel timedout since channel unbound from TSG
144 * has no context of its own so it can't serve any job
145 */
146 gk20a_channel_set_timedout(ch);
147
148out:
149 gk20a_channel_put(ch);
150 return err;
151}
152
153static int gk20a_tsg_get_event_data_from_id(struct tsg_gk20a *tsg,
154 unsigned int event_id,
155 struct gk20a_event_id_data **event_id_data)
156{
157 struct gk20a_event_id_data *local_event_id_data;
158 bool event_found = false;
159
160 nvgpu_mutex_acquire(&tsg->event_id_list_lock);
161 nvgpu_list_for_each_entry(local_event_id_data, &tsg->event_id_list,
162 gk20a_event_id_data, event_id_node) {
163 if (local_event_id_data->event_id == event_id) {
164 event_found = true;
165 break;
166 }
167 }
168 nvgpu_mutex_release(&tsg->event_id_list_lock);
169
170 if (event_found) {
171 *event_id_data = local_event_id_data;
172 return 0;
173 } else {
174 return -1;
175 }
176}
177
178/*
179 * Convert common event_id of the form NVGPU_EVENT_ID_* to Linux specific
180 * event_id of the form NVGPU_IOCTL_CHANNEL_EVENT_ID_* which is used in IOCTLs
181 */
182static u32 nvgpu_event_id_to_ioctl_channel_event_id(u32 event_id)
183{
184 switch (event_id) {
185 case NVGPU_EVENT_ID_BPT_INT:
186 return NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_INT;
187 case NVGPU_EVENT_ID_BPT_PAUSE:
188 return NVGPU_IOCTL_CHANNEL_EVENT_ID_BPT_PAUSE;
189 case NVGPU_EVENT_ID_BLOCKING_SYNC:
190 return NVGPU_IOCTL_CHANNEL_EVENT_ID_BLOCKING_SYNC;
191 case NVGPU_EVENT_ID_CILP_PREEMPTION_STARTED:
192 return NVGPU_IOCTL_CHANNEL_EVENT_ID_CILP_PREEMPTION_STARTED;
193 case NVGPU_EVENT_ID_CILP_PREEMPTION_COMPLETE:
194 return NVGPU_IOCTL_CHANNEL_EVENT_ID_CILP_PREEMPTION_COMPLETE;
195 case NVGPU_EVENT_ID_GR_SEMAPHORE_WRITE_AWAKEN:
196 return NVGPU_IOCTL_CHANNEL_EVENT_ID_GR_SEMAPHORE_WRITE_AWAKEN;
197 }
198
199 return NVGPU_IOCTL_CHANNEL_EVENT_ID_MAX;
200}
201
202void gk20a_tsg_event_id_post_event(struct tsg_gk20a *tsg,
203 int __event_id)
204{
205 struct gk20a_event_id_data *event_id_data;
206 u32 event_id;
207 int err = 0;
208 struct gk20a *g = tsg->g;
209
210 event_id = nvgpu_event_id_to_ioctl_channel_event_id(__event_id);
211 if (event_id >= NVGPU_IOCTL_CHANNEL_EVENT_ID_MAX)
212 return;
213
214 err = gk20a_tsg_get_event_data_from_id(tsg, event_id,
215 &event_id_data);
216 if (err)
217 return;
218
219 nvgpu_mutex_acquire(&event_id_data->lock);
220
221 nvgpu_log_info(g,
222 "posting event for event_id=%d on tsg=%d\n",
223 event_id, tsg->tsgid);