summaryrefslogtreecommitdiffstats
path: root/src/vnet/session/segment_manager.c
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2020-04-28 01:54:22 +0000
committerDave Barach <openvpp@barachs.net>2020-05-04 18:28:16 +0000
commit9845c20d77ce8e9e66c9a7693c6841cc971bd423 (patch)
tree04a313f6cd1d25fe47f70bc3981b7162d3c36724 /src/vnet/session/segment_manager.c
parent933c4ca5a0529b6ed22e0dcc52caa6c797f60563 (diff)
session: add option to preallocate fifo headers
Type: feature Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: Ie47546ef36590b90ed481b14cf812afbecf7981c
Diffstat (limited to 'src/vnet/session/segment_manager.c')
-rw-r--r--src/vnet/session/segment_manager.c71
1 files changed, 39 insertions, 32 deletions
diff --git a/src/vnet/session/segment_manager.c b/src/vnet/session/segment_manager.c
index 33ce6e58398..7734a3eef81 100644
--- a/src/vnet/session/segment_manager.c
+++ b/src/vnet/session/segment_manager.c
@@ -262,14 +262,6 @@ segment_manager_segment_handle (segment_manager_t * sm,
return (((u64) segment_manager_index (sm) << 32) | segment_index);
}
-static void
-segment_manager_parse_segment_handle (u64 segment_handle, u32 * sm_index,
- u32 * segment_index)
-{
- *sm_index = segment_handle >> 32;
- *segment_index = segment_handle & 0xFFFFFFFF;
-}
-
u64
segment_manager_make_segment_handle (u32 segment_manager_index,
u32 segment_index)
@@ -341,20 +333,14 @@ segment_manager_alloc (void)
int
segment_manager_init (segment_manager_t * sm)
{
- u32 rx_fifo_size, tx_fifo_size, pair_size;
- u32 rx_rounded_data_size, tx_rounded_data_size;
- uword first_seg_size;
- u32 prealloc_fifo_pairs;
- u64 approx_total_size, max_seg_size = ((u64) 1 << 32) - (128 << 10);
segment_manager_props_t *props;
- fifo_segment_t *segment;
- u32 approx_segment_count;
- int seg_index, i;
+ uword first_seg_size;
+ fifo_segment_t *fs;
+ int fs_index, i;
props = segment_manager_properties_get (sm);
first_seg_size = clib_max (props->segment_size,
sm_main.default_segment_size);
- prealloc_fifo_pairs = props->prealloc_fifos;
sm->max_fifo_size = props->max_fifo_size ?
props->max_fifo_size : sm_main.default_max_fifo_size;
@@ -364,8 +350,14 @@ segment_manager_init (segment_manager_t * sm)
props->high_watermark,
props->low_watermark);
- if (prealloc_fifo_pairs)
+ if (props->prealloc_fifos)
{
+ u64 approx_total_size, max_seg_size = ((u64) 1 << 32) - (128 << 10);
+ u32 rx_rounded_data_size, tx_rounded_data_size;
+ u32 prealloc_fifo_pairs = props->prealloc_fifos;
+ u32 rx_fifo_size, tx_fifo_size, pair_size;
+ u32 approx_segment_count;
+
/* Figure out how many segments should be preallocated */
rx_rounded_data_size = (1 << (max_log2 (props->rx_fifo_size)));
tx_rounded_data_size = (1 << (max_log2 (props->tx_fifo_size)));
@@ -383,36 +375,51 @@ segment_manager_init (segment_manager_t * sm)
/* Allocate the segments */
for (i = 0; i < approx_segment_count + 1; i++)
{
- seg_index = segment_manager_add_segment (sm, max_seg_size);
- if (seg_index < 0)
+ fs_index = segment_manager_add_segment (sm, max_seg_size);
+ if (fs_index < 0)
{
clib_warning ("Failed to preallocate segment %d", i);
- return seg_index;
+ return fs_index;
}
- segment = segment_manager_get_segment (sm, seg_index);
+ fs = segment_manager_get_segment (sm, fs_index);
if (i == 0)
- sm->event_queue = segment_manager_alloc_queue (segment, props);
+ sm->event_queue = segment_manager_alloc_queue (fs, props);
- fifo_segment_preallocate_fifo_pairs (segment,
+ fifo_segment_preallocate_fifo_pairs (fs,
props->rx_fifo_size,
props->tx_fifo_size,
&prealloc_fifo_pairs);
- fifo_segment_flags (segment) = FIFO_SEGMENT_F_IS_PREALLOCATED;
+ fifo_segment_flags (fs) = FIFO_SEGMENT_F_IS_PREALLOCATED;
if (prealloc_fifo_pairs == 0)
break;
}
+ return 0;
}
- else
+
+ fs_index = segment_manager_add_segment (sm, first_seg_size);
+ if (fs_index < 0)
+ {
+ clib_warning ("Failed to allocate segment");
+ return fs_index;
+ }
+
+ fs = segment_manager_get_segment (sm, fs_index);
+ sm->event_queue = segment_manager_alloc_queue (fs, props);
+
+ if (props->prealloc_fifo_hdrs)
{
- seg_index = segment_manager_add_segment (sm, first_seg_size);
- if (seg_index < 0)
+ u32 hdrs_per_slice;
+
+ /* Do not preallocate on slice associated to main thread */
+ i = (vlib_num_workers ()? 1 : 0);
+ hdrs_per_slice = props->prealloc_fifo_hdrs / (fs->n_slices - i);
+
+ for (; i < fs->n_slices; i++)
{
- clib_warning ("Failed to allocate segment");
- return seg_index;
+ if (fifo_segment_prealloc_fifo_hdrs (fs, i, hdrs_per_slice))
+ return VNET_API_ERROR_SVM_SEGMENT_CREATE_FAIL;
}
- segment = segment_manager_get_segment (sm, seg_index);
- sm->event_queue = segment_manager_alloc_queue (segment, props);
}
return 0;
nt-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
/*
 *------------------------------------------------------------------
 * api.h
 *
 * Copyright (c) 2009-2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *------------------------------------------------------------------
 */

#ifndef included_api_h
#define included_api_h

#include <stddef.h>
#include <vppinfra/error.h>
#include <svm/svm.h>
#include <vlib/vlib.h>
#include <vlibmemory/unix_shared_memory_queue.h>
#include <vlib/unix/unix.h>
#include <vlibapi/api_common.h>

/* *INDENT-OFF* */
typedef CLIB_PACKED
(struct
 {
   u8 endian; u8 wrapped;
   u32 nitems;
}) vl_api_trace_file_header_t;
/* *INDENT-ON* */

int vl_msg_api_trace_save (api_main_t * am,
			   vl_api_trace_which_t which, FILE * fp);

#define VLIB_API_INIT_FUNCTION(x) VLIB_DECLARE_INIT_FUNCTION(x,api_init)

/* Call given init function: used for init function dependencies. */
#define vlib_call_api_init_function(vm, x)                              \
  ({                                                                    \
    extern vlib_init_function_t * _VLIB_INIT_FUNCTION_SYMBOL (x,api_init); \
    vlib_init_function_t * _f = _VLIB_INIT_FUNCTION_SYMBOL (x,api_init); \
    clib_error_t * _error = 0;                                          \
    if (! hash_get (vm->init_functions_called, _f))                     \
      {                                                                 \
	hash_set1 (vm->init_functions_called, _f);                      \
	_error = _f (vm);                                               \
      }                                                                 \
    _error;                                                             \
  })


#define _VL_MSG_API_FUNCTION_SYMBOL(x, type)	\
  _vl_msg_api_##type##_function_##x

#define VL_MSG_API_FUNCTION_SYMBOL(x)		\
  _VL_MSG_API_FUNCTION_SYMBOL(x, reaper)

#define VLIB_DECLARE_REAPER_FUNCTION(x, tag)                            \
vl_msg_api_init_function_t * _VL_MSG_API_FUNCTION_SYMBOL (x, tag) = x;  \
static void __vl_msg_api_add_##tag##_function_##x (void)                \
    __attribute__((__constructor__)) ;                                  \
                                                                        \
static void __vl_msg_api_add_##tag##_function_##x (void)                \
{                                                                       \
 api_main_t * am = &api_main;                                           \
 static _vl_msg_api_function_list_elt_t _vl_msg_api_function;           \
 _vl_msg_api_function.next_init_function                                \
    = am->tag##_function_registrations;                                 \
  am->tag##_function_registrations = &_vl_msg_api_function;             \
 _vl_msg_api_function.f = &x;                                           \
}

#define VL_MSG_API_REAPER_FUNCTION(x) VLIB_DECLARE_REAPER_FUNCTION(x,reaper)

/* Call reaper function with client index */
#define vl_msg_api_call_reaper_function(ci)                             \
  ({                                                                    \
    extern vlib_init_function_t * VLIB_INIT_FUNCTION_SYMBOL (reaper);   \
    vlib_init_function_t * _f = VLIB_INIT_FUNCTION_SYMBOL (reaper);     \
    clib_error_t * _error = 0;                                          \
    _error = _f (ci);                                                   \
  })

static inline u32
vl_msg_api_get_msg_length_inline (void *msg_arg)
{
  u8 *msg = (u8 *) msg_arg;

  msgbuf_t *header = (msgbuf_t *) (msg - offsetof (msgbuf_t, data));

  return clib_net_to_host_u32 (header->data_len);
}

int vl_msg_api_rx_trace_enabled (api_main_t * am);
int vl_msg_api_tx_trace_enabled (api_main_t * am);
void vl_msg_api_trace (api_main_t * am, vl_api_trace_t * tp, void *msg);
int vl_msg_api_trace_onoff (api_main_t * am, vl_api_trace_which_t which,
			    int onoff);
int vl_msg_api_trace_free (api_main_t * am, vl_api_trace_which_t which);
int vl_msg_api_trace_configure (api_main_t * am, vl_api_trace_which_t which,
				u32 nitems);
void vl_msg_api_handler_with_vm_node (api_main_t * am,
				      void *the_msg, vlib_main_t * vm,
				      vlib_node_runtime_t * node);
vl_api_trace_t *vl_msg_api_trace_get (api_main_t * am,
				      vl_api_trace_which_t which);
void vl_msg_api_add_msg_name_crc (api_main_t * am, const char *string,
				  u32 id);
void vl_msg_api_add_version (api_main_t * am, const char *string,
			     u32 major, u32 minor, u32 patch);
/* node_serialize.c prototypes */
u8 *vlib_node_serialize (vlib_node_main_t * nm, u8 * vector,
			 u32 max_threads, int include_nexts,
			 int include_stats);
vlib_node_t **vlib_node_unserialize (u8 * vector);
u32 vl_msg_api_get_msg_length (void *msg_arg);

#endif /* included_api_h */
/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */