Skip to content

Commit 6155902

Browse files
committed
buffers: add page-size config
Type: feature Add a `buffers {page-size}` parameter to specify page size for buffers. This also fixes an issue with the parsing in unformat_log2_page_size. Change-Id: I7d7b1fa0bb7febaa7509cf2c625882f07eeafaad Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
1 parent f06b3bd commit 6155902

File tree

5 files changed

+101
-72
lines changed

5 files changed

+101
-72
lines changed

docs/gettingstarted/users/configuring/startup.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,7 @@ The buffers Section
579579
buffers {
580580
buffers-per-numa 128000
581581
default data-size 2048
582+
page-size default-hugepage
582583
}
583584
584585
buffers-per-numa number
@@ -601,6 +602,19 @@ Size of buffer data area, default is 2048
601602
602603
default data-size 2048
603604
605+
page-size number
606+
^^^^^^^^^^^^^^^^
607+
608+
Set the page size for buffer allocation
609+
610+
.. code-block:: console
611+
612+
page-size 4K
613+
page-size 2M
614+
page-size 1G
615+
page-size default
616+
page-size default-hugepage
617+
604618
605619
The dpdk Section
606620
----------------

src/vlib/buffer.c

Lines changed: 63 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -685,72 +685,90 @@ vlib_buffer_worker_init (vlib_main_t * vm)
685685
VLIB_WORKER_INIT_FUNCTION (vlib_buffer_worker_init);
686686

687687
static clib_error_t *
688-
vlib_buffer_main_init_numa_node (struct vlib_main_t *vm, u32 numa_node,
689-
u8 * index)
688+
vlib_buffer_main_init_numa_alloc (struct vlib_main_t *vm, u32 numa_node,
689+
u32 * physmem_map_index,
690+
clib_mem_page_sz_t log2_page_size,
691+
u8 unpriv)
690692
{
691693
vlib_buffer_main_t *bm = vm->buffer_main;
694+
u32 buffers_per_numa = bm->buffers_per_numa;
692695
clib_error_t *error;
693-
u32 physmem_map_index;
696+
u32 buffer_size;
694697
uword n_pages, pagesize;
695-
u32 buffers_per_numa;
696-
u32 buffer_size = vlib_buffer_alloc_size (bm->ext_hdr_size,
697-
vlib_buffer_get_default_data_size
698-
(vm));
699-
u8 *name;
700-
701-
pagesize = clib_mem_get_default_hugepage_size ();
702-
name = format (0, "buffers-numa-%d%c", numa_node, 0);
698+
u8 *name = 0;
703699

704-
buffers_per_numa = bm->buffers_per_numa ? bm->buffers_per_numa :
705-
VLIB_BUFFER_DEFAULT_BUFFERS_PER_NUMA;
706-
707-
retry:
700+
ASSERT (log2_page_size != CLIB_MEM_PAGE_SZ_UNKNOWN);
708701

702+
pagesize = clib_mem_page_bytes (log2_page_size);
703+
buffer_size = vlib_buffer_alloc_size (bm->ext_hdr_size,
704+
vlib_buffer_get_default_data_size
705+
(vm));
709706
if (buffer_size > pagesize)
710-
{
711-
error =
712-
clib_error_return (0,
713-
"buffer size (%llu) is greater than page size (%llu)",
714-
buffer_size, pagesize);
715-
goto done;
716-
}
707+
return clib_error_return (0, "buffer size (%llu) is greater than page "
708+
"size (%llu)", buffer_size, pagesize);
717709

710+
if (buffers_per_numa == 0)
711+
buffers_per_numa = unpriv ? VLIB_BUFFER_DEFAULT_BUFFERS_PER_NUMA_UNPRIV :
712+
VLIB_BUFFER_DEFAULT_BUFFERS_PER_NUMA;
713+
714+
name = format (0, "buffers-numa-%d%c", numa_node, 0);
718715
n_pages = (buffers_per_numa - 1) / (pagesize / buffer_size) + 1;
719716
error = vlib_physmem_shared_map_create (vm, (char *) name,
720717
n_pages * pagesize,
721718
min_log2 (pagesize), numa_node,
722-
&physmem_map_index);
719+
physmem_map_index);
720+
vec_free (name);
721+
return error;
722+
}
723723

724-
if (error && pagesize != clib_mem_get_page_size ())
724+
static clib_error_t *
725+
vlib_buffer_main_init_numa_node (struct vlib_main_t *vm, u32 numa_node,
726+
u8 * index)
727+
{
728+
vlib_buffer_main_t *bm = vm->buffer_main;
729+
u32 physmem_map_index;
730+
clib_error_t *error;
731+
u8 *name = 0;
732+
733+
if (bm->log2_page_size == CLIB_MEM_PAGE_SZ_UNKNOWN)
725734
{
726-
vlib_log_warn (bm->log_default, "%U", format_clib_error, error);
735+
error = vlib_buffer_main_init_numa_alloc (vm, numa_node,
736+
&physmem_map_index,
737+
CLIB_MEM_PAGE_SZ_DEFAULT_HUGE,
738+
0 /* unpriv */ );
739+
if (!error)
740+
goto buffer_pool_create;
741+
742+
/* If alloc failed, retry without hugepages */
743+
vlib_log_warn (bm->log_default,
744+
"numa[%u] falling back to non-hugepage backed "
745+
"buffer pool (%U)", numa_node, format_clib_error, error);
727746
clib_error_free (error);
728-
vlib_log_warn (bm->log_default, "falling back to non-hugepage "
729-
"backed buffer pool");
730-
pagesize = clib_mem_get_page_size ();
731-
buffers_per_numa = bm->buffers_per_numa ? bm->buffers_per_numa :
732-
VLIB_BUFFER_DEFAULT_BUFFERS_PER_NUMA_UNPRIV;
733-
goto retry;
734-
}
735747

748+
error = vlib_buffer_main_init_numa_alloc (vm, numa_node,
749+
&physmem_map_index,
750+
CLIB_MEM_PAGE_SZ_DEFAULT,
751+
1 /* unpriv */ );
752+
}
753+
else
754+
error = vlib_buffer_main_init_numa_alloc (vm, numa_node,
755+
&physmem_map_index,
756+
bm->log2_page_size,
757+
0 /* unpriv */ );
736758
if (error)
737-
goto done;
759+
return error;
738760

