mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 10:34:43 +03:00
gpu: nvgpu: bitmap allocator optimization
Add an optimization to the bitmap allocator for handling sequences of allocations. A common pattern of allocs from the priv_cmdbuf is to do many allocs and then many frees. In such cases it makes sense to store the last allocation offset and start searching for the next alloc from there. For such a pattern we know that the previous bits are already allocated so it doesn't make sense to search them unless we have to. Obviously, if there's no space found ahead of the precious alloc's block then we fall back to the remaining space. In random allocation patterns this optimization should not have any negative affects. It merely shifts the start point for searching for allocs but assuming each bit has an equal probability of being free the start location does not matter. Bug 1799159 Signed-off-by: Alex Waterman <alexw@nvidia.com> Reviewed-on: http://git-master/r/1205958 (cherry picked from commit 759c583962d6d57cb8cb073ccdbfcfc6db4c1e18) Change-Id: I267ef6fa155ff15d6ebfc76dc1abafd9aa1f44df Reviewed-on: http://git-master/r/1227923 GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
cd452a6ed4
commit
641444188f
@@ -211,7 +211,7 @@ static int __gk20a_bitmap_store_alloc(struct gk20a_bitmap_allocator *a,
|
||||
static u64 gk20a_bitmap_alloc(struct gk20a_allocator *__a, u64 len)
|
||||
{
|
||||
u64 blks, addr;
|
||||
unsigned long offs, adjusted_offs;
|
||||
unsigned long offs, adjusted_offs, limit;
|
||||
struct gk20a_bitmap_allocator *a = bitmap_allocator(__a);
|
||||
|
||||
blks = len >> a->blk_shift;
|
||||
@@ -221,11 +221,26 @@ static u64 gk20a_bitmap_alloc(struct gk20a_allocator *__a, u64 len)
|
||||
|
||||
alloc_lock(__a);
|
||||
|
||||
offs = bitmap_find_next_zero_area(a->bitmap, a->num_bits, 0, blks, 0);
|
||||
if (offs >= a->num_bits)
|
||||
goto fail;
|
||||
/*
|
||||
* First look from next_blk and onwards...
|
||||
*/
|
||||
offs = bitmap_find_next_zero_area(a->bitmap, a->num_bits,
|
||||
a->next_blk, blks, 0);
|
||||
if (offs >= a->num_bits) {
|
||||
/*
|
||||
* If that didn't work try the remaining area. Since there can
|
||||
* be available space that spans across a->next_blk we need to
|
||||
* search up to the first set bit after that.
|
||||
*/
|
||||
limit = find_next_bit(a->bitmap, a->num_bits, a->next_blk);
|
||||
offs = bitmap_find_next_zero_area(a->bitmap, limit,
|
||||
0, blks, 0);
|
||||
if (offs >= a->next_blk)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bitmap_set(a->bitmap, offs, blks);
|
||||
a->next_blk = offs + blks;
|
||||
|
||||
adjusted_offs = offs + a->bit_offs;
|
||||
addr = ((u64)adjusted_offs) * a->blk_size;
|
||||
@@ -255,6 +270,7 @@ static u64 gk20a_bitmap_alloc(struct gk20a_allocator *__a, u64 len)
|
||||
fail_reset_bitmap:
|
||||
bitmap_clear(a->bitmap, offs, blks);
|
||||
fail:
|
||||
a->next_blk = 0;
|
||||
alloc_unlock(__a);
|
||||
alloc_dbg(__a, "Alloc failed!\n");
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user