2 #include <vnet/plugin/plugin.h>
3 #include <vpp/app/version.h>
4 #include <vnet/session/session.h>
5 #include <vnet/session/segment_manager.h>
6 #include <vnet/session/application.h>
8 #define SEG_MGR_TEST_I(_cond, _comment, _args...) \
10 int _evald = (_cond); \
12 fformat(stderr, "FAIL:%d: " _comment "\n", \
15 fformat(stderr, "PASS:%d: " _comment "\n", \
21 #define SEG_MGR_TEST(_cond, _comment, _args...) \
23 if (!SEG_MGR_TEST_I(_cond, _comment, ##_args)) { \
28 #define ST_DBG(_comment, _args...) \
29 fformat(stderr, _comment "\n", ##_args); \
31 #define SEGMENT_MANAGER_GET_INDEX_FROM_HANDLE(x) (x >> 32)
33 /* placeholder callback functions */
35 placeholder_session_reset_callback (session_t * s)
37 clib_warning ("called...");
41 placeholder_session_connected_callback (u32 app_index, u32 api_context,
42 session_t * s, session_error_t err)
44 clib_warning ("called...");
49 placeholder_add_segment_callback (u32 client_index, u64 segment_handle)
51 clib_warning ("called...");
56 placeholder_del_segment_callback (u32 client_index, u64 segment_handle)
58 clib_warning ("called...");
63 placeholder_session_disconnect_callback (session_t * s)
65 clib_warning ("called...");
69 placeholder_session_accept_callback (session_t * s)
71 clib_warning ("called...");
76 placeholder_server_rx_callback (session_t * s)
78 clib_warning ("called...");
82 static session_cb_vft_t placeholder_session_cbs = {
83 .session_reset_callback = placeholder_session_reset_callback,
84 .session_connected_callback = placeholder_session_connected_callback,
85 .session_accept_callback = placeholder_session_accept_callback,
86 .session_disconnect_callback = placeholder_session_disconnect_callback,
87 .builtin_app_rx_callback = placeholder_server_rx_callback,
88 .add_segment_callback = placeholder_add_segment_callback,
89 .del_segment_callback = placeholder_del_segment_callback,
92 static char *states_str[] = {
93 #define _(sym,str) str,
94 foreach_segment_mem_status
98 static u32 size_4KB = 4 << 10;
99 static u32 size_8KB = 8 << 10;
100 static u32 size_12KB = 12 << 10;
101 static u32 size_16KB = 16 << 10;
102 static u32 size_20KB = 20 << 10;
103 static u32 size_32KB = 32 << 10;
104 static u32 size_52KB = 52 << 10;
105 static u32 size_64KB = 64 << 10;
106 static u32 size_128KB = 128 << 10;
107 static u32 size_1MB = 1 << 20;
108 static u32 size_2MB = 2 << 20;
112 segment_manager_test_pressure_1 (vlib_main_t * vm, unformat_input_t * input)
115 segment_manager_t *sm;
116 fifo_segment_t *fs0, *fs;
117 svm_fifo_t *rx_fifo, *tx_fifo;
118 uword app_seg_size = size_2MB;
119 u32 fifo_size = size_128KB;
120 u64 options[APP_OPTIONS_N_OPTIONS];
123 memset (&options, 0, sizeof (options));
125 vnet_app_attach_args_t attach_args = {
126 .api_client_index = ~0,
129 .session_cb_vft = &placeholder_session_cbs,
130 .name = format (0, "segment_manager_test_pressure_1"),
133 attach_args.options[APP_OPTIONS_SEGMENT_SIZE] = app_seg_size;
134 attach_args.options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
135 attach_args.options[APP_OPTIONS_RX_FIFO_SIZE] = fifo_size;
136 attach_args.options[APP_OPTIONS_TX_FIFO_SIZE] = fifo_size;
137 rv = vnet_application_attach (&attach_args);
138 SEG_MGR_TEST ((rv == 0), "vnet_application_attach %d", rv);
141 segment_manager_get (SEGMENT_MANAGER_GET_INDEX_FROM_HANDLE
142 (attach_args.segment_handle));
143 SEG_MGR_TEST ((sm != 0), "segment_manager_get %p", sm);
145 /* initial status : (0 / 2MB) */
146 fs0 = segment_manager_get_segment (sm, 0);
147 rv = fifo_segment_get_mem_status (fs0);
148 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_NO_PRESSURE),
149 "fifo_segment_get_mem_status %s", states_str[rv]);
152 /* allocate a fifo : 128KB x2 */
153 rv = segment_manager_alloc_session_fifos (sm,
154 vlib_get_thread_index (),
156 SEG_MGR_TEST ((rv == 0), "segment_manager_alloc_session_fifos %d", rv);
158 svm_fifo_set_size (rx_fifo, size_1MB);
159 svm_fifo_set_size (tx_fifo, size_1MB);
161 fs = segment_manager_get_segment (sm, rx_fifo->segment_index);
162 SEG_MGR_TEST ((fs == fs0), "fs %p", fs);
164 /* fill fifos (but not add chunks) */
165 svm_fifo_enqueue (rx_fifo, fifo_size - 1, data);
166 svm_fifo_enqueue (tx_fifo, fifo_size - 1, data);
168 /* 256KB+ / 2048KB+ => ~12% */
169 rv = fifo_segment_get_mem_status (fs);
170 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_NO_PRESSURE),
171 "fifo_segment_get_mem_status %s", states_str[rv]);
174 svm_fifo_enqueue (rx_fifo, fifo_size, data);
175 svm_fifo_enqueue (rx_fifo, fifo_size, data);
176 svm_fifo_enqueue (rx_fifo, fifo_size, data);
177 svm_fifo_enqueue (tx_fifo, fifo_size, data);
178 svm_fifo_enqueue (tx_fifo, fifo_size, data);
180 /* 7 chunks : ~44% */
181 rv = fifo_segment_get_mem_status (fs);
182 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_NO_PRESSURE),
183 "fifo_segment_get_mem_status %s", states_str[rv]);
186 svm_fifo_enqueue (tx_fifo, fifo_size, data);
187 svm_fifo_enqueue (rx_fifo, fifo_size, data);
188 svm_fifo_enqueue (tx_fifo, fifo_size, data);
190 /* 10 chunks : 61% */
191 rv = fifo_segment_get_mem_status (fs);
192 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_LOW_PRESSURE),
193 "fifo_segment_get_mem_status %s", states_str[rv]);
196 svm_fifo_enqueue (rx_fifo, fifo_size, data);
197 svm_fifo_enqueue (rx_fifo, fifo_size, data);
198 svm_fifo_enqueue (tx_fifo, fifo_size, data);
199 svm_fifo_enqueue (tx_fifo, fifo_size, data);
201 /* 14 chunks : 85% */
202 rv = fifo_segment_get_mem_status (fs);
203 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_HIGH_PRESSURE),
204 "fifo_segment_get_mem_status %s", states_str[rv]);
208 svm_fifo_dequeue_drop (rx_fifo, fifo_size);
209 svm_fifo_dequeue_drop (rx_fifo, fifo_size);
210 svm_fifo_dequeue_drop (tx_fifo, fifo_size);
211 svm_fifo_dequeue_drop (tx_fifo, fifo_size);
213 /* 10 chunks : 63% */
214 rv = fifo_segment_get_mem_status (fs);
215 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_LOW_PRESSURE),
216 "fifo_segment_get_mem_status %s", states_str[rv]);
220 svm_fifo_enqueue (rx_fifo, fifo_size, data);
221 svm_fifo_enqueue (rx_fifo, fifo_size, data);
222 svm_fifo_enqueue (tx_fifo, fifo_size, data);
223 svm_fifo_enqueue (tx_fifo, fifo_size, data);
225 /* 14 chunks : 88% */
226 rv = fifo_segment_get_mem_status (fs);
227 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_HIGH_PRESSURE),
228 "fifo_segment_get_mem_status %s", states_str[rv]);
230 svm_fifo_dequeue_drop (rx_fifo, fifo_size);
231 svm_fifo_dequeue_drop (rx_fifo, fifo_size);
232 svm_fifo_dequeue_drop (tx_fifo, fifo_size);
233 svm_fifo_dequeue_drop (tx_fifo, fifo_size);
235 /* 10 chunks : 63% */
236 rv = fifo_segment_get_mem_status (fs);
237 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_LOW_PRESSURE),
238 "fifo_segment_get_mem_status %s", states_str[rv]);
241 svm_fifo_dequeue_drop (rx_fifo, fifo_size);
242 svm_fifo_dequeue_drop (rx_fifo, fifo_size);
243 svm_fifo_dequeue_drop (rx_fifo, fifo_size);
244 svm_fifo_dequeue_drop (rx_fifo, fifo_size);
245 svm_fifo_dequeue_drop (tx_fifo, fifo_size);
246 svm_fifo_dequeue_drop (tx_fifo, fifo_size);
247 svm_fifo_dequeue_drop (tx_fifo, fifo_size);
248 svm_fifo_dequeue_drop (tx_fifo, fifo_size);
251 rv = fifo_segment_get_mem_status (fs);
252 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_NO_PRESSURE),
253 "fifo_segment_get_mem_status %s", states_str[rv]);
256 vnet_app_detach_args_t detach_args = {
257 .app_index = attach_args.app_index,
258 .api_client_index = ~0,
260 rv = vnet_application_detach (&detach_args);
261 SEG_MGR_TEST ((rv == 0), "vnet_application_detach %d", rv);
267 segment_manager_test_pressure_2 (vlib_main_t * vm, unformat_input_t * input)
270 segment_manager_t *sm;
271 fifo_segment_t *fs0, *fs;
272 svm_fifo_t *rx_fifo, *tx_fifo;
273 uword app_seg_size = size_2MB;
274 u32 fifo_size = size_4KB;
275 u64 options[APP_OPTIONS_N_OPTIONS];
278 memset (&options, 0, sizeof (options));
280 vnet_app_attach_args_t attach_args = {
281 .api_client_index = ~0,
284 .session_cb_vft = &placeholder_session_cbs,
285 .name = format (0, "segment_manager_test_pressure_2"),
288 attach_args.options[APP_OPTIONS_SEGMENT_SIZE] = app_seg_size;
289 attach_args.options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
290 attach_args.options[APP_OPTIONS_RX_FIFO_SIZE] = fifo_size;
291 attach_args.options[APP_OPTIONS_TX_FIFO_SIZE] = fifo_size;
292 rv = vnet_application_attach (&attach_args);
293 SEG_MGR_TEST ((rv == 0), "vnet_application_attach %d", rv);
296 segment_manager_get (SEGMENT_MANAGER_GET_INDEX_FROM_HANDLE
297 (attach_args.segment_handle));
298 SEG_MGR_TEST ((sm != 0), "segment_manager_get %p", sm);
300 /* initial status : (0 / 2MB) */
301 fs0 = segment_manager_get_segment (sm, 0);
302 rv = fifo_segment_get_mem_status (fs0);
303 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_NO_PRESSURE),
304 "fifo_segment_get_mem_status %s", states_str[rv]);
307 /* allocate fifos : 4KB x2 */
308 rv = segment_manager_alloc_session_fifos (sm,
309 vlib_get_thread_index (),
311 SEG_MGR_TEST ((rv == 0), "segment_manager_alloc_session_fifos %d", rv);
313 svm_fifo_set_size (rx_fifo, size_1MB);
314 svm_fifo_set_size (tx_fifo, size_1MB);
316 /* fill fifos (but not add chunks) */
317 svm_fifo_enqueue (rx_fifo, fifo_size - 1, data);
318 svm_fifo_enqueue (tx_fifo, fifo_size - 1, data);
320 fs = segment_manager_get_segment (sm, rx_fifo->segment_index);
323 for (i = 0; i < 509; ++i)
325 svm_fifo_enqueue (rx_fifo, fifo_size, data);
326 svm_fifo_enqueue (tx_fifo, fifo_size, data);
330 rv = fifo_segment_get_mem_status (fs);
331 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_HIGH_PRESSURE),
332 "fifo_segment_get_mem_status %s", states_str[rv]);
334 /* this fifo growth is expected to fail */
335 rv = svm_fifo_enqueue (rx_fifo, fifo_size, data);
336 SEG_MGR_TEST ((rv == SVM_FIFO_EGROW), "svm_fifo_enqueue %d", rv);
339 for (i = 0; i < 20; ++i)
341 svm_fifo_dequeue_drop (rx_fifo, fifo_size);
342 svm_fifo_dequeue_drop (tx_fifo, fifo_size);
345 /* 489 chunks : 96%, it is high-pressure level
346 * but the reached-mem-limit record is not reset
347 * so the no-memory state lasts.
350 rv = fifo_segment_get_mem_status (fs);
351 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_NO_MEMORY),
352 "fifo_segment_get_mem_status %s", states_str[rv]);
356 for (i = 0; i < 133; ++i)
358 svm_fifo_dequeue_drop (rx_fifo, fifo_size);
361 /* 356 chunks : 70% of 2MB */
362 rv = fifo_segment_get_mem_status (fs);
363 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_LOW_PRESSURE),
364 "fifo_segment_get_mem_status %s", states_str[rv]);
367 for (i = 0; i < 360; ++i)
369 svm_fifo_dequeue_drop (rx_fifo, fifo_size);
370 svm_fifo_dequeue_drop (tx_fifo, fifo_size);
373 /* 2 chunks : 3% of 2MB */
374 rv = fifo_segment_get_mem_status (fs);
375 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_NO_PRESSURE),
376 "fifo_segment_get_mem_status %s", states_str[rv]);
379 vnet_app_detach_args_t detach_args = {
380 .app_index = attach_args.app_index,
381 .api_client_index = ~0,
383 rv = vnet_application_detach (&detach_args);
384 SEG_MGR_TEST ((rv == 0), "vnet_application_detach %d", rv);
390 segment_manager_test_fifo_balanced_alloc (vlib_main_t * vm,
391 unformat_input_t * input)
394 segment_manager_t *sm;
395 fifo_segment_t *fs[4];
396 svm_fifo_t *rx_fifo[4], *tx_fifo[4];
397 uword app_seg_size = size_2MB;
398 u32 fifo_size = size_4KB;
399 u64 options[APP_OPTIONS_N_OPTIONS];
402 memset (&options, 0, sizeof (options));
404 vnet_app_attach_args_t attach_args = {
405 .api_client_index = ~0,
408 .session_cb_vft = &placeholder_session_cbs,
409 .name = format (0, "segment_manager_test_fifo_balanced_alloc"),
412 attach_args.options[APP_OPTIONS_SEGMENT_SIZE] = app_seg_size;
413 attach_args.options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
414 attach_args.options[APP_OPTIONS_RX_FIFO_SIZE] = fifo_size;
415 attach_args.options[APP_OPTIONS_TX_FIFO_SIZE] = fifo_size;
416 rv = vnet_application_attach (&attach_args);
417 SEG_MGR_TEST ((rv == 0), "vnet_application_attach %d", rv);
420 segment_manager_get (SEGMENT_MANAGER_GET_INDEX_FROM_HANDLE
421 (attach_args.segment_handle));
422 SEG_MGR_TEST ((sm != 0), "segment_manager_get %p", sm);
424 /* initial status : (0 / 2MB) */
425 fs[0] = segment_manager_get_segment (sm, 0);
426 rv = fifo_segment_get_mem_status (fs[0]);
427 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_NO_PRESSURE),
428 "fifo_segment_get_mem_status %s", states_str[rv]);
430 /* allocate fifos : 4KB x2 */
431 rv = segment_manager_alloc_session_fifos (sm,
432 vlib_get_thread_index (),
433 &rx_fifo[0], &tx_fifo[0]);
434 SEG_MGR_TEST ((rv == 0), "segment_manager_alloc_session_fifos %d", rv);
435 SEG_MGR_TEST ((rx_fifo[0]->segment_index == 0),
436 "segment_index %d", rx_fifo[0]->segment_index);
437 SEG_MGR_TEST ((tx_fifo[0]->segment_index == 0),
438 "segment_index %d", tx_fifo[0]->segment_index);
441 svm_fifo_set_size (rx_fifo[0], size_1MB);
442 for (i = 0; i < 200; ++i)
444 svm_fifo_enqueue (rx_fifo[0], fifo_size, data);
447 /* add another 2MB segment */
448 fs_index = segment_manager_add_segment (sm, size_2MB, 0);
449 SEG_MGR_TEST ((fs_index == 1), "fs_index %d", fs_index);
451 /* allocate fifos : 4KB x2
452 * expected to be allocated on the newer segment,
453 * because the usage of the first segment is high.
455 rv = segment_manager_alloc_session_fifos (sm,
456 vlib_get_thread_index (),
457 &rx_fifo[1], &tx_fifo[1]);
458 SEG_MGR_TEST ((rv == 0), "segment_manager_alloc_session_fifos %d", rv);
459 SEG_MGR_TEST ((rx_fifo[1]->segment_index == 1),
460 "segment_index %d", rx_fifo[1]->segment_index);
461 SEG_MGR_TEST ((tx_fifo[1]->segment_index == 1),
462 "segment_index %d", tx_fifo[1]->segment_index);
464 /* allocate fifos : 4KB x2
465 * expected to be allocated on the newer segment.
467 rv = segment_manager_alloc_session_fifos (sm,
468 vlib_get_thread_index (),
469 &rx_fifo[2], &tx_fifo[2]);
470 SEG_MGR_TEST ((rv == 0), "segment_manager_alloc_session_fifos %d", rv);
471 SEG_MGR_TEST ((rx_fifo[2]->segment_index == 1),
472 "segment_index %d", rx_fifo[2]->segment_index);
473 SEG_MGR_TEST ((tx_fifo[2]->segment_index == 1),
474 "segment_index %d", tx_fifo[2]->segment_index);
476 /* grow fifos, so the usage of the secong segment becomes
477 * higher than the first one.
479 svm_fifo_set_size (rx_fifo[1], size_1MB);
480 for (i = 0; i < 400; ++i)
482 svm_fifo_enqueue (rx_fifo[1], fifo_size, data);
485 /* allocate fifos : 4KB x2
486 * expected to be allocated on the first segment.
488 rv = segment_manager_alloc_session_fifos (sm,
489 vlib_get_thread_index (),
490 &rx_fifo[3], &tx_fifo[3]);
491 SEG_MGR_TEST ((rv == 0), "segment_manager_alloc_session_fifos %d", rv);
492 SEG_MGR_TEST ((rx_fifo[3]->segment_index == 0),
493 "segment_index %d", rx_fifo[3]->segment_index);
494 SEG_MGR_TEST ((tx_fifo[3]->segment_index == 0),
495 "segment_index %d", tx_fifo[3]->segment_index);
499 vnet_app_detach_args_t detach_args = {
500 .app_index = attach_args.app_index,
501 .api_client_index = ~0,
503 rv = vnet_application_detach (&detach_args);
504 SEG_MGR_TEST ((rv == 0), "vnet_application_detach %d", rv);
509 /* disabled until fifo tuning and memory pressure are properly working */
510 __clib_unused static int
511 segment_manager_test_fifo_ops (vlib_main_t *vm, unformat_input_t *input)
514 segment_manager_t *sm;
516 svm_fifo_t *rx_fifo, *tx_fifo;
517 uword app_seg_size = size_2MB, most_grown = 0;
518 u32 fifo_size = size_4KB;
520 u64 options[APP_OPTIONS_N_OPTIONS];
523 memset (&options, 0, sizeof (options));
525 vnet_app_attach_args_t attach_args = {
526 .api_client_index = ~0,
529 .session_cb_vft = &placeholder_session_cbs,
530 .name = format (0, "segment_manager_test_pressure_1"),
533 attach_args.options[APP_OPTIONS_SEGMENT_SIZE] = app_seg_size;
534 attach_args.options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
535 attach_args.options[APP_OPTIONS_RX_FIFO_SIZE] = fifo_size;
536 attach_args.options[APP_OPTIONS_TX_FIFO_SIZE] = fifo_size;
537 rv = vnet_application_attach (&attach_args);
538 SEG_MGR_TEST ((rv == 0), "vnet_application_attach %d", rv);
541 segment_manager_get (SEGMENT_MANAGER_GET_INDEX_FROM_HANDLE
542 (attach_args.segment_handle));
543 SEG_MGR_TEST ((sm != 0), "segment_manager_get %p", sm);
545 /* initial status : (0 / 2MB) */
546 fs = segment_manager_get_segment (sm, 0);
547 rv = fifo_segment_get_mem_status (fs);
548 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_NO_PRESSURE),
549 "fifo_segment_get_mem_status %s", states_str[rv]);
551 /* allocate fifos : 4KB x2 */
552 rv = segment_manager_alloc_session_fifos (sm,
553 vlib_get_thread_index (),
555 SEG_MGR_TEST ((rv == 0), "segment_manager_alloc_session_fifos %d", rv);
557 /* check the initial fifo size : 4KB */
558 rv = svm_fifo_size (rx_fifo);
559 SEG_MGR_TEST ((rv == size_4KB), "svm_fifo_size %d", rv);
562 rv = svm_fifo_enqueue (rx_fifo, size_4KB, data);
563 SEG_MGR_TEST ((rv == size_4KB), "svm_fifo_enqueue %d", rv);
564 max_dequeue = svm_fifo_max_dequeue (rx_fifo);
565 SEG_MGR_TEST ((max_dequeue == size_4KB), "max_dequeue %u", max_dequeue);
567 /* grow the fifo size : 4KB -> 8KB */
568 svm_fifo_set_size (rx_fifo, size_8KB);
569 rv = svm_fifo_size (rx_fifo);
570 SEG_MGR_TEST ((rv == size_8KB), "svm_fifo_size %d", rv);
572 /* verify that fifo cannot grow larger than the fifo size */
573 /* 4KB + 8KB > 8KB, so only 4KB is queued */
574 rv = svm_fifo_enqueue (rx_fifo, size_8KB, data);
575 SEG_MGR_TEST ((rv == size_4KB), "svm_fifo_enqueue %d", rv);
576 max_dequeue = svm_fifo_max_dequeue (rx_fifo);
577 SEG_MGR_TEST ((max_dequeue == size_8KB), "max_dequeue %u", max_dequeue);
579 /* grow the fifo size : 8KB -> 16KB */
580 svm_fifo_set_size (rx_fifo, size_16KB);
582 /* 8KB + 4KB = 12KB */
583 svm_fifo_enqueue (rx_fifo, size_4KB, data);
584 max_dequeue = svm_fifo_max_dequeue (rx_fifo);
585 SEG_MGR_TEST ((max_dequeue == size_12KB), "max_dequeue %u", max_dequeue);
587 /* grow the fifo size : 16KB -> 32KB */
588 svm_fifo_set_size (rx_fifo, size_32KB);
590 /* 12KB + 8KB = 20KB */
591 svm_fifo_enqueue (rx_fifo, size_8KB, data);
592 max_dequeue = svm_fifo_max_dequeue (rx_fifo);
593 SEG_MGR_TEST ((max_dequeue == size_20KB), "max_dequeue %u", max_dequeue);
595 /* grow the fifo size : 32KB -> 64KB */
596 svm_fifo_set_size (rx_fifo, size_64KB);
598 /* 20KB + 32KB = 52KB */
599 svm_fifo_enqueue (rx_fifo, size_32KB, data);
600 max_dequeue = svm_fifo_max_dequeue (rx_fifo);
601 SEG_MGR_TEST ((max_dequeue == size_52KB), "max_dequeue %u", max_dequeue);
604 for (i = 0; i < 55; ++i)
606 svm_fifo_set_size (rx_fifo, svm_fifo_size (rx_fifo) + size_32KB);
607 svm_fifo_enqueue (rx_fifo, size_32KB, data);
609 max_dequeue = svm_fifo_max_dequeue (rx_fifo);
610 SEG_MGR_TEST ((max_dequeue == (size_52KB + size_32KB * 55)),
611 "max_dequeue %u", max_dequeue);
612 rv = fifo_segment_get_mem_status (fs);
613 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_HIGH_PRESSURE),
614 "fifo_segment_get_mem_status %s", states_str[rv]);
615 most_grown = svm_fifo_size (rx_fifo);
618 svm_fifo_dequeue_drop (rx_fifo, size_20KB);
619 svm_fifo_dequeue_drop (rx_fifo, size_32KB);
622 for (i = 0; i < 20; ++i)
623 svm_fifo_dequeue_drop (rx_fifo, size_32KB);
624 max_dequeue = svm_fifo_max_dequeue (rx_fifo);
625 SEG_MGR_TEST ((max_dequeue == (size_32KB * 35)), "max_dequeue %u",
627 rv = fifo_segment_get_mem_status (fs);
628 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_LOW_PRESSURE),
629 "fifo_segment_get_mem_status %s", states_str[rv]);
632 for (i = 0; i < 10; ++i)
633 svm_fifo_dequeue_drop (rx_fifo, size_32KB);
634 max_dequeue = svm_fifo_max_dequeue (rx_fifo);
635 SEG_MGR_TEST ((max_dequeue == (size_32KB * 25)), "max_dequeue %u",
637 rv = fifo_segment_get_mem_status (fs);
638 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_NO_PRESSURE),
639 "fifo_segment_get_mem_status %s", states_str[rv]);
642 for (i = 0; i < 30; ++i)
643 svm_fifo_enqueue (rx_fifo, size_32KB, data);
644 max_dequeue = svm_fifo_max_dequeue (rx_fifo);
645 SEG_MGR_TEST ((max_dequeue == (size_32KB * 55)), "max_dequeue %u",
647 rv = fifo_segment_get_mem_status (fs);
648 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_HIGH_PRESSURE),
649 "fifo_segment_get_mem_status %s", states_str[rv]);
652 for (i = 0; i < 20; ++i)
653 svm_fifo_dequeue_drop (rx_fifo, size_32KB);
654 max_dequeue = svm_fifo_max_dequeue (rx_fifo);
655 SEG_MGR_TEST ((max_dequeue == (size_32KB * 35)), "max_dequeue %u",
657 rv = fifo_segment_get_mem_status (fs);
658 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_LOW_PRESSURE),
659 "fifo_segment_get_mem_status %s", states_str[rv]);
662 for (i = 0; i < 35; ++i)
663 svm_fifo_dequeue_drop (rx_fifo, size_32KB);
664 max_dequeue = svm_fifo_max_dequeue (rx_fifo);
665 SEG_MGR_TEST ((max_dequeue == 0), "max_dequeue %u", max_dequeue);
666 rv = fifo_segment_get_mem_status (fs);
667 SEG_MGR_TEST ((rv == MEMORY_PRESSURE_NO_PRESSURE),
668 "fifo_segment_get_mem_status %s", states_str[rv]);
670 /* (virtual) fifo size is still large as it is not updated */
671 SEG_MGR_TEST ((rx_fifo->shr->size == most_grown), "rx_fifo->size %u",
674 vnet_app_detach_args_t detach_args = {
675 .app_index = attach_args.app_index,
676 .api_client_index = ~0,
678 rv = vnet_application_detach (&detach_args);
679 SEG_MGR_TEST ((rv == 0), "vnet_application_detach %d", rv);
685 segment_manager_test_prealloc_hdrs (vlib_main_t * vm,
686 unformat_input_t * input)
688 u32 fifo_size = size_4KB, prealloc_hdrs, sm_index, fs_index;
689 u64 options[APP_OPTIONS_N_OPTIONS];
690 uword app_seg_size = size_2MB * 2;
691 segment_manager_t *sm;
695 memset (&options, 0, sizeof (options));
697 vnet_app_attach_args_t attach_args = {
698 .api_client_index = ~0,
701 .session_cb_vft = &placeholder_session_cbs,
702 .name = format (0, "segment_manager_test_prealloc_hdrs"),
707 attach_args.options[APP_OPTIONS_SEGMENT_SIZE] = app_seg_size;
708 attach_args.options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
709 attach_args.options[APP_OPTIONS_RX_FIFO_SIZE] = fifo_size;
710 attach_args.options[APP_OPTIONS_TX_FIFO_SIZE] = fifo_size;
711 attach_args.options[APP_OPTIONS_PREALLOC_FIFO_HDRS] = prealloc_hdrs;
713 rv = vnet_application_attach (&attach_args);
714 vec_free (attach_args.name);
716 SEG_MGR_TEST ((rv == 0), "vnet_application_attach %d", rv);
718 segment_manager_parse_segment_handle (attach_args.segment_handle, &sm_index,
720 sm = segment_manager_get (sm_index);
722 SEG_MGR_TEST ((sm != 0), "seg manager is valid", sm);
724 fs = segment_manager_get_segment (sm, fs_index);
725 SEG_MGR_TEST (fifo_segment_num_free_fifos (fs) == prealloc_hdrs,
726 "prealloc should be %u", prealloc_hdrs);
728 vnet_app_detach_args_t detach_args = {
729 .app_index = attach_args.app_index,
730 .api_client_index = ~0,
732 rv = vnet_application_detach (&detach_args);
733 SEG_MGR_TEST ((rv == 0), "vnet_application_detach %d", rv);
737 static clib_error_t *
738 segment_manager_test (vlib_main_t * vm,
739 unformat_input_t * input, vlib_cli_command_t * cmd_arg)
743 vnet_session_enable_disable (vm, 1);
745 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
747 if (unformat (input, "pressure_levels_1"))
748 res = segment_manager_test_pressure_1 (vm, input);
749 else if (unformat (input, "pressure_levels_2"))
750 res = segment_manager_test_pressure_2 (vm, input);
751 else if (unformat (input, "alloc"))
752 res = segment_manager_test_fifo_balanced_alloc (vm, input);
753 else if (unformat (input, "prealloc_hdrs"))
754 res = segment_manager_test_prealloc_hdrs (vm, input);
756 else if (unformat (input, "all"))
758 if ((res = segment_manager_test_pressure_1 (vm, input)))
760 if ((res = segment_manager_test_pressure_2 (vm, input)))
762 if ((res = segment_manager_test_fifo_balanced_alloc (vm, input)))
764 if ((res = segment_manager_test_prealloc_hdrs (vm, input)))
773 return clib_error_return (0, "Segment manager unit test failed.");
777 VLIB_CLI_COMMAND (tcp_test_command, static) =
779 .path = "test segment-manager",
780 .short_help = "test segment manager [pressure_levels_1]"
781 "[pressure_level_2][alloc][fifo_ops][prealloc_hdrs][all]",
782 .function = segment_manager_test,
786 * fd.io coding-style-patch-verification: ON
789 * eval: (c-set-style "gnu")