summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common
diff options
context:
space:
mode:
authorDebarshi Dutta <ddutta@nvidia.com>2018-03-23 06:02:27 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-04-23 00:04:48 -0400
commitd0e4dfd6efd651abc431aba9cfae5907638f8172 (patch)
tree1a412eaa4636ff2e2862c1623bad3a5ea6883d4e /drivers/gpu/nvgpu/common
parentc918c42a4a3651f757c6966aead4b07eb4b56697 (diff)
gpu: nvgpu: sync_framework cleanups
This patch deals with cleanups meant to make things simpler for the upcoming os abstraction patches for the sync framework. This patch causes some substantial changes which are listed out as follows. 1) sync_timeline is moved out of gk20a_fence into struct nvgpu_channel_linux. New function pointers are created to facilitate os independent methods for enabling/disabling timeline and are now named as os_fence_framework. These function pointers are located in the struct os_channel under struct gk20a. 2) construction of the channel_sync require nvgpu_finalize_poweron_linux() to be invoked before invocations to nvgpu_init_mm_ce_context(). Hence, these methods are now moved away from gk20a_finalize_poweron() and invoked after nvgpu_finalize_poweron_linux(). 3) sync_fence creation is now delinked from fence construction and move to the channel_sync_gk20a's channel_incr methods. These sync_fences are mainly associated with post_fences. 4) In case userspace requires the sync_fences to be constructed, we try to obtain an fd before the gk20a_channel_submit_gpfifo() instead of trying to do that later. This is used to avoid potential after effects of duplicate work submission due to failure to obtain an unused fd. JIRA NVGPU-66 Change-Id: I42a3e4e2e692a113b1b36d2b48ab107ae4444dfa Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1678400 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common')
-rw-r--r--drivers/gpu/nvgpu/common/linux/channel.c79
-rw-r--r--drivers/gpu/nvgpu/common/linux/channel.h15
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_channel.c21
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_ctrl.c21
-rw-r--r--drivers/gpu/nvgpu/common/linux/module.c16
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
43u32 nvgpu_submit_gpfifo_user_flags_to_common_flags(u32 user_flags) 45u32 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
326static 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}
347static 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
357static 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
368static 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
314int nvgpu_init_channel_support_linux(struct nvgpu_os_linux *l) 378int 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
337err_clean: 411err_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
359u32 nvgpu_get_gpfifo_entry_size(void) 438u32 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;
29struct fifo_profile_gk20a; 29struct fifo_profile_gk20a;
30struct nvgpu_os_linux; 30struct nvgpu_os_linux;
31 31
32struct sync_fence;
33struct sync_timeline;
34
32struct nvgpu_channel_completion_cb { 35struct 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 */
62struct nvgpu_os_fence_framework {
63 struct sync_timeline *timeline;
64};
65
55struct nvgpu_channel_linux { 66struct 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) &&