summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2020-06-11 08:57:52 -0400
committerDamjan Marion <dmarion@me.com>2020-06-12 12:06:29 +0000
commit01a2a10715551ccbad760cec641786aa079c373a (patch)
treebd9180e1456d2f0110ab6751a458ec4c4f7cd8b2
parent4cb21c8e5d70d20df94f5d892471a11488547881 (diff)
ip: allocate ip4 mtrie pages in htlb memory
No change in default behavior. To use htlb pages for the ip4 mtrie, use the "ip" command-line option "mtrie-hugetlb". Type: improvement Signed-off-by: Dave Barach <dave@barachs.net> Change-Id: I5497e426a47200edff2c7e15563ed6a42af12e7f
-rw-r--r--src/vnet/ip/ip4.h3
-rw-r--r--src/vnet/ip/ip4_forward.c3
-rw-r--r--src/vnet/ip/ip4_mtrie.c44
3 files changed, 48 insertions, 2 deletions
diff --git a/src/vnet/ip/ip4.h b/src/vnet/ip/ip4.h
index b5bc2e2c33f..f5ed9385232 100644
--- a/src/vnet/ip/ip4.h
+++ b/src/vnet/ip/ip4.h
@@ -167,6 +167,9 @@ typedef struct ip4_main_t
/** Heapsize for the Mtries */
uword mtrie_heap_size;
+ /** Use hugetlb pages for the Mtries */
+ int mtrie_hugetlb;
+
/** The memory heap for the mtries */
void *mtrie_mheap;
diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c
index 0fa9da22c93..595a0a1913c 100644
--- a/src/vnet/ip/ip4_forward.c
+++ b/src/vnet/ip/ip4_forward.c
@@ -3097,10 +3097,13 @@ ip4_config (vlib_main_t * vm, unformat_input_t * input)
{
if (unformat (input, "heap-size %U", unformat_memory_size, &heapsize))
;
+ else if (unformat (input, "mtrie-hugetlb %=", &im->mtrie_hugetlb, 1))
+ ;
else
return clib_error_return (0,
"invalid heap-size parameter `%U'",
format_unformat_error, input);
+
}
im->mtrie_heap_size = heapsize;
diff --git a/src/vnet/ip/ip4_mtrie.c b/src/vnet/ip/ip4_mtrie.c
index 258a0f76bdc..b5d0a890a7c 100644
--- a/src/vnet/ip/ip4_mtrie.c
+++ b/src/vnet/ip/ip4_mtrie.c
@@ -790,6 +790,9 @@ format_ip4_fib_mtrie (u8 * s, va_list * va)
/** Default heap size for the IPv4 mtries */
#define IP4_FIB_DEFAULT_MTRIE_HEAP_SIZE (32<<20)
+#ifndef MAP_HUGE_SHIFT
+#define MAP_HUGE_SHIFT 26
+#endif
static clib_error_t *
ip4_mtrie_module_init (vlib_main_t * vm)
@@ -799,9 +802,46 @@ ip4_mtrie_module_init (vlib_main_t * vm)
clib_error_t *error = NULL;
uword *old_heap;
- if (0 == im->mtrie_heap_size)
+ if (im->mtrie_heap_size == 0)
im->mtrie_heap_size = IP4_FIB_DEFAULT_MTRIE_HEAP_SIZE;
- im->mtrie_mheap = create_mspace (im->mtrie_heap_size, 1 /* locked */ );
+
+again:
+ if (im->mtrie_hugetlb)
+ {
+ void *rv;
+ int mmap_flags, mmap_flags_huge;
+ uword htlb_pagesize = clib_mem_get_default_hugepage_size ();
+ if (htlb_pagesize == 0)
+ {
+ clib_warning ("WARNING: htlb pagesize == 0");
+ im->mtrie_hugetlb = 0;
+ goto again;
+ }
+ /* Round the allocation request to an even number of huge pages */
+ im->mtrie_heap_size = (im->mtrie_heap_size + (htlb_pagesize - 1)) &
+ ~(htlb_pagesize - 1);
+ mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS;
+ mmap_flags_huge = (mmap_flags | MAP_HUGETLB | MAP_LOCKED |
+ min_log2 (htlb_pagesize) << MAP_HUGE_SHIFT);
+ rv = mmap (0, im->mtrie_heap_size,
+ PROT_READ | PROT_WRITE, mmap_flags_huge, -1, 0);
+ if (rv == MAP_FAILED)
+ {
+ /* Failure when running as root should be logged... */
+ if (geteuid () == 0)
+ clib_warning ("ip4 mtrie htlb map failed: not enough pages?");
+ im->mtrie_hugetlb = 0;
+ goto again;
+ }
+ if (mlock (rv, im->mtrie_heap_size))
+ clib_warning ("WARNING: couldn't lock mtrie heap at %llx", rv);
+ im->mtrie_mheap = create_mspace_with_base (rv, im->mtrie_heap_size,
+ 1 /* locked */ );
+ }
+ else
+ {
+ im->mtrie_mheap = create_mspace (im->mtrie_heap_size, 1 /* locked */ );
+ }
/* Burn one ply so index 0 is taken */
old_heap = clib_mem_set_heap (ip4_main.mtrie_mheap);