summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSagar Kamble <skamble@nvidia.com>2021-05-03 12:16:17 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2021-05-04 17:40:40 -0400
commit00c3d98acba40e0ee549a174f212850aa15646a5 (patch)
tree80928678cb7968af8a29c5ef09c646241506074d
parent13fc430775eb0e39dc06e420d5c92dda7016f6ae (diff)
gpu: nvgpu: create timed wait functions for stall and nonstall interrupts completion
In order to process stalling interrupts during TSG unbind, we need a API to wait for the stalling interrupts to complete within certain duration. Prepare these APIs for stalling and non-stalling interrupts. Bug 200711183 Bug 200726848 Change-Id: I634738249ade64224326b356d6244ad4299f1baf Signed-off-by: Sagar Kamble <skamble@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2521970 (cherry picked from commit I0b7a64c0f3761bbd0ca0843aea28a591ed23739f) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2523937 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-by: Bibek Basu <bbasu@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/gk20a.h4
-rw-r--r--drivers/gpu/nvgpu/os/linux/driver_common.c60
-rw-r--r--drivers/gpu/nvgpu/os/posix/nvgpu.c18
3 files changed, 70 insertions, 12 deletions
diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h
index aa95969d..3b193dbe 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2011-2020, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2011-2021, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * GK20A Graphics 4 * GK20A Graphics
5 * 5 *
@@ -1793,6 +1793,8 @@ bool gk20a_check_poweron(struct gk20a *g);
1793int gk20a_prepare_poweroff(struct gk20a *g); 1793int gk20a_prepare_poweroff(struct gk20a *g);
1794int gk20a_finalize_poweron(struct gk20a *g); 1794int gk20a_finalize_poweron(struct gk20a *g);
1795 1795
1796int nvgpu_wait_for_stall_interrupts(struct gk20a *g, u32 timeout);
1797int nvgpu_wait_for_nonstall_interrupts(struct gk20a *g, u32 timeout);
1796void nvgpu_wait_for_deferred_interrupts(struct gk20a *g); 1798void nvgpu_wait_for_deferred_interrupts(struct gk20a *g);
1797 1799
1798struct gk20a * __must_check gk20a_get(struct gk20a *g); 1800struct gk20a * __must_check gk20a_get(struct gk20a *g);
diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c
index c76dabeb..602d325d 100644
--- a/drivers/gpu/nvgpu/os/linux/driver_common.c
+++ b/drivers/gpu/nvgpu/os/linux/driver_common.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2016-2021, 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,
@@ -312,30 +312,70 @@ static int cyclic_delta(int a, int b)
312} 312}
313 313
314/** 314/**
315 * nvgpu_wait_for_deferred_interrupts - Wait for interrupts to complete 315 * nvgpu_wait_for_stall_interrupts - Wait for the stalling interrupts to
316 * complete.
316 * 317 *
317 * @g - The GPU to wait on. 318 * @g - The GPU to wait on.
319 * @timeout - maximum time period to wait for.
318 * 320 *
319 * Waits until all interrupt handlers that have been scheduled to run have 321 * Waits until all stalling interrupt handlers that have been scheduled to run
320 * completed. 322 * have completed.
321 */ 323 */
322void nvgpu_wait_for_deferred_interrupts(struct gk20a *g) 324int nvgpu_wait_for_stall_interrupts(struct gk20a *g, u32 timeout)
323{ 325{
324 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); 326 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
325 int stall_irq_threshold = atomic_read(&l->hw_irq_stall_count); 327 int stall_irq_threshold = atomic_read(&l->hw_irq_stall_count);
326 int nonstall_irq_threshold = atomic_read(&l->hw_irq_nonstall_count);
327 328
328 /* wait until all stalling irqs are handled */ 329 /* wait until all stalling irqs are handled */
329 NVGPU_COND_WAIT(&l->sw_irq_stall_last_handled_wq, 330 return NVGPU_COND_WAIT(&l->sw_irq_stall_last_handled_wq,
330 cyclic_delta(stall_irq_threshold, 331 cyclic_delta(stall_irq_threshold,
331 atomic_read(&l->sw_irq_stall_last_handled)) 332 atomic_read(&l->sw_irq_stall_last_handled))
332 <= 0, 0); 333 <= 0, timeout);
334}
335
336/**
337 * nvgpu_wait_for_nonstall_interrupts - Wait for the nonstalling interrupts to
338 * complete.
339 *
340 * @g - The GPU to wait on.
341 * @timeout - maximum time period to wait for.
342 *
343 * Waits until all non-stalling interrupt handlers that have been scheduled to
344 * run have completed.
345 */
346int nvgpu_wait_for_nonstall_interrupts(struct gk20a *g, u32 timeout)
347{
348 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
349 int nonstall_irq_threshold = atomic_read(&l->hw_irq_nonstall_count);
333 350
334 /* wait until all non-stalling irqs are handled */ 351 /* wait until all non-stalling irqs are handled */
335 NVGPU_COND_WAIT(&l->sw_irq_nonstall_last_handled_wq, 352 return NVGPU_COND_WAIT(&l->sw_irq_nonstall_last_handled_wq,
336 cyclic_delta(nonstall_irq_threshold, 353 cyclic_delta(nonstall_irq_threshold,
337 atomic_read(&l->sw_irq_nonstall_last_handled)) 354 atomic_read(&l->sw_irq_nonstall_last_handled))
338 <= 0, 0); 355 <= 0, timeout);
356}
357
358/**
359 * nvgpu_wait_for_deferred_interrupts - Wait for interrupts to complete
360 *
361 * @g - The GPU to wait on.
362 *
363 * Waits until all interrupt handlers that have been scheduled to run have
364 * completed.
365 */
366void nvgpu_wait_for_deferred_interrupts(struct gk20a *g)
367{
368 int ret;
369
370 ret = nvgpu_wait_for_stall_interrupts(g, 0U);
371 if (ret != 0) {
372 nvgpu_err(g, "wait for stall interrupts failed %d", ret);
373 }
374
375 ret = nvgpu_wait_for_nonstall_interrupts(g, 0U);
376 if (ret != 0) {
377 nvgpu_err(g, "wait for nonstall interrupts failed %d", ret);
378 }
339} 379}
340 380
341static void nvgpu_free_gk20a(struct gk20a *g) 381static void nvgpu_free_gk20a(struct gk20a *g)
diff --git a/drivers/gpu/nvgpu/os/posix/nvgpu.c b/drivers/gpu/nvgpu/os/posix/nvgpu.c
index e485ed73..5b68113c 100644
--- a/drivers/gpu/nvgpu/os/posix/nvgpu.c
+++ b/drivers/gpu/nvgpu/os/posix/nvgpu.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2018-2021, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a 4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"), 5 * copy of this software and associated documentation files (the "Software"),
@@ -36,6 +36,22 @@
36 36
37#include "os_posix.h" 37#include "os_posix.h"
38 38
39int nvgpu_wait_for_stall_interrupts(struct gk20a *g, u32 timeout)
40{
41 /*
42 * No interrupts in userspace so nothing to wait for.
43 */
44 return 0;
45}
46
47int nvgpu_wait_for_nonstall_interrupts(struct gk20a *g, u32 timeout)
48{
49 /*
50 * No interrupts in userspace so nothing to wait for.
51 */
52 return 0;
53}
54
39void nvgpu_wait_for_deferred_interrupts(struct gk20a *g) 55void nvgpu_wait_for_deferred_interrupts(struct gk20a *g)
40{ 56{
41 /* 57 /*