gpu: nvgpu: Fix OOM case for buddy allocator

The allocator could attempt to use a buddy list for an order larger than
the max order when all the valid buddy lists were empty. This patch
ensures that when looking for a particular order buddy that the passed
order is valid.

Also handle the prints in the no-mem case a litle differently. Only print
and update alloc info when there was a successful allocation.

Lastly print hex numbers for the allocator stats printing function.

Change-Id: If289f3e8925e236e3b7d84206a75bd45a14082a1
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: http://git-master/r/745071
(cherry picked from commit f3548e67f435975238b55ac152871dcd60a1a907)
Reviewed-on: http://git-master/r/753280
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Alex Waterman
2015-05-20 12:23:01 -07:00
committed by Terje Bergstrom
parent 140d213de6
commit 34a3e35631

View File

@@ -573,7 +573,8 @@ static struct gk20a_buddy *__balloc_find_buddy(struct gk20a_allocator *a,
{
struct gk20a_buddy *bud;
if (list_empty(balloc_get_order_list(a, order)))
if (order > a->max_order ||
list_empty(balloc_get_order_list(a, order)))
return NULL;
if (a->flags & GPU_BALLOC_GVA_SPACE &&
@@ -609,6 +610,10 @@ static u64 __balloc_do_alloc(struct gk20a_allocator *a, u64 order, int pte_size)
while (!(bud = __balloc_find_buddy(a, split_order, pte_size)))
split_order++;
/* Out of memory! */
if (!bud)
return 0;
while (bud->order != order) {
if (balloc_split_buddy(a, bud, pte_size))
return 0; /* No mem... */
@@ -658,15 +663,19 @@ u64 gk20a_balloc(struct gk20a_allocator *a, u64 len)
addr = __balloc_do_alloc(a, order, pte_size);
a->bytes_alloced += len;
a->bytes_alloced_real += balloc_order_to_len(a, order);
if (addr) {
a->bytes_alloced += len;
a->bytes_alloced_real += balloc_order_to_len(a, order);
balloc_dbg(a, "Alloc 0x%-10llx %3lld:0x%-10llx pte_size=%s\n",
addr, order, len,
pte_size == gmmu_page_size_big ? "big" :
pte_size == gmmu_page_size_small ? "small" :
"NA/any");
} else {
balloc_dbg(a, "Alloc failed: no mem!\n");
}
balloc_unlock(a);
balloc_dbg(a, "Alloc 0x%-10llx %3lld:0x%-10llx pte_size=%s\n",
addr, order, len,
pte_size == gmmu_page_size_big ? "big" :
pte_size == gmmu_page_size_small ? "small" :
"NA/any");
balloc_trace_func_done();
return addr;
@@ -1071,11 +1080,11 @@ static void balloc_print_stats(struct gk20a_allocator *a, struct seq_file *s,
__balloc_pstat(s, "base = %llu, limit = %llu, blk_size = %llu\n",
a->base, a->length, a->blk_size);
__balloc_pstat(s, "Internal params:\n");
__balloc_pstat(s, " start = %llu\n", a->start);
__balloc_pstat(s, " end = %llu\n", a->end);
__balloc_pstat(s, " count = %llu\n", a->count);
__balloc_pstat(s, " blks = %llu\n", a->blks);
__balloc_pstat(s, " max_order = %llu\n", a->max_order);
__balloc_pstat(s, " start = 0x%llx\n", a->start);
__balloc_pstat(s, " end = 0x%llx\n", a->end);
__balloc_pstat(s, " count = 0x%llx\n", a->count);
__balloc_pstat(s, " blks = 0x%llx\n", a->blks);
__balloc_pstat(s, " max_order = %llu\n", a->max_order);
__balloc_pstat(s, "Buddy blocks:\n");
__balloc_pstat(s, " Order Free Alloced Split\n");