diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/channel.c | 79 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/channel.h | 15 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/ioctl_channel.c | 21 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c | 21 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/module.c | 16 |
5 files changed, 140 insertions, 12 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/channel.c b/drivers/gpu/nvgpu/common/linux/channel.c index a360d0df..8f2adc3a 100644 --- a/drivers/gpu/nvgpu/common/linux/channel.c +++ b/drivers/gpu/nvgpu/common/linux/channel.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <trace/events/gk20a.h> | 40 | #include <trace/events/gk20a.h> |
41 | #include <uapi/linux/nvgpu.h> | 41 | #include <uapi/linux/nvgpu.h> |
42 | 42 | ||
43 | #include "gk20a/sync_gk20a.h" | ||
44 | |||
43 | u32 nvgpu_submit_gpfifo_user_flags_to_common_flags(u32 user_flags) | 45 | u32 nvgpu_submit_gpfifo_user_flags_to_common_flags(u32 user_flags) |
44 | { | 46 | { |
45 | u32 flags = 0; | 47 | u32 flags = 0; |
@@ -292,6 +294,10 @@ static int nvgpu_channel_alloc_linux(struct gk20a *g, struct channel_gk20a *ch) | |||
292 | ch->os_priv = priv; | 294 | ch->os_priv = priv; |
293 | priv->ch = ch; | 295 | priv->ch = ch; |
294 | 296 | ||
297 | #ifdef CONFIG_SYNC | ||
298 | ch->has_os_fence_framework_support = true; | ||
299 | #endif | ||
300 | |||
295 | err = nvgpu_mutex_init(&priv->error_notifier.mutex); | 301 | err = nvgpu_mutex_init(&priv->error_notifier.mutex); |
296 | if (err) { | 302 | if (err) { |
297 | nvgpu_kfree(g, priv); | 303 | nvgpu_kfree(g, priv); |
@@ -309,6 +315,64 @@ static void nvgpu_channel_free_linux(struct gk20a *g, struct channel_gk20a *ch) | |||
309 | 315 | ||
310 | nvgpu_mutex_destroy(&priv->error_notifier.mutex); | 316 | nvgpu_mutex_destroy(&priv->error_notifier.mutex); |
311 | nvgpu_kfree(g, priv); | 317 | nvgpu_kfree(g, priv); |
318 | |||
319 | ch->os_priv = NULL; | ||
320 | |||
321 | #ifdef CONFIG_SYNC | ||
322 | ch->has_os_fence_framework_support = false; | ||
323 | #endif | ||
324 | } | ||
325 | |||
326 | static int nvgpu_channel_init_os_fence_framework(struct channel_gk20a *ch, | ||
327 | const char *fmt, ...) | ||
328 | { | ||
329 | struct nvgpu_channel_linux *priv = ch->os_priv; | ||
330 | struct nvgpu_os_fence_framework *fence_framework; | ||
331 | char name[30]; | ||
332 | va_list args; | ||
333 | |||
334 | fence_framework = &priv->fence_framework; | ||
335 | |||
336 | va_start(args, fmt); | ||
337 | vsnprintf(name, sizeof(name), fmt, args); | ||
338 | va_end(args); | ||
339 | |||
340 | fence_framework->timeline = gk20a_sync_timeline_create(name); | ||
341 | |||
342 | if (!fence_framework->timeline) | ||
343 | return -EINVAL; | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | static void nvgpu_channel_signal_os_fence_framework(struct channel_gk20a *ch) | ||
348 | { | ||
349 | struct nvgpu_channel_linux *priv = ch->os_priv; | ||
350 | struct nvgpu_os_fence_framework *fence_framework; | ||
351 | |||
352 | fence_framework = &priv->fence_framework; | ||
353 | |||
354 | gk20a_sync_timeline_signal(fence_framework->timeline); | ||
355 | } | ||
356 | |||
357 | static void nvgpu_channel_destroy_os_fence_framework(struct channel_gk20a *ch) | ||
358 | { | ||
359 | struct nvgpu_channel_linux *priv = ch->os_priv; | ||
360 | struct nvgpu_os_fence_framework *fence_framework; | ||
361 | |||
362 | fence_framework = &priv->fence_framework; | ||
363 | |||
364 | gk20a_sync_timeline_destroy(fence_framework->timeline); | ||
365 | fence_framework->timeline = NULL; | ||
366 | } | ||
367 | |||
368 | static bool nvgpu_channel_fence_framework_exists(struct channel_gk20a *ch) | ||
369 | { | ||
370 | struct nvgpu_channel_linux *priv = ch->os_priv; | ||
371 | struct nvgpu_os_fence_framework *fence_framework; | ||
372 | |||
373 | fence_framework = &priv->fence_framework; | ||
374 | |||
375 | return (fence_framework->timeline != NULL); | ||
312 | } | 376 | } |
313 | 377 | ||
314 | int nvgpu_init_channel_support_linux(struct nvgpu_os_linux *l) | 378 | int nvgpu_init_channel_support_linux(struct nvgpu_os_linux *l) |
@@ -332,6 +396,16 @@ int nvgpu_init_channel_support_linux(struct nvgpu_os_linux *l) | |||
332 | nvgpu_channel_work_completion_signal; | 396 | nvgpu_channel_work_completion_signal; |
333 | g->os_channel.work_completion_cancel_sync = | 397 | g->os_channel.work_completion_cancel_sync = |
334 | nvgpu_channel_work_completion_cancel_sync; | 398 | nvgpu_channel_work_completion_cancel_sync; |
399 | |||
400 | g->os_channel.os_fence_framework_inst_exists = | ||
401 | nvgpu_channel_fence_framework_exists; | ||
402 | g->os_channel.init_os_fence_framework = | ||
403 | nvgpu_channel_init_os_fence_framework; | ||
404 | g->os_channel.signal_os_fence_framework = | ||
405 | nvgpu_channel_signal_os_fence_framework; | ||
406 | g->os_channel.destroy_os_fence_framework = | ||
407 | nvgpu_channel_destroy_os_fence_framework; | ||
408 | |||
335 | return 0; | 409 | return 0; |
336 | 410 | ||
337 | err_clean: | 411 | err_clean: |
@@ -354,6 +428,11 @@ void nvgpu_remove_channel_support_linux(struct nvgpu_os_linux *l) | |||
354 | 428 | ||
355 | nvgpu_channel_free_linux(g, ch); | 429 | nvgpu_channel_free_linux(g, ch); |
356 | } | 430 | } |
431 | |||
432 | g->os_channel.os_fence_framework_inst_exists = NULL; | ||
433 | g->os_channel.init_os_fence_framework = NULL; | ||
434 | g->os_channel.signal_os_fence_framework = NULL; | ||
435 | g->os_channel.destroy_os_fence_framework = NULL; | ||
357 | } | 436 | } |
358 | 437 | ||
359 | u32 nvgpu_get_gpfifo_entry_size(void) | 438 | u32 nvgpu_get_gpfifo_entry_size(void) |
diff --git a/drivers/gpu/nvgpu/common/linux/channel.h b/drivers/gpu/nvgpu/common/linux/channel.h index d4cb6d55..805de55a 100644 --- a/drivers/gpu/nvgpu/common/linux/channel.h +++ b/drivers/gpu/nvgpu/common/linux/channel.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. | 2 | * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 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, | 5 | * under the terms and conditions of the GNU General Public License, |
@@ -29,6 +29,9 @@ struct gk20a_fence; | |||
29 | struct fifo_profile_gk20a; | 29 | struct fifo_profile_gk20a; |
30 | struct nvgpu_os_linux; | 30 | struct nvgpu_os_linux; |
31 | 31 | ||
32 | struct sync_fence; | ||
33 | struct sync_timeline; | ||
34 | |||
32 | struct nvgpu_channel_completion_cb { | 35 | struct nvgpu_channel_completion_cb { |
33 | /* | 36 | /* |
34 | * Signal channel owner via a callback, if set, in job cleanup with | 37 | * Signal channel owner via a callback, if set, in job cleanup with |
@@ -52,9 +55,19 @@ struct nvgpu_error_notifier { | |||
52 | struct nvgpu_mutex mutex; | 55 | struct nvgpu_mutex mutex; |
53 | }; | 56 | }; |
54 | 57 | ||
58 | /* | ||
59 | * This struct contains fence_related data. | ||
60 | * e.g. sync_timeline for sync_fences. | ||
61 | */ | ||
62 | struct nvgpu_os_fence_framework { | ||
63 | struct sync_timeline *timeline; | ||
64 | }; | ||
65 | |||
55 | struct nvgpu_channel_linux { | 66 | struct nvgpu_channel_linux { |
56 | struct channel_gk20a *ch; | 67 | struct channel_gk20a *ch; |
57 | 68 | ||
69 | struct nvgpu_os_fence_framework fence_framework; | ||
70 | |||
58 | struct nvgpu_channel_completion_cb completion_cb; | 71 | struct nvgpu_channel_completion_cb completion_cb; |
59 | struct nvgpu_error_notifier error_notifier; | 72 | struct nvgpu_error_notifier error_notifier; |
60 | 73 | ||
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_channel.c b/drivers/gpu/nvgpu/common/linux/ioctl_channel.c index b4d7d501..06dfb180 100644 --- a/drivers/gpu/nvgpu/common/linux/ioctl_channel.c +++ b/drivers/gpu/nvgpu/common/linux/ioctl_channel.c | |||
@@ -774,6 +774,7 @@ static int gk20a_ioctl_channel_submit_gpfifo( | |||
774 | struct gk20a_fence *fence_out; | 774 | struct gk20a_fence *fence_out; |
775 | struct fifo_profile_gk20a *profile = NULL; | 775 | struct fifo_profile_gk20a *profile = NULL; |
776 | u32 submit_flags = 0; | 776 | u32 submit_flags = 0; |
777 | int fd = -1; | ||
777 | 778 | ||
778 | int ret = 0; | 779 | int ret = 0; |
779 | gk20a_dbg_fn(""); | 780 | gk20a_dbg_fn(""); |
@@ -794,19 +795,31 @@ static int gk20a_ioctl_channel_submit_gpfifo( | |||
794 | nvgpu_get_fence_args(&args->fence, &fence); | 795 | nvgpu_get_fence_args(&args->fence, &fence); |
795 | submit_flags = | 796 | submit_flags = |
796 | nvgpu_submit_gpfifo_user_flags_to_common_flags(args->flags); | 797 | nvgpu_submit_gpfifo_user_flags_to_common_flags(args->flags); |
798 | |||
799 | /* Try and allocate an fd here*/ | ||
800 | if ((args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_GET) | ||
801 | && (args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SYNC_FENCE)) { | ||
802 | fd = get_unused_fd_flags(O_RDWR); | ||
803 | if (fd < 0) | ||
804 | return fd; | ||
805 | } | ||
806 | |||
797 | ret = gk20a_submit_channel_gpfifo(ch, NULL, args, args->num_entries, | 807 | ret = gk20a_submit_channel_gpfifo(ch, NULL, args, args->num_entries, |
798 | submit_flags, &fence, | 808 | submit_flags, &fence, |
799 | &fence_out, false, profile); | 809 | &fence_out, false, profile); |
800 | 810 | ||
801 | if (ret) | 811 | if (ret) { |
812 | if (fd != -1) | ||
813 | put_unused_fd(fd); | ||
802 | goto clean_up; | 814 | goto clean_up; |
815 | } | ||
803 | 816 | ||
804 | /* Convert fence_out to something we can pass back to user space. */ | 817 | /* Convert fence_out to something we can pass back to user space. */ |
805 | if (args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_GET) { | 818 | if (args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_FENCE_GET) { |
806 | if (args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SYNC_FENCE) { | 819 | if (args->flags & NVGPU_SUBMIT_GPFIFO_FLAGS_SYNC_FENCE) { |
807 | int fd = gk20a_fence_install_fd(fence_out); | 820 | ret = gk20a_fence_install_fd(fence_out, fd); |
808 | if (fd < 0) | 821 | if (ret) |
809 | ret = fd; | 822 | put_unused_fd(fd); |
810 | else | 823 | else |
811 | args->fence.id = fd; | 824 | args->fence.id = fd; |
812 | } else { | 825 | } else { |
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c index e4b66460..70707a5c 100644 --- a/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c | |||
@@ -344,10 +344,19 @@ static int gk20a_ctrl_prepare_compressible_read( | |||
344 | struct gk20a_fence *fence_out = NULL; | 344 | struct gk20a_fence *fence_out = NULL; |
345 | int submit_flags = nvgpu_submit_gpfifo_user_flags_to_common_flags( | 345 | int submit_flags = nvgpu_submit_gpfifo_user_flags_to_common_flags( |
346 | args->submit_flags); | 346 | args->submit_flags); |
347 | int fd = -1; | ||
347 | 348 | ||
348 | fence.id = args->fence.syncpt_id; | 349 | fence.id = args->fence.syncpt_id; |
349 | fence.value = args->fence.syncpt_value; | 350 | fence.value = args->fence.syncpt_value; |
350 | 351 | ||
352 | /* Try and allocate an fd here*/ | ||
353 | if ((submit_flags & NVGPU_SUBMIT_FLAGS_FENCE_GET) | ||
354 | && (submit_flags & NVGPU_SUBMIT_FLAGS_SYNC_FENCE)) { | ||
355 | fd = get_unused_fd_flags(O_RDWR); | ||
356 | if (fd < 0) | ||
357 | return fd; | ||
358 | } | ||
359 | |||
351 | ret = gk20a_prepare_compressible_read(l, args->handle, | 360 | ret = gk20a_prepare_compressible_read(l, args->handle, |
352 | args->request_compbits, args->offset, | 361 | args->request_compbits, args->offset, |
353 | args->compbits_hoffset, args->compbits_voffset, | 362 | args->compbits_hoffset, args->compbits_voffset, |
@@ -356,20 +365,24 @@ static int gk20a_ctrl_prepare_compressible_read( | |||
356 | submit_flags, &fence, &args->valid_compbits, | 365 | submit_flags, &fence, &args->valid_compbits, |
357 | &args->zbc_color, &fence_out); | 366 | &args->zbc_color, &fence_out); |
358 | 367 | ||
359 | if (ret) | 368 | if (ret) { |
369 | if (fd != -1) | ||
370 | put_unused_fd(fd); | ||
360 | return ret; | 371 | return ret; |
372 | } | ||
361 | 373 | ||
362 | /* Convert fence_out to something we can pass back to user space. */ | 374 | /* Convert fence_out to something we can pass back to user space. */ |
363 | if (submit_flags & NVGPU_SUBMIT_FLAGS_FENCE_GET) { | 375 | if (submit_flags & NVGPU_SUBMIT_FLAGS_FENCE_GET) { |
364 | if (submit_flags & NVGPU_SUBMIT_FLAGS_SYNC_FENCE) { | 376 | if (submit_flags & NVGPU_SUBMIT_FLAGS_SYNC_FENCE) { |
365 | if (fence_out) { | 377 | if (fence_out) { |
366 | int fd = gk20a_fence_install_fd(fence_out); | 378 | ret = gk20a_fence_install_fd(fence_out, fd); |
367 | if (fd < 0) | 379 | if (ret) |
368 | ret = fd; | 380 | put_unused_fd(fd); |
369 | else | 381 | else |
370 | args->fence.fd = fd; | 382 | args->fence.fd = fd; |
371 | } else { | 383 | } else { |
372 | args->fence.fd = -1; | 384 | args->fence.fd = -1; |
385 | put_unused_fd(fd); | ||
373 | } | 386 | } |
374 | } else { | 387 | } else { |
375 | if (fence_out) { | 388 | if (fence_out) { |
diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c index b9c9554b..81b3db82 100644 --- a/drivers/gpu/nvgpu/common/linux/module.c +++ b/drivers/gpu/nvgpu/common/linux/module.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <nvgpu/enabled.h> | 40 | #include <nvgpu/enabled.h> |
41 | #include <nvgpu/debug.h> | 41 | #include <nvgpu/debug.h> |
42 | #include <nvgpu/ctxsw_trace.h> | 42 | #include <nvgpu/ctxsw_trace.h> |
43 | #include <nvgpu/vidmem.h> | ||
43 | 44 | ||
44 | #include "platform_gk20a.h" | 45 | #include "platform_gk20a.h" |
45 | #include "sysfs.h" | 46 | #include "sysfs.h" |
@@ -252,13 +253,22 @@ int gk20a_pm_finalize_poweron(struct device *dev) | |||
252 | return err; | 253 | return err; |
253 | 254 | ||
254 | err = gk20a_finalize_poweron(g); | 255 | err = gk20a_finalize_poweron(g); |
255 | set_user_nice(current, nice_value); | 256 | if (err) { |
256 | if (err) | 257 | set_user_nice(current, nice_value); |
257 | goto done; | 258 | goto done; |
259 | } | ||
258 | 260 | ||
259 | err = nvgpu_finalize_poweron_linux(l); | 261 | err = nvgpu_finalize_poweron_linux(l); |
260 | if (err) | 262 | if (err) { |
263 | set_user_nice(current, nice_value); | ||
261 | goto done; | 264 | goto done; |
265 | } | ||
266 | |||
267 | nvgpu_init_mm_ce_context(g); | ||
268 | |||
269 | nvgpu_vidmem_thread_unpause(&g->mm); | ||
270 | |||
271 | set_user_nice(current, nice_value); | ||
262 | 272 | ||
263 | /* Initialise scaling: it will initialize scaling drive only once */ | 273 | /* Initialise scaling: it will initialize scaling drive only once */ |
264 | if (IS_ENABLED(CONFIG_GK20A_DEVFREQ) && | 274 | if (IS_ENABLED(CONFIG_GK20A_DEVFREQ) && |