739-
vec_reset_length (name);
761+
buffer_pool_create:
740762
name = format (name, "default-numa-%d%c", numa_node, 0);
741-
742763
*index = vlib_buffer_pool_create (vm, (char *) name,
743764
vlib_buffer_get_default_data_size (vm),
744765
physmem_map_index);
745766

746767
if (*index == (u8) ~ 0)
747-
{
748-
error = clib_error_return (0, "maximum number of buffer pools reached");
749-
goto done;
750-
}
751-
752-
done:
768+
error = clib_error_return (0, "maximum number of buffer pools reached");
753769
vec_free (name);
770+
771+
754772
return error;
755773
}
756774

@@ -935,11 +953,15 @@ vlib_buffers_configure (vlib_main_t * vm, unformat_input_t * input)
935953
vlib_buffer_main_alloc (vm);
936954

937955
bm = vm->buffer_main;
956+
bm->log2_page_size = CLIB_MEM_PAGE_SZ_UNKNOWN;
938957

939958
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
940959
{
941960
if (unformat (input, "buffers-per-numa %u", &bm->buffers_per_numa))
942961
;
962+
else if (unformat (input, "page-size %U", unformat_log2_page_size,
963+
&bm->log2_page_size))
964+
;
943965
else if (unformat (input, "default data-size %u",
944966
&bm->default_data_size))
945967
;

src/vlib/buffer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ typedef struct
469469
u32 buffers_per_numa;
470470
u16 ext_hdr_size;
471471
u32 default_data_size;
472+
clib_mem_page_sz_t log2_page_size;
472473

473474
/* logging */
474475
vlib_log_class_t log_default;

src/vpp/conf/startup.conf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ cpu {
9999
## Size of buffer data area
100100
## Default is 2048
101101
# default data-size 2048
102+
103+
## Size of the memory pages allocated for buffer data
104+
## Default will try 'default-hugepage' then 'default'
105+
## you can also pass a size in K/M/G e.g. '8M'
106+
# page-size default-hugepage
102107
# }
103108

104109
# dpdk {

src/vppinfra/std-formats.c

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -299,40 +299,27 @@ format_log2_page_size (u8 * s, va_list * va)
299299
__clib_export uword
300300
unformat_log2_page_size (unformat_input_t * input, va_list * va)
301301
{
302-
uword amount, shift, c;
302+
uword amount;
303303
clib_mem_page_sz_t *result = va_arg (*va, clib_mem_page_sz_t *);
304304

305-
if (unformat (input, "default"))
306-
return CLIB_MEM_PAGE_SZ_DEFAULT;
307-
308305
if (unformat (input, "default-hugepage"))
309-
return CLIB_MEM_PAGE_SZ_DEFAULT_HUGE;
310-
311-
if (!unformat (input, "%wd%_", &amount))
312-
return CLIB_MEM_PAGE_SZ_UNKNOWN;
313-
314-
c = unformat_get_input (input);
315-
switch (c)
316-
{
317-
case 'k':
318-
case 'K':
319-
shift = 10;
320-
break;
321-
case 'm':
322-
case 'M':
323-
shift = 20;
324-
break;
325-
case 'g':
326-
case 'G':
327-
shift = 30;
328-
break;
329-
default:
330-
shift = 0;
331-
unformat_put_input (input);
332-
break;
333-
}
334-
335-
*result = min_log2 (amount) + shift;
306+
*result = CLIB_MEM_PAGE_SZ_DEFAULT_HUGE;
307+
else if (unformat (input, "default"))
308+
*result = CLIB_MEM_PAGE_SZ_DEFAULT;
309+
else if (unformat (input, "%wdk", &amount))
310+
*result = min_log2 (amount) + 10;
311+
else if (unformat (input, "%wdK", &amount))
312+
*result = min_log2 (amount) + 10;
313+
else if (unformat (input, "%wdm", &amount))
314+
*result = min_log2 (amount) + 20;
315+
else if (unformat (input, "%wdM", &amount))
316+
*result = min_log2 (amount) + 20;
317+
else if (unformat (input, "%wdg", &amount))
318+
*result = min_log2 (amount) + 30;
319+
else if (unformat (input, "%wdG", &amount))
320+
*result = min_log2 (amount) + 30;
321+
else
322+
return 0;
336323
return 1;
337324
}
338325

0 commit comments

Comments
 (0)