summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/fence_gk20a.c
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/gk20a/fence_gk20a.c
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/gk20a/fence_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/fence_gk20a.c101
1 files changed, 33 insertions, 68 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fence_gk20a.c b/drivers/gpu/nvgpu/gk20a/fence_gk20a.c
index f74afd6e..f0ad773f 100644
--- a/drivers/gpu/nvgpu/gk20a/fence_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fence_gk20a.c
@@ -54,9 +54,10 @@ static void gk20a_fence_free(struct nvgpu_ref *ref)
54 struct gk20a *g = f->g; 54 struct gk20a *g = f->g;
55 55
56#ifdef CONFIG_SYNC 56#ifdef CONFIG_SYNC
57 if (f->sync_fence) 57 if (f->os_fence)
58 sync_fence_put(f->sync_fence); 58 sync_fence_put(f->os_fence);
59#endif 59#endif
60
60 if (f->semaphore) 61 if (f->semaphore)
61 nvgpu_semaphore_put(f->semaphore); 62 nvgpu_semaphore_put(f->semaphore);
62 63
@@ -80,7 +81,7 @@ struct gk20a_fence *gk20a_fence_get(struct gk20a_fence *f)
80 return f; 81 return f;
81} 82}
82 83
83static inline bool gk20a_fence_is_valid(struct gk20a_fence *f) 84inline bool gk20a_fence_is_valid(struct gk20a_fence *f)
84{ 85{
85 bool valid = f->valid; 86 bool valid = f->valid;
86 87
@@ -88,6 +89,21 @@ static inline bool gk20a_fence_is_valid(struct gk20a_fence *f)
88 return valid; 89 return valid;
89} 90}
90 91
92int gk20a_fence_install_fd(struct gk20a_fence *f, int fd)
93{
94#ifdef CONFIG_SYNC
95 if (!f || !gk20a_fence_is_valid(f) || !f->os_fence)
96 return -EINVAL;
97
98 sync_fence_get(f->os_fence);
99 sync_fence_install(f->os_fence, fd);
100
101 return 0;
102#else
103 return -ENODEV;
104#endif
105}
106
91int gk20a_fence_wait(struct gk20a *g, struct gk20a_fence *f, 107int gk20a_fence_wait(struct gk20a *g, struct gk20a_fence *f,
92 unsigned long timeout) 108 unsigned long timeout)
93{ 109{
@@ -107,26 +123,6 @@ bool gk20a_fence_is_expired(struct gk20a_fence *f)
107 return true; 123 return true;
108} 124}
109 125
110int gk20a_fence_install_fd(struct gk20a_fence *f)
111{
112#ifdef CONFIG_SYNC
113 int fd;
114
115 if (!f || !gk20a_fence_is_valid(f) || !f->sync_fence)
116 return -EINVAL;
117
118 fd = get_unused_fd_flags(O_RDWR);
119 if (fd < 0)
120 return fd;
121
122 sync_fence_get(f->sync_fence);
123 sync_fence_install(f->sync_fence, fd);
124 return fd;
125#else
126 return -ENODEV;
127#endif
128}
129
130int gk20a_alloc_fence_pool(struct channel_gk20a *c, unsigned int count) 126int gk20a_alloc_fence_pool(struct channel_gk20a *c, unsigned int count)
131{ 127{
132 int err; 128 int err;
@@ -195,13 +191,14 @@ struct gk20a_fence *gk20a_alloc_fence(struct channel_gk20a *c)
195 191
196void gk20a_init_fence(struct gk20a_fence *f, 192void gk20a_init_fence(struct gk20a_fence *f,
197 const struct gk20a_fence_ops *ops, 193 const struct gk20a_fence_ops *ops,
198 struct sync_fence *sync_fence) 194 struct sync_fence *os_fence)
199{ 195{
200 if (!f) 196 if (!f)
201 return; 197 return;
202 f->ops = ops; 198 f->ops = ops;
203 f->sync_fence = sync_fence;
204 f->syncpt_id = -1; 199 f->syncpt_id = -1;
200 f->semaphore = NULL;
201 f->os_fence = os_fence;
205} 202}
206 203
207/* Fences that are backed by GPU semaphores: */ 204/* Fences that are backed by GPU semaphores: */
@@ -227,36 +224,19 @@ static const struct gk20a_fence_ops nvgpu_semaphore_fence_ops = {
227 .is_expired = &nvgpu_semaphore_fence_is_expired, 224 .is_expired = &nvgpu_semaphore_fence_is_expired,
228}; 225};
229 226
230/* This function takes ownership of the semaphore */ 227/* This function takes ownership of the semaphore as well as the os_fence */
231int gk20a_fence_from_semaphore( 228int gk20a_fence_from_semaphore(
232 struct gk20a *g,
233 struct gk20a_fence *fence_out, 229 struct gk20a_fence *fence_out,
234 struct sync_timeline *timeline,
235 struct nvgpu_semaphore *semaphore, 230 struct nvgpu_semaphore *semaphore,
236 struct nvgpu_cond *semaphore_wq, 231 struct nvgpu_cond *semaphore_wq,
237 bool need_sync_fence) 232 struct sync_fence *os_fence)
238{ 233{
239 struct gk20a_fence *f = fence_out; 234 struct gk20a_fence *f = fence_out;
240 struct sync_fence *sync_fence = NULL;
241
242#ifdef CONFIG_SYNC
243 if (need_sync_fence) {
244 sync_fence = gk20a_sync_fence_create(g, timeline, semaphore,
245 "f-gk20a-0x%04x",
246 nvgpu_semaphore_gpu_ro_va(semaphore));
247 if (!sync_fence)
248 return -ENOMEM;
249 }
250#endif
251 235
252 gk20a_init_fence(f, &nvgpu_semaphore_fence_ops, sync_fence); 236 gk20a_init_fence(f, &nvgpu_semaphore_fence_ops, os_fence);
253 if (!f) { 237 if (!f)
254#ifdef CONFIG_SYNC
255 if (sync_fence)
256 sync_fence_put(sync_fence);
257#endif
258 return -EINVAL; 238 return -EINVAL;
259 } 239
260 240
261 f->semaphore = semaphore; 241 f->semaphore = semaphore;
262 f->semaphore_wq = semaphore_wq; 242 f->semaphore_wq = semaphore_wq;
@@ -306,32 +286,18 @@ static const struct gk20a_fence_ops gk20a_syncpt_fence_ops = {
306 .is_expired = &gk20a_syncpt_fence_is_expired, 286 .is_expired = &gk20a_syncpt_fence_is_expired,
307}; 287};
308 288
289/* This function takes the ownership of the os_fence */
309int gk20a_fence_from_syncpt( 290int gk20a_fence_from_syncpt(
310 struct gk20a_fence *fence_out, 291 struct gk20a_fence *fence_out,
311 struct nvgpu_nvhost_dev *nvhost_dev, 292 struct nvgpu_nvhost_dev *nvhost_dev,
312 u32 id, u32 value, 293 u32 id, u32 value, struct sync_fence *os_fence)
313 bool need_sync_fence)
314{ 294{
315 struct gk20a_fence *f = fence_out; 295 struct gk20a_fence *f = fence_out;
316 struct sync_fence *sync_fence = NULL;
317
318#ifdef CONFIG_SYNC
319 if (need_sync_fence) {
320 sync_fence = nvgpu_nvhost_sync_create_fence(nvhost_dev,
321 id, value, "fence");
322 if (IS_ERR(sync_fence))
323 return PTR_ERR(sync_fence);
324 }
325#endif
326 296
327 gk20a_init_fence(f, &gk20a_syncpt_fence_ops, sync_fence); 297 gk20a_init_fence(f, &gk20a_syncpt_fence_ops, os_fence);
328 if (!f) { 298 if (!f)
329#ifdef CONFIG_SYNC
330 if (sync_fence)
331 sync_fence_put(sync_fence);
332#endif
333 return -EINVAL; 299 return -EINVAL;
334 } 300
335 f->nvhost_dev = nvhost_dev; 301 f->nvhost_dev = nvhost_dev;
336 f->syncpt_id = id; 302 f->syncpt_id = id;
337 f->syncpt_value = value; 303 f->syncpt_value = value;
@@ -346,8 +312,7 @@ int gk20a_fence_from_syncpt(
346int gk20a_fence_from_syncpt( 312int gk20a_fence_from_syncpt(
347 struct gk20a_fence *fence_out, 313 struct gk20a_fence *fence_out,
348 struct nvgpu_nvhost_dev *nvhost_dev, 314 struct nvgpu_nvhost_dev *nvhost_dev,
349 u32 id, u32 value, 315 u32 id, u32 value, struct sync_fence *os_fence)
350 bool need_sync_fence)
351{ 316{
352 return -EINVAL; 317 return -EINVAL;
353} 318}