session: add option to preallocate fifo headers
Type: feature Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: Ie47546ef36590b90ed481b14cf812afbecf7981c
This commit is contained in:
committed by
Dave Barach
parent
933c4ca5a0
commit
9845c20d77
@@ -642,7 +642,7 @@ echo_clients_attach (u8 * appns_id, u64 appns_flags, u64 appns_secret)
|
||||
u32 prealloc_fifos, segment_size = 256 << 20;
|
||||
echo_client_main_t *ecm = &echo_client_main;
|
||||
vnet_app_attach_args_t _a, *a = &_a;
|
||||
u64 options[17];
|
||||
u64 options[18];
|
||||
int rv;
|
||||
|
||||
clib_memset (a, 0, sizeof (*a));
|
||||
|
||||
@@ -697,6 +697,58 @@ segment_manager_test_fifo_ops (vlib_main_t * vm, unformat_input_t * input)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
segment_manager_test_prealloc_hdrs (vlib_main_t * vm,
|
||||
unformat_input_t * input)
|
||||
{
|
||||
u32 fifo_size = size_4KB, prealloc_hdrs, sm_index, fs_index;
|
||||
u64 options[APP_OPTIONS_N_OPTIONS];
|
||||
uword app_seg_size = size_2MB;
|
||||
segment_manager_t *sm;
|
||||
fifo_segment_t *fs;
|
||||
int rv;
|
||||
|
||||
memset (&options, 0, sizeof (options));
|
||||
|
||||
vnet_app_attach_args_t attach_args = {
|
||||
.api_client_index = ~0,
|
||||
.options = options,
|
||||
.namespace_id = 0,
|
||||
.session_cb_vft = &dummy_session_cbs,
|
||||
.name = format (0, "segment_manager_prealloc_hdrs"),
|
||||
};
|
||||
|
||||
prealloc_hdrs = (app_seg_size - (16 << 10)) / sizeof (svm_fifo_t);
|
||||
|
||||
attach_args.options[APP_OPTIONS_SEGMENT_SIZE] = app_seg_size;
|
||||
attach_args.options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
|
||||
attach_args.options[APP_OPTIONS_RX_FIFO_SIZE] = fifo_size;
|
||||
attach_args.options[APP_OPTIONS_TX_FIFO_SIZE] = fifo_size;
|
||||
attach_args.options[APP_OPTIONS_PREALLOC_FIFO_HDRS] = prealloc_hdrs;
|
||||
|
||||
rv = vnet_application_attach (&attach_args);
|
||||
vec_free (attach_args.name);
|
||||
|
||||
SEG_MGR_TEST ((rv == 0), "vnet_application_attach %d", rv);
|
||||
|
||||
segment_manager_parse_segment_handle (attach_args.segment_handle, &sm_index,
|
||||
&fs_index);
|
||||
sm = segment_manager_get (sm_index);
|
||||
|
||||
SEG_MGR_TEST ((sm != 0), "seg manager is valid", sm);
|
||||
|
||||
fs = segment_manager_get_segment (sm, fs_index);
|
||||
SEG_MGR_TEST (fifo_segment_num_free_fifos (fs) == prealloc_hdrs,
|
||||
"prealloc should be %u", prealloc_hdrs);
|
||||
|
||||
vnet_app_detach_args_t detach_args = {
|
||||
.app_index = attach_args.app_index,
|
||||
.api_client_index = ~0,
|
||||
};
|
||||
rv = vnet_application_detach (&detach_args);
|
||||
SEG_MGR_TEST ((rv == 0), "vnet_application_detach %d", rv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static clib_error_t *
|
||||
segment_manager_test (vlib_main_t * vm,
|
||||
@@ -716,6 +768,8 @@ segment_manager_test (vlib_main_t * vm,
|
||||
res = segment_manager_test_fifo_balanced_alloc (vm, input);
|
||||
else if (unformat (input, "fifo_ops"))
|
||||
res = segment_manager_test_fifo_ops (vm, input);
|
||||
else if (unformat (input, "prealloc_hdrs"))
|
||||
res = segment_manager_test_prealloc_hdrs (vm, input);
|
||||
|
||||
else if (unformat (input, "all"))
|
||||
{
|
||||
@@ -727,6 +781,8 @@ segment_manager_test (vlib_main_t * vm,
|
||||
goto done;
|
||||
if ((res = segment_manager_test_fifo_ops (vm, input)))
|
||||
goto done;
|
||||
if ((res = segment_manager_test_prealloc_hdrs (vm, input)))
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
break;
|
||||
@@ -743,7 +799,7 @@ VLIB_CLI_COMMAND (tcp_test_command, static) =
|
||||
{
|
||||
.path = "test segment-manager",
|
||||
.short_help = "test segment manager [pressure_levels_1]"
|
||||
"[pressure_level_2][alloc][fifo_ops][all]",
|
||||
"[pressure_level_2][alloc][fifo_ops][prealloc_hdrs][all]",
|
||||
.function = segment_manager_test,
|
||||
};
|
||||
|
||||
|
||||
@@ -517,6 +517,10 @@ application_alloc_and_init (app_init_args_t * a)
|
||||
if (!application_verify_cfg (seg_type))
|
||||
return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
|
||||
|
||||
if (options[APP_OPTIONS_PREALLOC_FIFO_PAIRS]
|
||||
&& options[APP_OPTIONS_PREALLOC_FIFO_HDRS])
|
||||
return VNET_API_ERROR_APP_UNSUPPORTED_CFG;
|
||||
|
||||
/* Check that the obvious things are properly set up */
|
||||
application_verify_cb_fns (a->session_cb_vft);
|
||||
|
||||
@@ -535,6 +539,7 @@ application_alloc_and_init (app_init_args_t * a)
|
||||
segment_manager_props_init (props);
|
||||
props->segment_size = options[APP_OPTIONS_SEGMENT_SIZE];
|
||||
props->prealloc_fifos = options[APP_OPTIONS_PREALLOC_FIFO_PAIRS];
|
||||
props->prealloc_fifo_hdrs = options[APP_OPTIONS_PREALLOC_FIFO_HDRS];
|
||||
if (options[APP_OPTIONS_ADD_SEGMENT_SIZE])
|
||||
{
|
||||
props->add_segment_size = options[APP_OPTIONS_ADD_SEGMENT_SIZE];
|
||||
|
||||
@@ -200,6 +200,7 @@ typedef enum
|
||||
APP_OPTIONS_RX_FIFO_SIZE,
|
||||
APP_OPTIONS_TX_FIFO_SIZE,
|
||||
APP_OPTIONS_PREALLOC_FIFO_PAIRS,
|
||||
APP_OPTIONS_PREALLOC_FIFO_HDRS,
|
||||
APP_OPTIONS_NAMESPACE,
|
||||
APP_OPTIONS_NAMESPACE_SECRET,
|
||||
APP_OPTIONS_PROXY_TRANSPORT,
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
seg_index = segment_manager_add_segment (sm, first_seg_size);
|
||||
if (seg_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)
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -27,6 +27,7 @@ typedef struct _segment_manager_props
|
||||
u32 tx_fifo_size; /**< transmit fifo size */
|
||||
u32 evt_q_size; /**< event queue length */
|
||||
u32 prealloc_fifos; /**< preallocated fifo pairs */
|
||||
u32 prealloc_fifo_hdrs; /**< preallocated fifo hdrs */
|
||||
uword segment_size; /**< first segment size */
|
||||
uword add_segment_size; /**< additional segment size */
|
||||
u8 add_segment:1; /**< can add new segments flag */
|
||||
@@ -159,6 +160,14 @@ void segment_manager_main_init (segment_manager_main_init_args_t * a);
|
||||
segment_manager_props_t *segment_manager_props_init (segment_manager_props_t *
|
||||
sm);
|
||||
|
||||
static inline 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;
|
||||
}
|
||||
|
||||
#endif /* SRC_VNET_SESSION_SEGMENT_MANAGER_H_ */
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
option version = "3.1.0";
|
||||
option version = "3.2.0";
|
||||
|
||||
import "vnet/interface_types.api";
|
||||
import "vnet/ip/ip_types.api";
|
||||
@@ -37,7 +37,7 @@ enum transport_proto : u8
|
||||
define app_attach {
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
u64 options[17];
|
||||
u64 options[18];
|
||||
string namespace_id[];
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user