diff options
author | Florin Coras <fcoras@cisco.com> | 2019-12-19 16:10:58 -0800 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2020-02-25 19:18:49 +0000 |
commit | f22f4e562e1b922cff036ef628b77fd2d479d015 (patch) | |
tree | 4cbc3091a5ce89a73c94685dcee198dd583ca375 /src/vnet | |
parent | b020806806c0e6c54886cdb4347a5fd1f19504b0 (diff) |
svm: refactor fifo
Type: refactor
Switch from a wrapped byte space to a "continuous" one wherein fifo
chunks are appended to the fifo as more data is enqueued and chunks are
removed as data is dequeued.
The fifo is still subject to a maximum size, i.e., maximum number of
bytes that can be enqueued, so the max number of chunks associated to
the fifo is also constrained.
When enqueueing data, which must fit within the available free space, if
not enough "supporting" chunk memory is available, the fifo asks the
fifo segment for enough chunk memory to ensure that the write can
succeed. To avoid allocating large amounts of small chunks due to small
writes, if possible, the size of the chunks requested is lower capped by
min_alloc.
When dequeuing data, all the chunks that have been completely drained,
i.e., head moved beyond the chunks’ end bytes, are unlinked from the
fifo and returned to the fifo segment. The one exception to this is the
last chunk which is never unlinked.
Change-Id: I98c1dbd9135fb79650365c7e40c29238b96cd4ee
Signed-off-by: Florin Coras <fcoras@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/session/application_local.c | 6 | ||||
-rw-r--r-- | src/vnet/session/segment_manager.c | 44 | ||||
-rw-r--r-- | src/vnet/session/segment_manager.h | 44 | ||||
-rw-r--r-- | src/vnet/session/session.h | 4 |
4 files changed, 7 insertions, 91 deletions
diff --git a/src/vnet/session/application_local.c b/src/vnet/session/application_local.c index 25fb39e094b..cc02026e3bb 100644 --- a/src/vnet/session/application_local.c +++ b/src/vnet/session/application_local.c @@ -180,7 +180,11 @@ ct_init_local_session (app_worker_t * client_wrk, app_worker_t * server_wrk, props = application_segment_manager_properties (server); round_rx_fifo_sz = 1 << max_log2 (props->rx_fifo_size); round_tx_fifo_sz = 1 << max_log2 (props->tx_fifo_size); - seg_size = round_rx_fifo_sz + round_tx_fifo_sz + margin; + /* Increase size because of inefficient chunk allocations. Depending on + * how data is consumed, it may happen that more chunks than needed are + * allocated. + * TODO should remove once allocations are done more efficiently */ + seg_size = 4 * (round_rx_fifo_sz + round_tx_fifo_sz + margin); sm = app_worker_get_listen_segment_manager (server_wrk, ll); seg_index = segment_manager_add_segment (sm, seg_size); diff --git a/src/vnet/session/segment_manager.c b/src/vnet/session/segment_manager.c index 0600b671be7..0a54b96a125 100644 --- a/src/vnet/session/segment_manager.c +++ b/src/vnet/session/segment_manager.c @@ -686,50 +686,6 @@ segment_manager_dealloc_fifos (svm_fifo_t * rx_fifo, svm_fifo_t * tx_fifo) segment_manager_segment_reader_unlock (sm); } -int -segment_manager_grow_fifo (segment_manager_t * sm, svm_fifo_t * f, u32 size) -{ - fifo_segment_t *fs; - int rv; - - fs = segment_manager_get_segment_w_lock (sm, f->segment_index); - rv = fifo_segment_grow_fifo (fs, f, size); - segment_manager_segment_reader_unlock (sm); - - return rv; -} - -int -segment_manager_collect_fifo_chunks (segment_manager_t * sm, svm_fifo_t * f) -{ - fifo_segment_t *fs; - int rv; - - fs = segment_manager_get_segment_w_lock (sm, f->segment_index); - rv = fifo_segment_collect_fifo_chunks (fs, f); - segment_manager_segment_reader_unlock (sm); - - return rv; -} - -int -segment_manager_shrink_fifo (segment_manager_t * sm, svm_fifo_t * f, u32 size, - u8 is_producer) -{ - int rv; - - rv = svm_fifo_reduce_size (f, size, is_producer); - - /* Nothing to collect at this point */ - if (!is_producer) - return rv; - - if (f->flags & SVM_FIFO_F_COLLECT_CHUNKS) - segment_manager_collect_fifo_chunks (sm, f); - - return rv; -} - u32 segment_manager_evt_q_expected_size (u32 q_len) { diff --git a/src/vnet/session/segment_manager.h b/src/vnet/session/segment_manager.h index b40926091c4..52f89eef171 100644 --- a/src/vnet/session/segment_manager.h +++ b/src/vnet/session/segment_manager.h @@ -118,50 +118,6 @@ int segment_manager_try_alloc_fifos (fifo_segment_t * fs, void segment_manager_dealloc_fifos (svm_fifo_t * rx_fifo, svm_fifo_t * tx_fifo); -/** - * Grows fifo owned by segment manager - * - * @param sm segment manager that owns the fifo - * @param f fifo to be grown - * @param size amount of bytes to add to fifo - * @return 0 on success, negative number otherwise - */ -int segment_manager_grow_fifo (segment_manager_t * sm, svm_fifo_t * f, - u32 size); - -/** - * Request to shrink fifo owned by segment manager - * - * If this is not called by the producer, no attempt is made to reduce the - * size until the producer tries to enqueue more data. To collect the chunks - * that are to be removed call @ref segment_manager_collect_fifo_chunks - * - * Size reduction does not affect fifo chunk boundaries. Therefore chunks are - * not split and the amount of bytes to be removed can be equal to or less - * than what was requested. - * - * @param sm segment manager that owns the fifo - * @param f fifo to be shrunk - * @param size amount of bytes to remove from fifo - * @param is_producer flag that indicates is caller is the producer for the - * fifo. - * @return actual number of bytes to be removed - */ -int segment_manager_shrink_fifo (segment_manager_t * sm, svm_fifo_t * f, - u32 size, u8 is_producer); - -/** - * Collect fifo chunks that are no longer used - * - * This should not be called unless SVM_FIFO_F_COLLECT_CHUNKS is set for - * the fifo. The chunks are returned to the fifo segment freelist. - * - * @param sm segment manager that owns the fifo - * @param f fifo whose chunks are to be collected - * @return 0 on success, error otherwise - */ -int segment_manager_collect_fifo_chunks (segment_manager_t * sm, - svm_fifo_t * f); u8 segment_manager_has_fifos (segment_manager_t * sm); svm_msg_q_t *segment_manager_alloc_queue (fifo_segment_t * fs, diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h index 346af546856..e85637283a7 100644 --- a/src/vnet/session/session.h +++ b/src/vnet/session/session.h @@ -492,14 +492,14 @@ always_inline u32 transport_rx_fifo_size (transport_connection_t * tc) { session_t *s = session_get (tc->s_index, tc->thread_index); - return s->rx_fifo->nitems; + return svm_fifo_size (s->rx_fifo); } always_inline u32 transport_tx_fifo_size (transport_connection_t * tc) { session_t *s = session_get (tc->s_index, tc->thread_index); - return s->tx_fifo->nitems; + return svm_fifo_size (s->tx_fifo); } always_inline u8 |