diff options
author | Alex Waterman <alexw@nvidia.com> | 2017-04-12 14:27:48 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-04-25 17:26:00 -0400 |
commit | 84dadb1a9ae2ab0473976ebf5ece1cb0d1e60205 (patch) | |
tree | 8ec8d404c319082dc472eae1ca1b56f2b7e7c197 /drivers/gpu/nvgpu/include/nvgpu/semaphore.h | |
parent | aff9d46c00a2a82c93d6cc43d790584e7e474d0e (diff) |
gpu: nvgpu: Move semaphore impl to nvgpu_mem
Use struct nvgpu_mem for DMA allocations (and the corresponding
nvgpu_dma_alloc_sys()) instead of custom rolled code. This migrates
away from using linux scatter gather tables directly. Instead this
is hidden in the nvgpu_mem struct. With this change the semaphore.c
code no longer has any direct Linux dependencies.
JIRA NVGPU-12
JIRA NVGPU-30
Change-Id: I92167c98aac9b413ae87496744dcee051cd60207
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: http://git-master/r/1464081
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/include/nvgpu/semaphore.h')
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/semaphore.h | 72 |
1 files changed, 36 insertions, 36 deletions
diff --git a/drivers/gpu/nvgpu/include/nvgpu/semaphore.h b/drivers/gpu/nvgpu/include/nvgpu/semaphore.h index f197a918..45a3af5a 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/semaphore.h +++ b/drivers/gpu/nvgpu/include/nvgpu/semaphore.h | |||
@@ -14,23 +14,22 @@ | |||
14 | #ifndef SEMAPHORE_GK20A_H | 14 | #ifndef SEMAPHORE_GK20A_H |
15 | #define SEMAPHORE_GK20A_H | 15 | #define SEMAPHORE_GK20A_H |
16 | 16 | ||
17 | #include <linux/delay.h> | ||
18 | |||
19 | #include <nvgpu/log.h> | 17 | #include <nvgpu/log.h> |
20 | #include <nvgpu/allocator.h> | 18 | #include <nvgpu/timers.h> |
21 | #include <nvgpu/atomic.h> | 19 | #include <nvgpu/atomic.h> |
22 | #include <nvgpu/bug.h> | 20 | #include <nvgpu/bug.h> |
23 | #include <nvgpu/kref.h> | 21 | #include <nvgpu/kref.h> |
24 | #include <nvgpu/list.h> | 22 | #include <nvgpu/list.h> |
23 | #include <nvgpu/nvgpu_mem.h> | ||
25 | 24 | ||
26 | #include "gk20a/gk20a.h" | 25 | #include "gk20a/gk20a.h" |
27 | #include "gk20a/mm_gk20a.h" | 26 | #include "gk20a/mm_gk20a.h" |
28 | #include "gk20a/channel_gk20a.h" | 27 | #include "gk20a/channel_gk20a.h" |
29 | 28 | ||
30 | #define gpu_sema_dbg(fmt, args...) \ | 29 | #define gpu_sema_dbg(g, fmt, args...) \ |
31 | gk20a_dbg(gpu_dbg_sema, fmt, ##args) | 30 | nvgpu_log(g, gpu_dbg_sema, fmt, ##args) |
32 | #define gpu_sema_verbose_dbg(fmt, args...) \ | 31 | #define gpu_sema_verbose_dbg(g, fmt, args...) \ |
33 | gk20a_dbg(gpu_dbg_sema_v, fmt, ##args) | 32 | nvgpu_log(g, gpu_dbg_sema_v, fmt, ##args) |
34 | 33 | ||
35 | /* | 34 | /* |
36 | * Max number of channels that can be used is 512. This of course needs to be | 35 | * Max number of channels that can be used is 512. This of course needs to be |
@@ -50,7 +49,6 @@ struct nvgpu_semaphore_int { | |||
50 | int idx; /* Semaphore index. */ | 49 | int idx; /* Semaphore index. */ |
51 | u32 offset; /* Offset into the pool. */ | 50 | u32 offset; /* Offset into the pool. */ |
52 | atomic_t next_value; /* Next available value. */ | 51 | atomic_t next_value; /* Next available value. */ |
53 | u32 *value; /* Current value (access w/ readl()). */ | ||
54 | u32 nr_incrs; /* Number of increments programmed. */ | 52 | u32 nr_incrs; /* Number of increments programmed. */ |
55 | struct nvgpu_semaphore_pool *p; /* Pool that owns this sema. */ | 53 | struct nvgpu_semaphore_pool *p; /* Pool that owns this sema. */ |
56 | struct channel_gk20a *ch; /* Channel that owns this sema. */ | 54 | struct channel_gk20a *ch; /* Channel that owns this sema. */ |
@@ -82,9 +80,7 @@ struct nvgpu_semaphore { | |||
82 | * A semaphore pool. Each address space will own exactly one of these. | 80 | * A semaphore pool. Each address space will own exactly one of these. |
83 | */ | 81 | */ |
84 | struct nvgpu_semaphore_pool { | 82 | struct nvgpu_semaphore_pool { |
85 | struct page *page; /* This pool's page of memory */ | ||
86 | struct nvgpu_list_node pool_list_entry; /* Node for list of pools. */ | 83 | struct nvgpu_list_node pool_list_entry; /* Node for list of pools. */ |
87 | void *cpu_va; /* CPU access to the pool. */ | ||
88 | u64 gpu_va; /* GPU access to the pool. */ | 84 | u64 gpu_va; /* GPU access to the pool. */ |
89 | u64 gpu_va_ro; /* GPU access to the pool. */ | 85 | u64 gpu_va_ro; /* GPU access to the pool. */ |
90 | int page_idx; /* Index into sea bitmap. */ | 86 | int page_idx; /* Index into sea bitmap. */ |
@@ -98,15 +94,10 @@ struct nvgpu_semaphore_pool { | |||
98 | 94 | ||
99 | /* | 95 | /* |
100 | * This is the address spaces's personal RW table. Other channels will | 96 | * This is the address spaces's personal RW table. Other channels will |
101 | * ultimately map this page as RO. | 97 | * ultimately map this page as RO. This is a sub-nvgpu_mem from the |
102 | */ | 98 | * sea's mem. |
103 | struct sg_table *rw_sg_table; | ||
104 | |||
105 | /* | ||
106 | * This is to keep track of whether the pool has had its sg_table | ||
107 | * updated during sea resizing. | ||
108 | */ | 99 | */ |
109 | struct sg_table *ro_sg_table; | 100 | struct nvgpu_mem rw_mem; |
110 | 101 | ||
111 | int mapped; | 102 | int mapped; |
112 | 103 | ||
@@ -148,11 +139,12 @@ struct nvgpu_semaphore_sea { | |||
148 | */ | 139 | */ |
149 | int page_count; /* Pages allocated to pools. */ | 140 | int page_count; /* Pages allocated to pools. */ |
150 | 141 | ||
151 | struct sg_table *ro_sg_table; | ||
152 | /* | 142 | /* |
153 | struct page *pages[SEMAPHORE_POOL_COUNT]; | 143 | * The read-only memory for the entire semaphore sea. Each semaphore |
154 | */ | 144 | * pool needs a sub-nvgpu_mem that will be mapped as RW in its address |
155 | 145 | * space. This sea_mem cannot be freed until all semaphore_pools have | |
146 | * been freed. | ||
147 | */ | ||
156 | struct nvgpu_mem sea_mem; | 148 | struct nvgpu_mem sea_mem; |
157 | 149 | ||
158 | /* | 150 | /* |
@@ -224,12 +216,26 @@ static inline u64 nvgpu_hw_sema_addr(struct nvgpu_semaphore_int *hw_sema) | |||
224 | hw_sema->offset; | 216 | hw_sema->offset; |
225 | } | 217 | } |
226 | 218 | ||
219 | static inline u32 __nvgpu_semaphore_read(struct nvgpu_semaphore_int *hw_sema) | ||
220 | { | ||
221 | return nvgpu_mem_rd(hw_sema->ch->g, | ||
222 | &hw_sema->p->rw_mem, hw_sema->offset); | ||
223 | } | ||
224 | |||
225 | /* | ||
226 | * Read the underlying value from a semaphore. | ||
227 | */ | ||
228 | static inline u32 nvgpu_semaphore_read(struct nvgpu_semaphore *s) | ||
229 | { | ||
230 | return __nvgpu_semaphore_read(s->hw_sema); | ||
231 | } | ||
232 | |||
227 | /* | 233 | /* |
228 | * TODO: handle wrap around... Hmm, how to do this? | 234 | * TODO: handle wrap around... Hmm, how to do this? |
229 | */ | 235 | */ |
230 | static inline bool nvgpu_semaphore_is_released(struct nvgpu_semaphore *s) | 236 | static inline bool nvgpu_semaphore_is_released(struct nvgpu_semaphore *s) |
231 | { | 237 | { |
232 | u32 sema_val = readl(s->hw_sema->value); | 238 | u32 sema_val = nvgpu_semaphore_read(s); |
233 | 239 | ||
234 | /* | 240 | /* |
235 | * If the underlying semaphore value is greater than or equal to | 241 | * If the underlying semaphore value is greater than or equal to |
@@ -244,14 +250,6 @@ static inline bool nvgpu_semaphore_is_acquired(struct nvgpu_semaphore *s) | |||
244 | return !nvgpu_semaphore_is_released(s); | 250 | return !nvgpu_semaphore_is_released(s); |
245 | } | 251 | } |
246 | 252 | ||
247 | /* | ||
248 | * Read the underlying value from a semaphore. | ||
249 | */ | ||
250 | static inline u32 nvgpu_semaphore_read(struct nvgpu_semaphore *s) | ||
251 | { | ||
252 | return readl(s->hw_sema->value); | ||
253 | } | ||
254 | |||
255 | static inline u32 nvgpu_semaphore_get_value(struct nvgpu_semaphore *s) | 253 | static inline u32 nvgpu_semaphore_get_value(struct nvgpu_semaphore *s) |
256 | { | 254 | { |
257 | return (u32)atomic_read(&s->value); | 255 | return (u32)atomic_read(&s->value); |
@@ -269,6 +267,7 @@ static inline u32 nvgpu_semaphore_next_value(struct nvgpu_semaphore *s) | |||
269 | static inline void __nvgpu_semaphore_release(struct nvgpu_semaphore *s, | 267 | static inline void __nvgpu_semaphore_release(struct nvgpu_semaphore *s, |
270 | bool force) | 268 | bool force) |
271 | { | 269 | { |
270 | struct nvgpu_semaphore_int *hw_sema = s->hw_sema; | ||
272 | u32 current_val; | 271 | u32 current_val; |
273 | u32 val = nvgpu_semaphore_get_value(s); | 272 | u32 val = nvgpu_semaphore_get_value(s); |
274 | int attempts = 0; | 273 | int attempts = 0; |
@@ -282,7 +281,7 @@ static inline void __nvgpu_semaphore_release(struct nvgpu_semaphore *s, | |||
282 | while ((current_val = nvgpu_semaphore_read(s)) < (val - 1)) { | 281 | while ((current_val = nvgpu_semaphore_read(s)) < (val - 1)) { |
283 | if (force) | 282 | if (force) |
284 | break; | 283 | break; |
285 | msleep(100); | 284 | nvgpu_msleep(100); |
286 | attempts += 1; | 285 | attempts += 1; |
287 | if (attempts > 100) { | 286 | if (attempts > 100) { |
288 | WARN(1, "Stall on sema release!"); | 287 | WARN(1, "Stall on sema release!"); |
@@ -297,10 +296,10 @@ static inline void __nvgpu_semaphore_release(struct nvgpu_semaphore *s, | |||
297 | if (current_val >= val) | 296 | if (current_val >= val) |
298 | return; | 297 | return; |
299 | 298 | ||
300 | writel(val, s->hw_sema->value); | 299 | nvgpu_mem_wr(hw_sema->ch->g, &hw_sema->p->rw_mem, hw_sema->offset, val); |
301 | 300 | ||
302 | gpu_sema_verbose_dbg("(c=%d) WRITE %u", | 301 | gpu_sema_verbose_dbg(hw_sema->p->sema_sea->gk20a, |
303 | s->hw_sema->ch->hw_chid, val); | 302 | "(c=%d) WRITE %u", hw_sema->ch->hw_chid, val); |
304 | } | 303 | } |
305 | 304 | ||
306 | static inline void nvgpu_semaphore_release(struct nvgpu_semaphore *s) | 305 | static inline void nvgpu_semaphore_release(struct nvgpu_semaphore *s) |
@@ -324,7 +323,8 @@ static inline void nvgpu_semaphore_incr(struct nvgpu_semaphore *s) | |||
324 | atomic_set(&s->value, atomic_add_return(1, &s->hw_sema->next_value)); | 323 | atomic_set(&s->value, atomic_add_return(1, &s->hw_sema->next_value)); |
325 | s->incremented = 1; | 324 | s->incremented = 1; |
326 | 325 | ||
327 | gpu_sema_verbose_dbg("INCR sema for c=%d (%u)", | 326 | gpu_sema_verbose_dbg(s->hw_sema->p->sema_sea->gk20a, |
327 | "INCR sema for c=%d (%u)", | ||
328 | s->hw_sema->ch->hw_chid, | 328 | s->hw_sema->ch->hw_chid, |
329 | nvgpu_semaphore_next_value(s)); | 329 | nvgpu_semaphore_next_value(s)); |
330 | } | 330 | } |