Currently, VA space allocation is regulated by two constants picked up from
config - max memseg per list, and max memory per list. In preparation for
these limits being dynamic, add a per-page-size limit value in config,
populate that value from these defaults at init time, and adjust the code
to only refer to the mem limits from internal config.

Signed-off-by: Anatoly Burakov <[email protected]>
---
 lib/eal/common/eal_common_dynmem.c  | 22 ++++++++--------------
 lib/eal/common/eal_common_options.c | 20 ++++++++++++++++++++
 lib/eal/common/eal_internal_cfg.h   |  2 ++
 lib/eal/common/eal_options.h        |  1 +
 lib/eal/freebsd/eal.c               |  6 ++++++
 lib/eal/linux/eal.c                 |  6 ++++++
 lib/eal/linux/eal_memory.c          |  3 +++
 lib/eal/windows/eal.c               |  6 ++++++
 8 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/lib/eal/common/eal_common_dynmem.c 
b/lib/eal/common/eal_common_dynmem.c
index c163bf4967..c33fbdea6d 100644
--- a/lib/eal/common/eal_common_dynmem.c
+++ b/lib/eal/common/eal_common_dynmem.c
@@ -24,13 +24,13 @@ eal_dynmem_memseg_lists_init(void)
        struct memtype {
                uint64_t page_sz;
                int socket_id;
+               unsigned int hpi_idx;
                unsigned int n_segs;
                size_t mem_sz;
                size_t va_offset;
        } memtypes[RTE_MAX_MEMSEG_LISTS] = {0};
        int i, hpi_idx, msl_idx, ret = -1; /* fail unless told to succeed */
        struct rte_memseg_list *msl;
-       uint64_t max_mem_per_type;
        size_t mem_va_len, mem_va_page_sz;
        unsigned int n_memtypes, cur_type;
        void *mem_va_addr = NULL;
@@ -51,15 +51,9 @@ eal_dynmem_memseg_lists_init(void)
         * balancing act between maximum segments per type, maximum memory per
         * type, and number of detected NUMA nodes.
         *
-        * the total amount of memory per type is limited by
-        * RTE_MAX_MEM_MB_PER_TYPE. additionally, maximum number of segments per
-        * type is also limited by RTE_MAX_MEMSEG_PER_TYPE. this is because for
-        * smaller page sizes, it can take hundreds of thousands of segments to
-        * reach the above specified per-type memory limits.
-        *
-        * each memory type is allotted a single memseg list. the size of that
-        * list is calculated here to respect the per-type memory and segment
-        * limits that apply.
+        * the total amount of memory per type is limited by per-page-size
+        * memory values in internal config. each memory type is allotted one
+        * memseg list.
         */
 
        /* maximum number of memtypes we're ever going to get */
@@ -92,6 +86,7 @@ eal_dynmem_memseg_lists_init(void)
 #endif
                        memtypes[cur_type].page_sz = hugepage_sz;
                        memtypes[cur_type].socket_id = socket_id;
