eal/freebsd: support option --base-virtaddr

According to our docs, only Linuxapp supports base-virtaddr option.
That is, strictly speaking, not true because most of the things
that are attempting to respect base-virtaddr are in common files,
so FreeBSD already *mostly* supports this option in practice.

This commit fixes the remaining bits to explicitly support
base-virtaddr option, and moves the arg parsing from EAL to common
options parsing code. Documentation is also updated to reflect
that all platforms now support base-virtaddr.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>
This commit is contained in:
Anatoly Burakov 2019-10-24 16:17:56 +01:00 committed by David Marchand
parent c345c7d1ac
commit 8f29a60764
6 changed files with 71 additions and 56 deletions

View File

@ -86,6 +86,12 @@ Multiprocessing-related options
Set the type of the current process. Set the type of the current process.
* ``--base-virtaddr <address>``
Attempt to use a different starting address for all memory maps of the
primary DPDK process. This can be helpful if secondary processes cannot
start due to conflicts in address map.
Memory-related options Memory-related options
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

View File

@ -49,12 +49,6 @@ Multiprocessing-related options
allows running multiple independent DPDK primary/secondary processes under allows running multiple independent DPDK primary/secondary processes under
different prefixes. different prefixes.
* ``--base-virtaddr <address>``
Attempt to use a different starting address for all memory maps of the
primary DPDK process. This can be helpful if secondary processes cannot
start due to conflicts in address map.
Memory-related options Memory-related options
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

View File

@ -56,6 +56,11 @@ New Features
Also, make sure to start the actual text at the margin. Also, make sure to start the actual text at the margin.
========================================================= =========================================================
* **FreeBSD now supports `--base-virtaddr` EAL option.**
FreeBSD version now also supports setting base virtual address for mapping
pages and resources into its address space.
* **Added Lock-free Stack for aarch64.** * **Added Lock-free Stack for aarch64.**
The lock-free stack implementation is enabled for aarch64 platforms. The lock-free stack implementation is enabled for aarch64 platforms.

View File

@ -20,6 +20,7 @@
#include <rte_eal.h> #include <rte_eal.h>
#include <rte_log.h> #include <rte_log.h>
#include <rte_lcore.h> #include <rte_lcore.h>
#include <rte_memory.h>
#include <rte_tailq.h> #include <rte_tailq.h>
#include <rte_version.h> #include <rte_version.h>
#include <rte_devargs.h> #include <rte_devargs.h>
@ -1095,6 +1096,36 @@ eal_parse_iova_mode(const char *name)
return 0; return 0;
} }
static int
eal_parse_base_virtaddr(const char *arg)
{
char *end;
uint64_t addr;
errno = 0;
addr = strtoull(arg, &end, 16);
/* check for errors */
if ((errno != 0) || (arg[0] == '\0') || end == NULL || (*end != '\0'))
return -1;
/* make sure we don't exceed 32-bit boundary on 32-bit target */
#ifndef RTE_ARCH_64
if (addr >= UINTPTR_MAX)
return -1;
#endif
/* align the addr on 16M boundary, 16MB is the minimum huge page
* size on IBM Power architecture. If the addr is aligned to 16MB,
* it can align to 2MB for x86. So this alignment can also be used
* on x86 and other architectures.
*/
internal_config.base_virtaddr =
RTE_PTR_ALIGN_CEIL((uintptr_t)addr, (size_t)RTE_PGSIZE_16M);
return 0;
}
/* caller is responsible for freeing the returned string */ /* caller is responsible for freeing the returned string */
static char * static char *
available_cores(void) available_cores(void)
@ -1408,6 +1439,13 @@ eal_parse_common_option(int opt, const char *optarg,
return -1; return -1;
} }
break; break;
case OPT_BASE_VIRTADDR_NUM:
if (eal_parse_base_virtaddr(optarg) < 0) {
RTE_LOG(ERR, EAL, "invalid parameter for --"
OPT_BASE_VIRTADDR "\n");
return -1;
}
break;
/* don't know what to do, leave this to caller */ /* don't know what to do, leave this to caller */
default: default:
@ -1648,6 +1686,7 @@ eal_common_usage(void)
" -h, --help This help\n" " -h, --help This help\n"
" --"OPT_IN_MEMORY" Operate entirely in memory. This will\n" " --"OPT_IN_MEMORY" Operate entirely in memory. This will\n"
" disable secondary process support\n" " disable secondary process support\n"
" --"OPT_BASE_VIRTADDR" Base virtual address\n"
"\nEAL options for DEBUG use only:\n" "\nEAL options for DEBUG use only:\n"
" --"OPT_HUGE_UNLINK" Unlink hugepage files after init\n" " --"OPT_HUGE_UNLINK" Unlink hugepage files after init\n"
" --"OPT_NO_HUGE" Use malloc instead of hugetlbfs\n" " --"OPT_NO_HUGE" Use malloc instead of hugetlbfs\n"

View File

