From 61559029dacaac95b410fcb39e93134ee4858591 Mon Sep 17 00:00:00 2001 From: Nathan Skrzypczak Date: Mon, 23 Nov 2020 16:25:21 +0100 Subject: 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 --- src/vlib/buffer.c | 104 +++++++++++++++++++++++++++++++++--------------------- src/vlib/buffer.h | 1 + 2 files changed, 64 insertions(+), 41 deletions(-) (limited to 'src/vlib') 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; -- cgit 1.2.3-korg