aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2019-12-20 18:48:20 -0800
committerFlorin Coras <fcoras@cisco.com>2019-12-20 18:48:20 -0800
commitd849edf3841c1c9774c5ce209a2b903415f2370a (patch)
treeaa944df3ecbcbdcf641473927e0b1a393102b809
parent623b4f85e6ee4611ae15bb3103fe30725ca977ed (diff)
svm: fix multichunk alloc with not enough space
Type: fix Change-Id: Ia89c76b0e897fc3a3ebbc8dcba25e8ac9974b7fa Signed-off-by: Florin Coras <fcoras@cisco.com>
-rw-r--r--src/svm/fifo_segment.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/svm/fifo_segment.c b/src/svm/fifo_segment.c
index 61939637434..944bf7cd34a 100644
--- a/src/svm/fifo_segment.c
+++ b/src/svm/fifo_segment.c
@@ -314,7 +314,10 @@ fs_try_alloc_fifo_freelist_multi_chunk (fifo_segment_header_t * fsh,
fss->free_fifos = f->next;
}
- fl_index = fs_freelist_for_size (data_bytes) - 1;
+ fl_index = fs_freelist_for_size (data_bytes);
+ if (fl_index > 0)
+ fl_index -= 1;
+
fl_size = fs_freelist_index_to_size (fl_index);
while (data_bytes)
@@ -333,11 +336,38 @@ fs_try_alloc_fifo_freelist_multi_chunk (fifo_segment_header_t * fsh,
}
else
{
- ASSERT (fl_index > 0);
+ /* Failed to allocate with smaller chunks */
+ if (fl_index == 0)
+ {
+ /* free all chunks if any allocated */
+ c = first;
+ while (c)
+ {
+ fl_index = fs_freelist_for_size (c->length);
+ fl_size = fs_freelist_index_to_size (fl_index);
+ c->next = fss->free_chunks[fl_index];
+ fss->free_chunks[fl_index] = c;
+ fss->n_fl_chunk_bytes += fl_size;
+ data_bytes += fl_size;
+ }
+ first = last = 0;
+ fl_index = fs_freelist_for_size (data_bytes);
+ if (fss->free_chunks[fl_index + 1])
+ {
+ fl_index += 1;
+ fl_size = fs_freelist_index_to_size (fl_index);
+ continue;
+ }
+
+ f->next = fss->free_fifos;
+ fss->free_fifos = f;
+ return 0;
+ }
fl_index -= 1;
fl_size = fl_size >> 1;
}
}
+
f->start_chunk = first;
f->end_chunk = last;
last->next = first;