@ -226,6 +226,14 @@ rte_eal_config_create(void)
if (internal_config.no_shconf) if (internal_config.no_shconf)
return 0; return 0;
/* map the config before base address so that we don't waste a page */
if (internal_config.base_virtaddr != 0)
rte_mem_cfg_addr = (void *)
RTE_ALIGN_FLOOR(internal_config.base_virtaddr -
sizeof(struct rte_mem_config), sysconf(_SC_PAGE_SIZE));
else
rte_mem_cfg_addr = NULL;
if (mem_cfg_fd < 0){ if (mem_cfg_fd < 0){
mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0600); mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0600);
if (mem_cfg_fd < 0) { if (mem_cfg_fd < 0) {
@ -253,8 +261,9 @@ rte_eal_config_create(void)
return -1; return -1;
} }
rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config), rte_mem_cfg_addr = mmap(rte_mem_cfg_addr,
PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0); sizeof(*rte_config.mem_config), PROT_READ | PROT_WRITE,
MAP_SHARED, mem_cfg_fd, 0);
if (rte_mem_cfg_addr == MAP_FAILED){ if (rte_mem_cfg_addr == MAP_FAILED){
RTE_LOG(ERR, EAL, "Cannot mmap memory for rte_config\n"); RTE_LOG(ERR, EAL, "Cannot mmap memory for rte_config\n");
@ -332,15 +341,17 @@ rte_eal_config_reattach(void)
close(mem_cfg_fd); close(mem_cfg_fd);
mem_cfg_fd = -1; mem_cfg_fd = -1;
if (mem_config == MAP_FAILED) { if (mem_config == MAP_FAILED || mem_config != rte_mem_cfg_addr) {
if (mem_config != MAP_FAILED) {
/* errno is stale, don't use */
RTE_LOG(ERR, EAL, "Cannot mmap memory for rte_config at [%p], got [%p]"
" - please use '--base-virtaddr' option\n",
rte_mem_cfg_addr, mem_config);
munmap(mem_config, sizeof(struct rte_mem_config));
return -1;
}
RTE_LOG(ERR, EAL, "Cannot mmap memory for rte_config! error %i (%s)\n", RTE_LOG(ERR, EAL, "Cannot mmap memory for rte_config! error %i (%s)\n",
errno, strerror(errno)); errno, strerror(errno));
return -1;
} else if (mem_config != rte_mem_cfg_addr) {
/* errno is stale, don't use */
RTE_LOG(ERR, EAL, "Cannot mmap memory for rte_config at [%p], got [%p]\n",
rte_mem_cfg_addr, mem_config);
munmap(mem_config, sizeof(struct rte_mem_config));
return -1; return -1;
} }

View File

@ -539,7 +539,6 @@ eal_usage(const char *prgname)
" --"OPT_SOCKET_LIMIT" Limit memory allocation on sockets (comma separated values)\n" " --"OPT_SOCKET_LIMIT" Limit memory allocation on sockets (comma separated values)\n"
" --"OPT_HUGE_DIR" Directory where hugetlbfs is mounted\n" " --"OPT_HUGE_DIR" Directory where hugetlbfs is mounted\n"
" --"OPT_FILE_PREFIX" Prefix for hugepage filenames\n" " --"OPT_FILE_PREFIX" Prefix for hugepage filenames\n"
" --"OPT_BASE_VIRTADDR" Base virtual address\n"
" --"OPT_CREATE_UIO_DEV" Create /dev/uioX (usually done by hotplug)\n" " --"OPT_CREATE_UIO_DEV" Create /dev/uioX (usually done by hotplug)\n"
" --"OPT_VFIO_INTR" Interrupt mode for VFIO (legacy|msi|msix)\n" " --"OPT_VFIO_INTR" Interrupt mode for VFIO (legacy|msi|msix)\n"
" --"OPT_LEGACY_MEM" Legacy memory mode (no dynamic allocation, contiguous segments)\n" " --"OPT_LEGACY_MEM" Legacy memory mode (no dynamic allocation, contiguous segments)\n"
@ -611,35 +610,6 @@ eal_parse_socket_arg(char *strval, volatile uint64_t *socket_arg)
return 0; return 0;
} }
static int
eal_parse_base_virtaddr(const char *arg)
{
char *end;
uint64_t addr;
errno = 0;
addr = strtoull(arg, &end, 16);
/* check for errors */
if ((errno != 0) || (arg[0] == '\0') || end == NULL || (*end != '\0'))
return -1;
/* make sure we don't exceed 32-bit boundary on 32-bit target */
#ifndef RTE_ARCH_64
if (addr >= UINTPTR_MAX)
return -1;
#endif
/* align the addr on 16M boundary, 16MB is the minimum huge page
* size on IBM Power architecture. If the addr is aligned to 16MB,
* it can align to 2MB for x86. So this alignment can also be used
* on x86 */
internal_config.base_virtaddr =
RTE_PTR_ALIGN_CEIL((uintptr_t)addr, (size_t)RTE_PGSIZE_16M);
return 0;
}
static int static int
eal_parse_vfio_intr(const char *mode) eal_parse_vfio_intr(const char *mode)
{ {
@ -798,16 +768,6 @@ eal_parse_args(int argc, char **argv)
internal_config.force_socket_limits = 1; internal_config.force_socket_limits = 1;
break; break;
case OPT_BASE_VIRTADDR_NUM:
if (eal_parse_base_virtaddr(optarg) < 0) {
RTE_LOG(ERR, EAL, "invalid parameter for --"
OPT_BASE_VIRTADDR "\n");
eal_usage(prgname);
ret = -1;
goto out;
}
break;
case OPT_VFIO_INTR_NUM: case OPT_VFIO_INTR_NUM:
if (eal_parse_vfio_intr(optarg) < 0) { if (eal_parse_vfio_intr(optarg) < 0) {
RTE_LOG(ERR, EAL, "invalid parameters for --" RTE_LOG(ERR, EAL, "invalid parameters for --"