+                       memtypes[cur_type].hpi_idx = hpi_idx;
 
                        EAL_LOG(DEBUG, "Detected memory type: "
                                "socket_id:%u hugepage_sz:%" PRIu64,
@@ -101,8 +96,6 @@ eal_dynmem_memseg_lists_init(void)
        /* number of memtypes could have been lower due to no NUMA support */
        n_memtypes = cur_type;
 
-       /* set up limits for types */
-       max_mem_per_type = (uint64_t)RTE_MAX_MEM_MB_PER_TYPE << 20;
        mem_va_len = 0;
        mem_va_page_sz = 0;
 
@@ -110,9 +103,12 @@ eal_dynmem_memseg_lists_init(void)
        for (cur_type = 0; cur_type < n_memtypes; cur_type++) {
                unsigned int n_segs;
                struct memtype *type = &memtypes[cur_type];
+               uint64_t max_mem_per_type;
                uint64_t pagesz;
 
                pagesz = type->page_sz;
+               max_mem_per_type =
+                       internal_conf->hugepage_mem_sz_limits[type->hpi_idx];
 
                /*
                 * we need to create a segment list for this type. we must take
@@ -121,10 +117,8 @@ eal_dynmem_memseg_lists_init(void)
                 * 1. total amount of memory to use for this memory type
                 * 2. total amount of memory allowed per type
                 * 3. number of segments needed to fit the amount of memory
-                * 4. number of segments allowed per type
                 */
                n_segs = max_mem_per_type / pagesz;
-               n_segs = RTE_MIN(n_segs, (unsigned int)RTE_MAX_MEMSEG_PER_TYPE);
                type->n_segs = n_segs;
                type->mem_sz = (size_t)pagesz * type->n_segs;
                mem_va_page_sz = RTE_MAX(mem_va_page_sz, (size_t)pagesz);
diff --git a/lib/eal/common/eal_common_options.c 
b/lib/eal/common/eal_common_options.c
index aad676a004..bbc4427524 100644
--- a/lib/eal/common/eal_common_options.c
+++ b/lib/eal/common/eal_common_options.c
@@ -510,6 +510,7 @@ eal_reset_internal_config(struct internal_config 
*internal_cfg)
                memset(&internal_cfg->hugepage_info[i], 0,
                                sizeof(internal_cfg->hugepage_info[0]));
                internal_cfg->hugepage_info[i].lock_descriptor = -1;
+               internal_cfg->hugepage_mem_sz_limits[i] = 0;
        }
        internal_cfg->base_virtaddr = 0;
 
@@ -2359,6 +2360,25 @@ eal_adjust_config(struct internal_config *internal_cfg)
        return 0;
 }
 
+int
+eal_apply_hugepage_mem_sz_limits(struct internal_config *internal_cfg)
+{
+       unsigned int i;
+
+       for (i = 0; i < internal_cfg->num_hugepage_sizes; i++) {
+               const uint64_t pagesz = 
internal_cfg->hugepage_info[i].hugepage_sz;
+               uint64_t limit;
+
+               /* assign default limits */
+               limit = RTE_MIN((uint64_t)RTE_MAX_MEM_MB_PER_TYPE << 20,
+                               (uint64_t)RTE_MAX_MEMSEG_PER_TYPE * pagesz);
+
+               internal_cfg->hugepage_mem_sz_limits[i] = limit;
+       }
+
+       return 0;
+}
+
 RTE_EXPORT_SYMBOL(rte_vect_get_max_simd_bitwidth)
 uint16_t
 rte_vect_get_max_simd_bitwidth(void)
diff --git a/lib/eal/common/eal_internal_cfg.h 
b/lib/eal/common/eal_internal_cfg.h
index 95d327a613..0bf192c6e5 100644
--- a/lib/eal/common/eal_internal_cfg.h
+++ b/lib/eal/common/eal_internal_cfg.h
@@ -96,6 +96,8 @@ struct internal_config {
                        /**< user defined mbuf pool ops name */
        unsigned num_hugepage_sizes;      /**< how many sizes on this system */
        struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES];
+       uint64_t hugepage_mem_sz_limits[MAX_HUGEPAGE_SIZES];
+       /**< default max memory per hugepage size */
        enum rte_iova_mode iova_mode ;    /**< Set IOVA mode on this system  */
        rte_cpuset_t ctrl_cpuset;         /**< cpuset for ctrl threads */
        volatile unsigned int init_complete;
diff --git a/lib/eal/common/eal_options.h b/lib/eal/common/eal_options.h
index f5e7905609..82cc8be8db 100644
--- a/lib/eal/common/eal_options.h
+++ b/lib/eal/common/eal_options.h
@@ -12,6 +12,7 @@ struct rte_tel_data;
 int eal_parse_log_options(void);
 int eal_parse_args(void);
 int eal_option_device_parse(void);
