summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2020-02-28 21:51:24 +0000
committerFlorin Coras <fcoras@cisco.com>2020-02-29 01:35:29 +0000
commitc75ce4dfffe367874fcefda33ad7469015343be1 (patch)
treeef52542e228e5a7e9a214f8f2d168d355fa7ead3 /src
parent952ec0e0a68ccf5a4c3c00894bb26a25d80910a3 (diff)
svm: fix slice locking on fifo alloc
Type: fix Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I1fef115ffc2277ad6e0673b49be137147808891c
Diffstat (limited to 'src')
-rw-r--r--src/plugins/unittest/svm_fifo_test.c3
-rw-r--r--src/svm/fifo_segment.c20
2 files changed, 17 insertions, 6 deletions
diff --git a/src/plugins/unittest/svm_fifo_test.c b/src/plugins/unittest/svm_fifo_test.c
index 7221fb8345e..ba3cf4f0707 100644
--- a/src/plugins/unittest/svm_fifo_test.c
+++ b/src/plugins/unittest/svm_fifo_test.c
@@ -2632,7 +2632,8 @@ svm_fifo_test (vlib_main_t * vm, unformat_input_t * input,
int res = 0;
char *str;
- fifo_segment_main_init (&segment_main, HIGH_SEGMENT_BASEVA << 3, 5);
+ clib_warning ("high mem %lu", HIGH_SEGMENT_BASEVA << 4);
+ fifo_segment_main_init (&segment_main, HIGH_SEGMENT_BASEVA << 4, 5);
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (input, "fifo1"))
diff --git a/src/svm/fifo_segment.c b/src/svm/fifo_segment.c
index e19113fd449..d711c87c88c 100644
--- a/src/svm/fifo_segment.c
+++ b/src/svm/fifo_segment.c
@@ -384,7 +384,7 @@ fs_try_alloc_fifo_freelist_multi_chunk (fifo_segment_header_t * fsh,
fifo_segment_slice_t * fss,
u32 data_bytes)
{
- svm_fifo_chunk_t *c, *first = 0, *last = 0;
+ svm_fifo_chunk_t *c, *first = 0, *last = 0, *next;
u32 fl_index, fl_size, n_alloc = 0;
svm_fifo_t *f;
@@ -421,7 +421,7 @@ fs_try_alloc_fifo_freelist_multi_chunk (fifo_segment_header_t * fsh,
c->next = first;
first = c;
n_alloc += fl_size;
- data_bytes -= c->length;
+ data_bytes -= clib_min (fl_size, data_bytes);
}
else
{
@@ -434,11 +434,13 @@ fs_try_alloc_fifo_freelist_multi_chunk (fifo_segment_header_t * fsh,
{
fl_index = fs_freelist_for_size (c->length);
fl_size = fs_freelist_index_to_size (fl_index);
+ next = c->next;
c->next = fss->free_chunks[fl_index];
fss->free_chunks[fl_index] = c;
fss->n_fl_chunk_bytes += fl_size;
n_alloc -= fl_size;
data_bytes += fl_size;
+ c = next;
}
first = last = 0;
fl_index = fs_freelist_for_size (data_bytes);
@@ -584,6 +586,8 @@ fs_try_alloc_fifo (fifo_segment_header_t * fsh, fifo_segment_slice_t * fss,
fifo_sz = sizeof (svm_fifo_t) + sizeof (svm_fifo_chunk_t);
fifo_sz += 1 << max_log2 (min_size);
+ clib_spinlock_lock (&fss->chunk_lock);
+
if (fss->free_fifos && fss->free_chunks[fl_index])
{
f = fs_try_alloc_fifo_freelist (fss, fl_index);
@@ -618,13 +622,19 @@ fs_try_alloc_fifo (fifo_segment_header_t * fsh, fifo_segment_slice_t * fss,
goto done;
}
}
- if (data_bytes <= fss->n_fl_chunk_bytes)
- f = fs_try_alloc_fifo_freelist_multi_chunk (fsh, fss, data_bytes);
+ /* All failed, try to allocate min of data bytes and fifo sz */
+ fifo_sz = clib_min (fifo_sz, data_bytes);
+ if (fifo_sz <= fss->n_fl_chunk_bytes)
+ f = fs_try_alloc_fifo_freelist_multi_chunk (fsh, fss, fifo_sz);
done:
+ clib_spinlock_unlock (&fss->chunk_lock);
if (f)
- f->fs_hdr = fsh;
+ {
+ f->size = data_bytes;
+ f->fs_hdr = fsh;
+ }
return f;
}