summaryrefslogtreecommitdiffstats
path: root/src/svm/fifo_segment.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/svm/fifo_segment.c')
-rw-r--r--src/svm/fifo_segment.c89
1 files changed, 75 insertions, 14 deletions
diff --git a/src/svm/fifo_segment.c b/src/svm/fifo_segment.c
index eb240b0ada1..cfc795418b2 100644
--- a/src/svm/fifo_segment.c
+++ b/src/svm/fifo_segment.c
@@ -657,7 +657,7 @@ fs_try_alloc_fifo (fifo_segment_header_t * fsh, fifo_segment_slice_t * fss,
ssvm_pop_heap (oldheap);
if (f)
{
- fss->num_chunks[fl_index] += 1;
+ clib_atomic_fetch_add_rel (&fss->num_chunks[fl_index], 1);
fsh_free_bytes_sub (fsh, fifo_sz);
goto done;
}
@@ -717,7 +717,7 @@ fsh_alloc_chunk (fifo_segment_header_t * fsh, u32 slice_index, u32 chunk_size)
if (c)
{
- fss->num_chunks[fl_index] += 1;
+ clib_atomic_fetch_add_rel (&fss->num_chunks[fl_index], 1);
fsh_free_bytes_sub (fsh, chunk_size + sizeof (*c));
goto done;
}
@@ -796,6 +796,31 @@ fsh_collect_chunks (fifo_segment_header_t * fsh, u32 slice_index,
fsh_slice_collect_chunks (fsh, fss, c);
}
+static inline void
+fss_fifo_add_active_list (fifo_segment_slice_t * fss, svm_fifo_t * f)
+{
+ if (fss->fifos)
+ {
+ fss->fifos->prev = f;
+ f->next = fss->fifos;
+ }
+ fss->fifos = f;
+}
+
+static inline void
+fss_fifo_del_active_list (fifo_segment_slice_t * fss, svm_fifo_t * f)
+{
+ if (f->flags & SVM_FIFO_F_LL_TRACKED)
+ {
+ if (f->prev)
+ f->prev->next = f->next;
+ else
+ fss->fifos = f->next;
+ if (f->next)
+ f->next->prev = f->prev;
+ }
+}
+
/**
* Allocate fifo in fifo segment
*/
@@ -824,12 +849,7 @@ fifo_segment_alloc_fifo_w_slice (fifo_segment_t * fs, u32 slice_index,
* only one. */
if (ftype == FIFO_SEGMENT_RX_FIFO)
{
- if (fss->fifos)
- {
- fss->fifos->prev = f;
- f->next = fss->fifos;
- }
- fss->fifos = f;
+ fss_fifo_add_active_list (fss, f);
f->flags |= SVM_FIFO_F_LL_TRACKED;
svm_fifo_init_ooo_lookup (f, 0 /* ooo enq */ );
@@ -865,12 +885,7 @@ fifo_segment_free_fifo (fifo_segment_t * fs, svm_fifo_t * f)
/* Remove from active list. Only rx fifos are tracked */
if (f->flags & SVM_FIFO_F_LL_TRACKED)
{
- if (f->prev)
- f->prev->next = f->next;
- else
- fss->fifos = f->next;
- if (f->next)
- f->next->prev = f->prev;
+ fss_fifo_del_active_list (fss, f);
f->flags &= ~SVM_FIFO_F_LL_TRACKED;
}
@@ -900,6 +915,52 @@ fifo_segment_free_fifo (fifo_segment_t * fs, svm_fifo_t * f)
fsh_active_fifos_update (fsh, -1);
}
+void
+fifo_segment_detach_fifo (fifo_segment_t * fs, svm_fifo_t * f)
+{
+ fifo_segment_slice_t *fss;
+ svm_fifo_chunk_t *c;
+ u32 fl_index;
+
+ ASSERT (f->refcnt == 1);
+
+ fss = fsh_slice_get (fs->h, f->slice_index);
+ fss->virtual_mem -= svm_fifo_size (f);
+ if (f->flags & SVM_FIFO_F_LL_TRACKED)
+ fss_fifo_del_active_list (fss, f);
+
+ c = f->start_chunk;
+ while (c)
+ {
+ fl_index = fs_freelist_for_size (c->length);
+ clib_atomic_fetch_sub_rel (&fss->num_chunks[fl_index], 1);
+ c = c->next;
+ }
+}
+
+void
+fifo_segment_attach_fifo (fifo_segment_t * fs, svm_fifo_t * f,
+ u32 slice_index)
+{
+ fifo_segment_slice_t *fss;
+ svm_fifo_chunk_t *c;
+ u32 fl_index;
+
+ f->slice_index = slice_index;
+ fss = fsh_slice_get (fs->h, f->slice_index);
+ fss->virtual_mem += svm_fifo_size (f);
+ if (f->flags & SVM_FIFO_F_LL_TRACKED)
+ fss_fifo_add_active_list (fss, f);
+
+ c = f->start_chunk;
+ while (c)
+ {
+ fl_index = fs_freelist_for_size (c->length);
+ clib_atomic_fetch_add_rel (&fss->num_chunks[fl_index], 1);
+ c = c->next;
+ }
+}
+
int
fifo_segment_prealloc_fifo_hdrs (fifo_segment_t * fs, u32 slice_index,
u32 batch_size)