From: Nathan Skrzypczak Date: Mon, 23 Nov 2020 15:25:21 +0000 (+0100) Subject: buffers: add page-size config X-Git-Tag: v21.06-rc0~130 X-Git-Url: https://gerrit.fd.io/r/gitweb?a=commitdiff_plain;h=61559029dacaac95b410fcb39e93134ee4858591;p=vpp.git 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 --- diff --git a/docs/gettingstarted/users/configuring/startup.rst b/docs/gettingstarted/users/configuring/startup.rst index 69d6ee5e3ea..e594b6a08a4 100644 --- a/docs/gettingstarted/users/configuring/startup.rst +++ b/docs/gettingstarted/users/configuring/startup.rst @@ -579,6 +579,7 @@ The buffers Section buffers { buffers-per-numa 128000 default data-size 2048 + page-size default-hugepage } buffers-per-numa number @@ -601,6 +602,19 @@ Size of buffer data area, default is 2048 default data-size 2048 +page-size number +^^^^^^^^^^^^^^^^ + +Set the page size for buffer allocation + +.. code-block:: console + + page-size 4K + page-size 2M + page-size 1G + page-size default + page-size default-hugepage + The dpdk Section ---------------- diff --git a/src/vlib/buffer.c b/src/vlib/buffer.c index 17e7d24cb27..a30fca32d8b 100644 --- a/src/vlib/buffer.c +++ b/src/vlib/buffer.c @@ -685,72 +685,90 @@ vlib_buffer_worker_init (vlib_main_t * vm) VLIB_WORKER_INIT_FUNCTION (vlib_buffer_worker_init); static clib_error_t * -vlib_buffer_main_init_numa_node (struct vlib_main_t *vm, u32 numa_node, - u8 * index) +vlib_buffer_main_init_numa_alloc (struct vlib_main_t *vm, u32 numa_node, + u32 * physmem_map_index, + clib_mem_page_sz_t log2_page_size, + u8 unpriv) { vlib_buffer_main_t *bm = vm->buffer_main; + u32 buffers_per_numa = bm->buffers_per_numa; clib_error_t *error; - u32 physmem_map_index; + u32 buffer_size; uword n_pages, pagesize; - u32 buffers_per_numa; - u32 buffer_size = vlib_buffer_alloc_size (bm->ext_hdr_size, - vlib_buffer_get_default_data_size - (vm)); - u8 *name; - - pagesize = clib_mem_get_default_hugepage_size (); - name = format (0, "buffers-numa-%d%c", numa_node, 0); + u8 *name = 0; - buffers_per_numa = bm->buffers_per_numa ? bm->buffers_per_numa : - VLIB_BUFFER_DEFAULT_BUFFERS_PER_NUMA; - -retry: + ASSERT (log2_page_size != CLIB_MEM_PAGE_SZ_UNKNOWN); + pagesize = clib_mem_page_bytes (log2_page_size); + buffer_size = vlib_buffer_alloc_size (bm->ext_hdr_size, + vlib_buffer_get_default_data_size + (vm)); if (buffer_size > pagesize) - { - error = - clib_error_return (0, - "buffer size (%llu) is greater than page size (%llu)", - buffer_size, pagesize); - goto done; - } + return clib_error_return (0, "buffer size (%llu) is greater than page " + "size (%llu)", buffer_size, pagesize); + if (buffers_per_numa == 0) + buffers_per_numa = unpriv ? VLIB_BUFFER_DEFAULT_BUFFERS_PER_NUMA_UNPRIV : + VLIB_BUFFER_DEFAULT_BUFFERS_PER_NUMA; + + name = format (0, "buffers-numa-%d%c", numa_node, 0); n_pages = (buffers_per_numa - 1) / (pagesize / buffer_size) + 1; error = vlib_physmem_shared_map_create (vm, (char *) name, n_pages * pagesize, min_log2 (pagesize), numa_node, - &physmem_map_index); + physmem_map_index); + vec_free (name); + return error; +} - if (error && pagesize != clib_mem_get_page_size ()) +static clib_error_t * +vlib_buffer_main_init_numa_node (struct vlib_main_t *vm, u32 numa_node, + u8 * index) +{ + vlib_buffer_main_t *bm = vm->buffer_main; + u32 physmem_map_index; + clib_error_t *error; + u8 *name = 0; + + if (bm->log2_page_size == CLIB_MEM_PAGE_SZ_UNKNOWN) { - vlib_log_warn (bm->log_default, "%U", format_clib_error, error); + error = vlib_buffer_main_init_numa_alloc (vm, numa_node, + &physmem_map_index, + CLIB_MEM_PAGE_SZ_DEFAULT_HUGE, + 0 /* unpriv */ ); + if (!error) + goto buffer_pool_create; + + /* If alloc failed, retry without hugepages */ + vlib_log_warn (bm->log_default, + "numa[%u] falling back to non-hugepage backed " + "buffer pool (%U)", numa_node, format_clib_error, error); clib_error_free (error); - vlib_log_warn (bm->log_default, "falling back to non-hugepage " - "backed buffer pool"); - pagesize = clib_mem_get_page_size (); - buffers_per_numa = bm->buffers_per_numa ? bm->buffers_per_numa : - VLIB_BUFFER_DEFAULT_BUFFERS_PER_NUMA_UNPRIV; - goto retry; - } + error = vlib_buffer_main_init_numa_alloc (vm, numa_node, + &physmem_map_index, + CLIB_MEM_PAGE_SZ_DEFAULT, + 1 /* unpriv */ ); + } + else + error = vlib_buffer_main_init_numa_alloc (vm, numa_node, + &physmem_map_index, + bm->log2_page_size, + 0 /* unpriv */ ); if (error) - goto done; + return error; - vec_reset_length (name); +buffer_pool_create: name = format (name, "default-numa-%d%c", numa_node, 0); - *index = vlib_buffer_pool_create (vm, (char *) name, vlib_buffer_get_default_data_size (vm), physmem_map_index); if (*index == (u8) ~ 0) - { - error = clib_error_return (0, "maximum number of buffer pools reached"); - goto done; - } - -done: + error = clib_error_return (0, "maximum number of buffer pools reached"); vec_free (name); + + return error; } @@ -935,11 +953,15 @@ vlib_buffers_configure (vlib_main_t * vm, unformat_input_t * input) vlib_buffer_main_alloc (vm); bm = vm->buffer_main; + bm->log2_page_size = CLIB_MEM_PAGE_SZ_UNKNOWN; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "buffers-per-numa %u", &bm->buffers_per_numa)) ; + else if (unformat (input, "page-size %U", unformat_log2_page_size, + &bm->log2_page_size)) + ; else if (unformat (input, "default data-size %u", &bm->default_data_size)) ; diff --git a/src/vlib/buffer.h b/src/vlib/buffer.h index d1a00bb3a45..297240d45f7 100644 --- a/src/vlib/buffer.h +++ b/src/vlib/buffer.h @@ -469,6 +469,7 @@ typedef struct u32 buffers_per_numa; u16 ext_hdr_size; u32 default_data_size; + clib_mem_page_sz_t log2_page_size; /* logging */ vlib_log_class_t log_default; diff --git a/src/vpp/conf/startup.conf b/src/vpp/conf/startup.conf index 864de11251f..270160217a0 100644 --- a/src/vpp/conf/startup.conf +++ b/src/vpp/conf/startup.conf @@ -99,6 +99,11 @@ cpu { ## Size of buffer data area ## Default is 2048 # default data-size 2048 + + ## Size of the memory pages allocated for buffer data + ## Default will try 'default-hugepage' then 'default' + ## you can also pass a size in K/M/G e.g. '8M' + # page-size default-hugepage # } # dpdk { diff --git a/src/vppinfra/std-formats.c b/src/vppinfra/std-formats.c index 1667c93fd88..1616001f9c5 100644 --- a/src/vppinfra/std-formats.c +++ b/src/vppinfra/std-formats.c @@ -299,40 +299,27 @@ format_log2_page_size (u8 * s, va_list * va) __clib_export uword unformat_log2_page_size (unformat_input_t * input, va_list * va) { - uword amount, shift, c; + uword amount; clib_mem_page_sz_t *result = va_arg (*va, clib_mem_page_sz_t *); - if (unformat (input, "default")) - return CLIB_MEM_PAGE_SZ_DEFAULT; - if (unformat (input, "default-hugepage")) - return CLIB_MEM_PAGE_SZ_DEFAULT_HUGE; - - if (!unformat (input, "%wd%_", &amount)) - return CLIB_MEM_PAGE_SZ_UNKNOWN; - - c = unformat_get_input (input); - switch (c) - { - case 'k': - case 'K': - shift = 10; - break; - case 'm': - case 'M': - shift = 20; - break; - case 'g': - case 'G': - shift = 30; - break; - default: - shift = 0; - unformat_put_input (input); - break; - } - - *result = min_log2 (amount) + shift; + *result = CLIB_MEM_PAGE_SZ_DEFAULT_HUGE; + else if (unformat (input, "default")) + *result = CLIB_MEM_PAGE_SZ_DEFAULT; + else if (unformat (input, "%wdk", &amount)) + *result = min_log2 (amount) + 10; + else if (unformat (input, "%wdK", &amount)) + *result = min_log2 (amount) + 10; + else if (unformat (input, "%wdm", &amount)) + *result = min_log2 (amount) + 20; + else if (unformat (input, "%wdM", &amount)) + *result = min_log2 (amount) + 20; + else if (unformat (input, "%wdg", &amount)) + *result = min_log2 (amount) + 30; + else if (unformat (input, "%wdG", &amount)) + *result = min_log2 (amount) + 30; + else + return 0; return 1; }