diff options
author | Sachit Kadle <skadle@nvidia.com> | 2016-08-15 17:32:39 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2016-10-20 11:14:11 -0400 |
commit | 733fb79b39869665addcd80ccdf1c15f4a5aaa29 (patch) | |
tree | b3c9c1ba32406ed9c2af4bebee820e83ea6172e4 /drivers/gpu/nvgpu/gk20a/fence_gk20a.c | |
parent | 63e8592e06939e20c7b9e56b430353ebbee31ad6 (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.c | 70 |
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 | ||
53 | void gk20a_fence_put(struct gk20a_fence *f) | 58 | void 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 | ||
112 | struct gk20a_fence *gk20a_alloc_fence(struct channel_gk20a *c) | 117 | int 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 | |||
140 | fail: | ||
141 | vfree(fence_pool); | ||
142 | return err; | ||
143 | } | ||
144 | |||
145 | void 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); | 155 | struct 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 | ||