summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2017-09-28 15:32:18 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-10-14 17:13:18 -0400
commit7685f60d9dd6ed062f3037d4e72ea124c103d211 (patch)
treea30185cde3b5f4fe1f4b657c7708e2fe8e07ee96
parentc7e0c7e7ce045a9bef53f3fa11377ddb23bd79a3 (diff)
gpu: nvgpu: Abstract rw_semaphore implementation
Abstract implementation of rw_semaphore. In Linux it's implemented in terms of rw_semaphore. Change deterministic_busy to use the new implementation. JIRA NVGPU-259 Change-Id: Ia9c1b6e397581bff7711c5ab6fb76ef6d23cff87 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1570405 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
-rw-r--r--drivers/gpu/nvgpu/Makefile.nvgpu1
-rw-r--r--drivers/gpu/nvgpu/common/linux/driver_common.c2
-rw-r--r--drivers/gpu/nvgpu/common/linux/rwsem.c39
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.c24
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/linux/rwsem.h26
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/rwsem.h44
7 files changed, 125 insertions, 14 deletions
diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu b/drivers/gpu/nvgpu/Makefile.nvgpu
index e059002a..02fb8529 100644
--- a/drivers/gpu/nvgpu/Makefile.nvgpu
+++ b/drivers/gpu/nvgpu/Makefile.nvgpu
@@ -47,6 +47,7 @@ nvgpu-y := \
47 common/linux/sysfs.o \ 47 common/linux/sysfs.o \
48 common/linux/cde.o \ 48 common/linux/cde.o \
49 common/linux/io.o \ 49 common/linux/io.o \
50 common/linux/rwsem.o \
50 common/mm/nvgpu_allocator.o \ 51 common/mm/nvgpu_allocator.o \
51 common/mm/bitmap_allocator.o \ 52 common/mm/bitmap_allocator.o \
52 common/mm/buddy_allocator.o \ 53 common/mm/buddy_allocator.o \
diff --git a/drivers/gpu/nvgpu/common/linux/driver_common.c b/drivers/gpu/nvgpu/common/linux/driver_common.c
index 734bc1d2..295297b6 100644
--- a/drivers/gpu/nvgpu/common/linux/driver_common.c
+++ b/drivers/gpu/nvgpu/common/linux/driver_common.c
@@ -44,7 +44,7 @@ static void nvgpu_init_vars(struct gk20a *g)
44 gk20a_init_gr(g); 44 gk20a_init_gr(g);
45 45
46 init_rwsem(&l->busy_lock); 46 init_rwsem(&l->busy_lock);
47 init_rwsem(&g->deterministic_busy); 47 nvgpu_rwsem_init(&g->deterministic_busy);
48 48
49 nvgpu_spinlock_init(&g->mc_enable_lock); 49 nvgpu_spinlock_init(&g->mc_enable_lock);
50 50
diff --git a/drivers/gpu/nvgpu/common/linux/rwsem.c b/drivers/gpu/nvgpu/common/linux/rwsem.c
new file mode 100644
index 00000000..297ddf11
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/linux/rwsem.c
@@ -0,0 +1,39 @@
1/*
2 * Copyright (c) 2017, 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
14#include <nvgpu/rwsem.h>
15
16void nvgpu_rwsem_init(struct nvgpu_rwsem *rwsem)
17{
18 init_rwsem(&rwsem->rwsem);
19}
20
21void nvgpu_rwsem_up_read(struct nvgpu_rwsem *rwsem)
22{
23 up_read(&rwsem->rwsem);
24}
25
26void nvgpu_rwsem_down_read(struct nvgpu_rwsem *rwsem)
27{
28 down_read(&rwsem->rwsem);
29}
30
31void nvgpu_rwsem_up_write(struct nvgpu_rwsem *rwsem)
32{
33 up_write(&rwsem->rwsem);
34}
35
36void nvgpu_rwsem_down_write(struct nvgpu_rwsem *rwsem)
37{
38 down_write(&rwsem->rwsem);
39}
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index e3937afd..713c4215 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -602,10 +602,10 @@ unbind:
602 602
603 /* put back the channel-wide submit ref from init */ 603 /* put back the channel-wide submit ref from init */
604 if (ch->deterministic) { 604 if (ch->deterministic) {
605 down_read(&g->deterministic_busy); 605 nvgpu_rwsem_down_read(&g->deterministic_busy);
606 ch->deterministic = false; 606 ch->deterministic = false;
607 gk20a_idle(g); 607 gk20a_idle(g);
608 up_read(&g->deterministic_busy); 608 nvgpu_rwsem_up_read(&g->deterministic_busy);
609 } 609 }
610 610
611 ch->vpr = false; 611 ch->vpr = false;
@@ -1268,7 +1268,7 @@ int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c,
1268 c->vpr = true; 1268 c->vpr = true;
1269 1269
1270 if (flags & NVGPU_ALLOC_GPFIFO_EX_FLAGS_DETERMINISTIC) { 1270 if (flags & NVGPU_ALLOC_GPFIFO_EX_FLAGS_DETERMINISTIC) {
1271 down_read(&g->deterministic_busy); 1271 nvgpu_rwsem_down_read(&g->deterministic_busy);
1272 /* 1272 /*
1273 * Railgating isn't deterministic; instead of disallowing 1273 * Railgating isn't deterministic; instead of disallowing
1274 * railgating globally, take a power refcount for this 1274 * railgating globally, take a power refcount for this
@@ -1280,12 +1280,12 @@ int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c,
1280 */ 1280 */
1281 err = gk20a_busy(g); 1281 err = gk20a_busy(g);
1282 if (err) { 1282 if (err) {
1283 up_read(&g->deterministic_busy); 1283 nvgpu_rwsem_up_read(&g->deterministic_busy);
1284 return err; 1284 return err;
1285 } 1285 }
1286 1286
1287 c->deterministic = true; 1287 c->deterministic = true;
1288 up_read(&g->deterministic_busy); 1288 nvgpu_rwsem_up_read(&g->deterministic_busy);
1289 } 1289 }
1290 1290
1291 /* an address space needs to have been bound at this point. */ 1291 /* an address space needs to have been bound at this point. */
@@ -1397,10 +1397,10 @@ clean_up:
1397 memset(&c->gpfifo, 0, sizeof(struct gpfifo_desc)); 1397 memset(&c->gpfifo, 0, sizeof(struct gpfifo_desc));
1398clean_up_idle: 1398clean_up_idle:
1399 if (c->deterministic) { 1399 if (c->deterministic) {
1400 down_read(&g->deterministic_busy); 1400 nvgpu_rwsem_down_read(&g->deterministic_busy);
1401 gk20a_idle(g); 1401 gk20a_idle(g);
1402 c->deterministic = false; 1402 c->deterministic = false;
1403 up_read(&g->deterministic_busy); 1403 nvgpu_rwsem_up_read(&g->deterministic_busy);
1404 } 1404 }
1405 nvgpu_err(g, "fail"); 1405 nvgpu_err(g, "fail");
1406 return err; 1406 return err;
@@ -2661,7 +2661,7 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
2661 2661
2662 /* Grab access to HW to deal with do_idle */ 2662 /* Grab access to HW to deal with do_idle */
2663 if (c->deterministic) 2663 if (c->deterministic)
2664 down_read(&g->deterministic_busy); 2664 nvgpu_rwsem_down_read(&g->deterministic_busy);
2665 2665
2666 trace_gk20a_channel_submit_gpfifo(g->name, 2666 trace_gk20a_channel_submit_gpfifo(g->name,
2667 c->chid, 2667 c->chid,
@@ -2741,7 +2741,7 @@ int gk20a_submit_channel_gpfifo(struct channel_gk20a *c,
2741 2741
2742 /* No hw access beyond this point */ 2742 /* No hw access beyond this point */
2743 if (c->deterministic) 2743 if (c->deterministic)
2744 up_read(&g->deterministic_busy); 2744 nvgpu_rwsem_up_read(&g->deterministic_busy);
2745 2745
2746 trace_gk20a_channel_submitted_gpfifo(g->name, 2746 trace_gk20a_channel_submitted_gpfifo(g->name,
2747 c->chid, 2747 c->chid,
@@ -2765,7 +2765,7 @@ clean_up:
2765 gk20a_fence_put(pre_fence); 2765 gk20a_fence_put(pre_fence);
2766 gk20a_fence_put(post_fence); 2766 gk20a_fence_put(post_fence);
2767 if (c->deterministic) 2767 if (c->deterministic)
2768 up_read(&g->deterministic_busy); 2768 nvgpu_rwsem_up_read(&g->deterministic_busy);
2769 else if (need_deferred_cleanup) 2769 else if (need_deferred_cleanup)
2770 gk20a_idle(g); 2770 gk20a_idle(g);
2771 2771
@@ -2787,7 +2787,7 @@ void gk20a_channel_deterministic_idle(struct gk20a *g)
2787 u32 chid; 2787 u32 chid;
2788 2788
2789 /* Grab exclusive access to the hw to block new submits */ 2789 /* Grab exclusive access to the hw to block new submits */
2790 down_write(&g->deterministic_busy); 2790 nvgpu_rwsem_down_write(&g->deterministic_busy);
2791 2791
2792 for (chid = 0; chid < f->num_channels; chid++) { 2792 for (chid = 0; chid < f->num_channels; chid++) {
2793 struct channel_gk20a *ch = &f->channel[chid]; 2793 struct channel_gk20a *ch = &f->channel[chid];
@@ -2845,7 +2845,7 @@ void gk20a_channel_deterministic_unidle(struct gk20a *g)
2845 } 2845 }
2846 2846
2847 /* Release submits, new deterministic channels and frees */ 2847 /* Release submits, new deterministic channels and frees */
2848 up_write(&g->deterministic_busy); 2848 nvgpu_rwsem_up_write(&g->deterministic_busy);
2849} 2849}
2850 2850
2851int gk20a_init_channel_support(struct gk20a *g, u32 chid) 2851int gk20a_init_channel_support(struct gk20a *g, u32 chid)
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index cf13999a..b6f6a97b 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -58,6 +58,7 @@ struct nvgpu_mem_sgt;
58#include <nvgpu/pmu.h> 58#include <nvgpu/pmu.h>
59#include <nvgpu/atomic.h> 59#include <nvgpu/atomic.h>
60#include <nvgpu/barrier.h> 60#include <nvgpu/barrier.h>
61#include <nvgpu/rwsem.h>
61 62
62#include "clk_gk20a.h" 63#include "clk_gk20a.h"
63#include "ce2_gk20a.h" 64#include "ce2_gk20a.h"
@@ -1082,7 +1083,7 @@ struct gk20a {
1082 * for submits and held for channel lifetime but dropped for an ongoing 1083 * for submits and held for channel lifetime but dropped for an ongoing
1083 * gk20a_do_idle(). 1084 * gk20a_do_idle().
1084 */ 1085 */
1085 struct rw_semaphore deterministic_busy; 1086 struct nvgpu_rwsem deterministic_busy;
1086 1087
1087 struct nvgpu_falcon pmu_flcn; 1088 struct nvgpu_falcon pmu_flcn;
1088 struct nvgpu_falcon sec2_flcn; 1089 struct nvgpu_falcon sec2_flcn;
diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/rwsem.h b/drivers/gpu/nvgpu/include/nvgpu/linux/rwsem.h
new file mode 100644
index 00000000..7d073d39
--- /dev/null
+++ b/drivers/gpu/nvgpu/include/nvgpu/linux/rwsem.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (c) 2017, 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#ifndef __NVGPU_RWSEM_LINUX_H__
18#define __NVGPU_RWSEM_LINUX_H__
19
20#include <linux/rwsem.h>
21
22struct nvgpu_rwsem {
23 struct rw_semaphore rwsem;
24};
25
26#endif
diff --git a/drivers/gpu/nvgpu/include/nvgpu/rwsem.h b/drivers/gpu/nvgpu/include/nvgpu/rwsem.h
new file mode 100644
index 00000000..d37c11a8
--- /dev/null
+++ b/drivers/gpu/nvgpu/include/nvgpu/rwsem.h
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22#ifndef __NVGPU_RWSEM_H__
23#define __NVGPU_RWSEM_H__
24
25#ifdef __KERNEL__
26#include <nvgpu/linux/rwsem.h>
27#endif
28
29/*
30 * struct nvgpu_rwsem
31 *
32 * Should be implemented per-OS in a separate library
33 * But implementation should adhere to rw_semaphore implementation
34 * as specified in Linux Documentation
35 */
36struct nvgpu_rwsem;
37
38void nvgpu_rwsem_init(struct nvgpu_rwsem *rwsem);
39void nvgpu_rwsem_up_read(struct nvgpu_rwsem *rwsem);
40void nvgpu_rwsem_down_read(struct nvgpu_rwsem *rwsem);
41void nvgpu_rwsem_up_write(struct nvgpu_rwsem *rwsem);
42void nvgpu_rwsem_down_write(struct nvgpu_rwsem *rwsem);
43
44#endif