summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/fence_gk20a.c
diff options
context:
space:
mode:
authorSachit Kadle <skadle@nvidia.com>2016-08-15 17:32:39 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2016-10-20 11:14:11 -0400
commit733fb79b39869665addcd80ccdf1c15f4a5aaa29 (patch)
treeb3c9c1ba32406ed9c2af4bebee820e83ea6172e4 /drivers/gpu/nvgpu/gk20a/fence_gk20a.c
parent63e8592e06939e20c7b9e56b430353ebbee31ad6 (diff)
gpu: nvgpu: add support for pre-allocated resources
Add support for pre-allocation of job tracking resources w/ new (extended) ioctl. Goal is to avoid dynamic memory allocation in the submit path. This patch does the following: 1) Intoduces a new ioctl, NVGPU_IOCTL_CHANNEL_ALLOC_GPFIFO_EX, which enables pre-allocation of tracking resources per job: a) 2x priv_cmd_entry b) 2x gk20a_fence 2) Implements circular ring buffer for job tracking to avoid lock contention between producer (submitter) and consumer (clean-up) Bug 1795076 Change-Id: I6b52e5c575871107ff380f9a5790f440a6969347 Signed-off-by: Sachit Kadle <skadle@nvidia.com> Reviewed-on: http://git-master/r/1203300 (cherry picked from commit 9fd270c22b860935dffe244753dabd87454bef39) Reviewed-on: http://git-master/r/1223934 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.c70
1 files changed, 63 insertions, 7 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/fence_gk20a.c b/drivers/gpu/nvgpu/gk20a/fence_gk20a.c
index f788829f..c11d363e 100644
--- a/drivers/gpu/nvgpu/gk20a/fence_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fence_gk20a.c
@@ -47,7 +47,12 @@ static void gk20a_fence_free(struct kref *ref)
47#endif 47#endif
48 if (f->semaphore) 48 if (f->semaphore)
49 gk20a_semaphore_put(f->semaphore); 49 gk20a_semaphore_put(f->semaphore);
50 kfree(f); 50
51 if (f->allocator) {
52 if (gk20a_alloc_initialized(f->allocator))
53 gk20a_free(f->allocator, (u64)f);
54 } else
55 kfree(f);
51} 56}
52 57
53void gk20a_fence_put(struct gk20a_fence *f) 58void gk20a_fence_put(struct gk20a_fence *f)
@@ -109,15 +114,66 @@ int gk20a_fence_install_fd(struct gk20a_fence *f)
109#endif 114#endif
110} 115}
111 116
112struct gk20a_fence *gk20a_alloc_fence(struct channel_gk20a *c) 117int gk20a_alloc_fence_pool(struct channel_gk20a *c, int count)
118{
119 int err;
120 size_t size;
121 struct gk20a_fence *fence_pool = NULL;
122
123 size = sizeof(struct gk20a_fence);
124 if (count <= ULONG_MAX / size) {
125 size = count * size;
126 fence_pool = vzalloc(size);
127 }
128
129 if (!fence_pool)
130 return -ENOMEM;
131
132 err = gk20a_lockless_allocator_init(&c->fence_allocator,
133 "fence_pool", (u64)fence_pool, size,
134 sizeof(struct gk20a_fence), 0);
135 if (err)
136 goto fail;
137
138 return 0;
139
140fail:
141 vfree(fence_pool);
142 return err;
143}
144
145void gk20a_free_fence_pool(struct channel_gk20a *c)
113{ 146{
114 struct gk20a_fence *fence; 147 if (gk20a_alloc_initialized(&c->fence_allocator)) {
148 void *base = (void *)gk20a_alloc_base(&c->fence_allocator);
149
150 gk20a_alloc_destroy(&c->fence_allocator);
151 vfree(base);
152 }
153}
115 154
116 fence = kzalloc(sizeof(struct gk20a_fence), GFP_KERNEL); 155struct gk20a_fence *gk20a_alloc_fence(struct channel_gk20a *c)
117 if (!fence) 156{
118 return NULL; 157 struct gk20a_fence *fence = NULL;
158
159 if (channel_gk20a_is_prealloc_enabled(c)) {
160 if (gk20a_alloc_initialized(&c->fence_allocator)) {
161 fence = (struct gk20a_fence *)
162 gk20a_alloc(&c->fence_allocator,
163 sizeof(struct gk20a_fence));
164
165 /* clear the node and reset the allocator pointer */
166 if (fence) {
167 memset(fence, 0, sizeof(*fence));
168 fence->allocator = &c->fence_allocator;
169 }
170 }
171 } else
172 fence = kzalloc(sizeof(struct gk20a_fence), GFP_KERNEL);
173
174 if (fence)
175 kref_init(&fence->ref);
119 176
120 kref_init(&fence->ref);
121 return fence; 177 return fence;
122} 178}
123 179