+int eal_apply_hugepage_mem_sz_limits(struct internal_config *internal_cfg);
 int eal_adjust_config(struct internal_config *internal_cfg);
 int eal_cleanup_config(struct internal_config *internal_cfg);
 enum rte_proc_type_t eal_proc_type_detect(void);
diff --git a/lib/eal/freebsd/eal.c b/lib/eal/freebsd/eal.c
index 60f5e676a8..8b1ba5b99b 100644
--- a/lib/eal/freebsd/eal.c
+++ b/lib/eal/freebsd/eal.c
@@ -585,6 +585,12 @@ rte_eal_init(int argc, char **argv)
                        rte_errno = EACCES;
                        goto err_out;
                }
+               if (internal_conf->process_type == RTE_PROC_PRIMARY &&
+                               eal_apply_hugepage_mem_sz_limits(internal_conf) 
< 0) {
+                       rte_eal_init_alert("Cannot apply hugepage memory 
limits.");
+                       rte_errno = EINVAL;
+                       goto err_out;
+               }
        }
 
        if (internal_conf->memory == 0 && internal_conf->force_numa == 0) {
diff --git a/lib/eal/linux/eal.c b/lib/eal/linux/eal.c
index d848de03d8..fc2e9b8c0e 100644
--- a/lib/eal/linux/eal.c
+++ b/lib/eal/linux/eal.c
@@ -748,6 +748,12 @@ rte_eal_init(int argc, char **argv)
                        rte_errno = EACCES;
                        goto err_out;
                }
+               if (internal_conf->process_type == RTE_PROC_PRIMARY &&
+                               eal_apply_hugepage_mem_sz_limits(internal_conf) 
< 0) {
+                       rte_eal_init_alert("Cannot apply hugepage memory 
limits.");
+                       rte_errno = EINVAL;
+                       goto err_out;
+               }
        }
 
        if (internal_conf->memory == 0 && internal_conf->force_numa == 0) {
diff --git a/lib/eal/linux/eal_memory.c b/lib/eal/linux/eal_memory.c
index 55779badec..1ed4f69e3e 100644
--- a/lib/eal/linux/eal_memory.c
+++ b/lib/eal/linux/eal_memory.c
@@ -1813,6 +1813,7 @@ memseg_primary_init_32(void)
                for (hpi_idx = 0; hpi_idx < hp_sizes; hpi_idx++) {
                        uint64_t max_pagesz_mem, cur_pagesz_mem = 0;
                        uint64_t hugepage_sz;
+                       uint64_t pagesz_mem_limit;
                        struct hugepage_info *hpi;
 
                        hpi = &internal_conf->hugepage_info[hpi_idx];
@@ -1823,6 +1824,8 @@ memseg_primary_init_32(void)
                                continue;
 
                        max_pagesz_mem = max_socket_mem - cur_socket_mem;
+                       pagesz_mem_limit = 
internal_conf->hugepage_mem_sz_limits[hpi_idx];
+                       max_pagesz_mem = RTE_MIN(max_pagesz_mem, 
pagesz_mem_limit);
 
                        /* make it multiple of page size */
                        max_pagesz_mem = RTE_ALIGN_FLOOR(max_pagesz_mem,
diff --git a/lib/eal/windows/eal.c b/lib/eal/windows/eal.c
index f06375a624..6dacae7235 100644
--- a/lib/eal/windows/eal.c
+++ b/lib/eal/windows/eal.c
@@ -229,6 +229,12 @@ rte_eal_init(int argc, char **argv)
                rte_errno = EACCES;
                goto err_out;
        }
+       if (!internal_conf->no_hugetlbfs &&
+                       eal_apply_hugepage_mem_sz_limits(internal_conf) < 0) {
+               rte_eal_init_alert("Cannot apply hugepage memory limits");
+               rte_errno = EINVAL;
+               goto err_out;
+       }
 
        if (internal_conf->memory == 0 && !internal_conf->force_numa) {
                if (internal_conf->no_hugetlbfs)
-- 
2.47.3

Reply via email to