summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/gk20a_allocator_bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/gk20a_allocator_bitmap.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a_allocator_bitmap.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_allocator_bitmap.c b/drivers/gpu/nvgpu/gk20a/gk20a_allocator_bitmap.c
index a2aa85fa..03ccbe85 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a_allocator_bitmap.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a_allocator_bitmap.c
@@ -211,7 +211,7 @@ static int __gk20a_bitmap_store_alloc(struct gk20a_bitmap_allocator *a,
211static u64 gk20a_bitmap_alloc(struct gk20a_allocator *__a, u64 len) 211static u64 gk20a_bitmap_alloc(struct gk20a_allocator *__a, u64 len)
212{ 212{
213 u64 blks, addr; 213 u64 blks, addr;
214 unsigned long offs, adjusted_offs; 214 unsigned long offs, adjusted_offs, limit;
215 struct gk20a_bitmap_allocator *a = bitmap_allocator(__a); 215 struct gk20a_bitmap_allocator *a = bitmap_allocator(__a);
216 216
217 blks = len >> a->blk_shift; 217 blks = len >> a->blk_shift;
@@ -221,11 +221,26 @@ static u64 gk20a_bitmap_alloc(struct gk20a_allocator *__a, u64 len)
221 221
222 alloc_lock(__a); 222 alloc_lock(__a);
223 223
224 offs = bitmap_find_next_zero_area(a->bitmap, a->num_bits, 0, blks, 0); 224 /*
225 if (offs >= a->num_bits) 225 * First look from next_blk and onwards...
226 goto fail; 226 */
227 offs = bitmap_find_next_zero_area(a->bitmap, a->num_bits,
228 a->next_blk, blks, 0);
229 if (offs >= a->num_bits) {
230 /*
231 * If that didn't work try the remaining area. Since there can
232 * be available space that spans across a->next_blk we need to
233 * search up to the first set bit after that.
234 */
235 limit = find_next_bit(a->bitmap, a->num_bits, a->next_blk);
236 offs = bitmap_find_next_zero_area(a->bitmap, limit,
237 0, blks, 0);
238 if (offs >= a->next_blk)
239 goto fail;
240 }
227 241
228 bitmap_set(a->bitmap, offs, blks); 242 bitmap_set(a->bitmap, offs, blks);
243 a->next_blk = offs + blks;
229 244
230 adjusted_offs = offs + a->bit_offs; 245 adjusted_offs = offs + a->bit_offs;
231 addr = ((u64)adjusted_offs) * a->blk_size; 246 addr = ((u64)adjusted_offs) * a->blk_size;
@@ -255,6 +270,7 @@ static u64 gk20a_bitmap_alloc(struct gk20a_allocator *__a, u64 len)
255fail_reset_bitmap: 270fail_reset_bitmap:
256 bitmap_clear(a->bitmap, offs, blks); 271 bitmap_clear(a->bitmap, offs, blks);
257fail: 272fail:
273 a->next_blk = 0;
258 alloc_unlock(__a); 274 alloc_unlock(__a);
259 alloc_dbg(__a, "Alloc failed!\n"); 275 alloc_dbg(__a, "Alloc failed!\n");
260 return 0; 276 return 0;