summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/fence_gk20a.c
diff options
context:
space:
mode:
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