summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c18
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.h2
-rw-r--r--drivers/gpu/nvgpu/gk20a/tsg_gk20a.c126
-rw-r--r--drivers/gpu/nvgpu/gk20a/tsg_gk20a.h3
-rw-r--r--include/uapi/linux/nvgpu.h8
5 files changed, 152 insertions, 5 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index be9c7cd4..4ad9d85b 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -2506,7 +2506,13 @@ unsigned int gk20a_event_id_poll(struct file *filep, poll_table *wait)
2506 2506
2507 mutex_lock(&event_id_data->lock); 2507 mutex_lock(&event_id_data->lock);
2508 2508
2509 if (!event_id_data->is_tsg) { 2509 if (event_id_data->is_tsg) {
2510 struct tsg_gk20a *tsg = g->fifo.tsg + event_id_data->id;
2511
2512 gk20a_dbg_info(
2513 "found pending event_id=%d on TSG=%d\n",
2514 event_id, tsg->tsgid);
2515 } else {
2510 struct channel_gk20a *ch = g->fifo.channel 2516 struct channel_gk20a *ch = g->fifo.channel
2511 + event_id_data->id; 2517 + event_id_data->id;
2512 2518
@@ -2526,7 +2532,13 @@ int gk20a_event_id_release(struct inode *inode, struct file *filp)
2526 struct gk20a_event_id_data *event_id_data = filp->private_data; 2532 struct gk20a_event_id_data *event_id_data = filp->private_data;
2527 struct gk20a *g = event_id_data->g; 2533 struct gk20a *g = event_id_data->g;
2528 2534
2529 if (!event_id_data->is_tsg) { 2535 if (event_id_data->is_tsg) {
2536 struct tsg_gk20a *tsg = g->fifo.tsg + event_id_data->id;
2537
2538 mutex_lock(&tsg->event_id_list_lock);
2539 list_del_init(&event_id_data->event_id_node);
2540 mutex_unlock(&tsg->event_id_list_lock);
2541 } else {
2530 struct channel_gk20a *ch = g->fifo.channel + event_id_data->id; 2542 struct channel_gk20a *ch = g->fifo.channel + event_id_data->id;
2531 2543
2532 mutex_lock(&ch->event_id_list_lock); 2544 mutex_lock(&ch->event_id_list_lock);
@@ -2540,7 +2552,7 @@ int gk20a_event_id_release(struct inode *inode, struct file *filp)
2540 return 0; 2552 return 0;
2541} 2553}
2542 2554
2543static const struct file_operations gk20a_event_id_ops = { 2555const struct file_operations gk20a_event_id_ops = {
2544 .owner = THIS_MODULE, 2556 .owner = THIS_MODULE,
2545 .poll = gk20a_event_id_poll, 2557 .poll = gk20a_event_id_poll,
2546 .release = gk20a_event_id_release, 2558 .release = gk20a_event_id_release,
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
index cbe0fd59..577e3861 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
@@ -38,6 +38,8 @@ struct gk20a_fence;
38#include "gr_gk20a.h" 38#include "gr_gk20a.h"
39#include "fence_gk20a.h" 39#include "fence_gk20a.h"
40 40
41extern const struct file_operations gk20a_event_id_ops;
42
41struct notification { 43struct notification {
42 struct { 44 struct {
43 u32 nanoseconds[2]; 45 u32 nanoseconds[2];
diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
index b41cca08..a0232a69 100644
--- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.c
@@ -153,6 +153,9 @@ int gk20a_init_tsg_support(struct gk20a *g, u32 tsgid)
153 INIT_LIST_HEAD(&tsg->ch_list); 153 INIT_LIST_HEAD(&tsg->ch_list);
154 mutex_init(&tsg->ch_list_lock); 154 mutex_init(&tsg->ch_list_lock);
155 155
156 INIT_LIST_HEAD(&tsg->event_id_list);
157 mutex_init(&tsg->event_id_list_lock);
158
156 return 0; 159 return 0;
157} 160}
158 161
@@ -184,6 +187,122 @@ static int gk20a_tsg_set_priority(struct gk20a *g, struct tsg_gk20a *tsg,
184 return 0; 187 return 0;
185} 188}
186 189
190static int gk20a_tsg_get_event_data_from_id(struct tsg_gk20a *tsg,
191 int event_id,
192 struct gk20a_event_id_data **event_id_data)
193{
194 struct gk20a_event_id_data *local_event_id_data;
195 bool event_found = false;
196
197 mutex_lock(&tsg->event_id_list_lock);
198 list_for_each_entry(local_event_id_data, &tsg->event_id_list,
199 event_id_node) {
200 if (local_event_id_data->event_id == event_id) {
201 event_found = true;
202 break;
203 }
204 }
205 mutex_unlock(&tsg->event_id_list_lock);
206
207 if (event_found) {
208 *event_id_data = local_event_id_data;
209 return 0;
210 } else {
211 return -1;
212 }
213}
214
215static int gk20a_tsg_event_id_enable(struct tsg_gk20a *tsg,
216 int event_id,
217 int *fd)
218{
219 int err = 0;
220 int local_fd;
221 struct file *file;
222 char *name;
223 struct gk20a_event_id_data *event_id_data;
224
225 err = gk20a_tsg_get_event_data_from_id(tsg,
226 event_id, &event_id_data);
227 if (err == 0) /* We already have event enabled */
228 return -EINVAL;
229
230 err = get_unused_fd_flags(O_RDWR);
231 if (err < 0)
232 return err;
233 local_fd = err;
234
235 name = kasprintf(GFP_KERNEL, "nvgpu-event%d-fd%d",
236 event_id, local_fd);
237
238 file = anon_inode_getfile(name, &gk20a_event_id_ops,
239 NULL, O_RDWR);
240 kfree(name);
241 if (IS_ERR(file)) {
242 err = PTR_ERR(file);
243 goto clean_up;
244 }
245
246 event_id_data = kzalloc(sizeof(*event_id_data), GFP_KERNEL);
247 if (!event_id_data) {
248 err = -ENOMEM;
249 goto clean_up_file;
250 }
251 event_id_data->g = tsg->g;
252 event_id_data->id = tsg->tsgid;
253 event_id_data->is_tsg = true;
254 event_id_data->event_id = event_id;
255
256 init_waitqueue_head(&event_id_data->event_id_wq);
257 mutex_init(&event_id_data->lock);
258 INIT_LIST_HEAD(&event_id_data->event_id_node);
259
260 mutex_lock(&tsg->event_id_list_lock);
261 list_add_tail(&event_id_data->event_id_node, &tsg->event_id_list);
262 mutex_unlock(&tsg->event_id_list_lock);
263
264 fd_install(local_fd, file);
265 file->private_data = event_id_data;
266
267 *fd = local_fd;
268
269 return 0;
270
271clean_up_file:
272 fput(file);
273clean_up:
274 put_unused_fd(local_fd);
275 return err;
276}
277
278static int gk20a_tsg_event_id_ctrl(struct gk20a *g, struct tsg_gk20a *tsg,
279 struct nvgpu_event_id_ctrl_args *args)
280{
281 int err = 0;
282 int fd = -1;
283
284 if (args->event_id < 0 ||
285 args->event_id >= NVGPU_IOCTL_CHANNEL_EVENT_ID_MAX)
286 return -EINVAL;
287
288 switch (args->cmd) {
289 case NVGPU_IOCTL_CHANNEL_EVENT_ID_CMD_ENABLE:
290 err = gk20a_tsg_event_id_enable(tsg, args->event_id, &fd);
291 if (!err)
292 args->event_fd = fd;
293 break;
294
295 default:
296 gk20a_err(dev_from_gk20a(tsg->g),
297 "unrecognized tsg event id cmd: 0x%x",
298 args->cmd);
299 err = -EINVAL;
300 break;
301 }
302
303 return err;
304}
305
187static void release_used_tsg(struct fifo_gk20a *f, struct tsg_gk20a *tsg) 306static void release_used_tsg(struct fifo_gk20a *f, struct tsg_gk20a *tsg)
188{ 307{
189 mutex_lock(&f->tsg_inuse_mutex); 308 mutex_lock(&f->tsg_inuse_mutex);
@@ -372,6 +491,13 @@ long gk20a_tsg_dev_ioctl(struct file *filp, unsigned int cmd,
372 break; 491 break;
373 } 492 }
374 493
494 case NVGPU_IOCTL_TSG_EVENT_ID_CTRL:
495 {
496 err = gk20a_tsg_event_id_ctrl(g, tsg,
497 (struct nvgpu_event_id_ctrl_args *)buf);
498 break;
499 }
500
375 default: 501 default:
376 gk20a_err(dev_from_gk20a(g), 502 gk20a_err(dev_from_gk20a(g),
377 "unrecognized tsg gpu ioctl cmd: 0x%x", 503 "unrecognized tsg gpu ioctl cmd: 0x%x",
diff --git a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h
index 7e0a75d1..ac872e30 100644
--- a/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/tsg_gk20a.h
@@ -51,6 +51,9 @@ struct tsg_gk20a {
51 struct vm_gk20a *vm; 51 struct vm_gk20a *vm;
52 52
53 u32 interleave_level; 53 u32 interleave_level;
54
55 struct list_head event_id_list;
56 struct mutex event_id_list_lock;
54}; 57};
55 58
56int gk20a_enable_tsg(struct tsg_gk20a *tsg); 59int gk20a_enable_tsg(struct tsg_gk20a *tsg);
diff --git a/include/uapi/linux/nvgpu.h b/include/uapi/linux/nvgpu.h
index 6fed9e9f..45d1c217 100644
--- a/include/uapi/linux/nvgpu.h
+++ b/include/uapi/linux/nvgpu.h
@@ -448,11 +448,15 @@ struct nvgpu_gpu_get_cpu_time_correlation_info_args {
448 _IO(NVGPU_TSG_IOCTL_MAGIC, 5) 448 _IO(NVGPU_TSG_IOCTL_MAGIC, 5)
449#define NVGPU_IOCTL_TSG_SET_PRIORITY \ 449#define NVGPU_IOCTL_TSG_SET_PRIORITY \
450 _IOW(NVGPU_TSG_IOCTL_MAGIC, 6, struct nvgpu_set_priority_args) 450 _IOW(NVGPU_TSG_IOCTL_MAGIC, 6, struct nvgpu_set_priority_args)
451#define NVGPU_IOCTL_TSG_EVENT_ID_CTRL \
452 _IOWR(NVGPU_TSG_IOCTL_MAGIC, 7, struct nvgpu_event_id_ctrl_args)
451 453
452#define NVGPU_TSG_IOCTL_MAX_ARG_SIZE \ 454#define NVGPU_TSG_IOCTL_MAX_ARG_SIZE \
453 sizeof(struct nvgpu_set_priority_args) 455 sizeof(struct nvgpu_event_id_ctrl_args)
454#define NVGPU_TSG_IOCTL_LAST \ 456#define NVGPU_TSG_IOCTL_LAST \
455 _IOC_NR(NVGPU_IOCTL_TSG_SET_PRIORITY) 457 _IOC_NR(NVGPU_IOCTL_TSG_EVENT_ID_CTRL)
458
459
456/* 460/*
457 * /dev/nvhost-dbg-gpu device 461 * /dev/nvhost-dbg-gpu device
458 * 462 *