From df03c02a845e50f8fb92f7bfaa32f0d05888470d Mon Sep 17 00:00:00 2001 From: Jaroslava Fiedlerova <Jaroslava.Fiedlerova@openairinterface.org> Date: Thu, 2 Jan 2025 15:42:52 +0100 Subject: [PATCH] fhi_72: allow to provide dpdk_iova_mode to xran In DPDK, IO Virtual Addresses (IOVA) refers to the memory addressing scheme used for IO operations. The two IOVA modes supported by DPDK are: - IOVA as Physical Address (PA): IO memory addresses correspond directly to physical addresses, no address translation required. - IOVA as Virtual Address (VA): IO memory addresses align with user-space virtual addresses, requiring IOMMU to remap physical memory. Previously, this was hardcoded to 0, to use IOVA as PA mode, with xRAN's DPDK EAL initialization using the "--iova-mode=pa" flag. This commit introduces a gNB configuration option to allow users to select the desired IOVA mode. The default remains PA mode to ensure backward compatibility. Using IOVA VA mode allows DPDK to run without requiring SYS_ADMIN capability in the docker container. --- doc/ORAN_FHI7.2_Tutorial.md | 11 +++++++++++ doc/tuning_and_security.md | 3 +++ radio/fhi_72/oran-config.c | 8 +++++++- radio/fhi_72/oran-params.h | 21 +++++++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/doc/ORAN_FHI7.2_Tutorial.md b/doc/ORAN_FHI7.2_Tutorial.md index 199f910b1ce..84ae6b20644 100644 --- a/doc/ORAN_FHI7.2_Tutorial.md +++ b/doc/ORAN_FHI7.2_Tutorial.md @@ -917,6 +917,17 @@ Edit the sample OAI gNB configuration file and check following parameters: cannot preallocate memory on NUMA nodes other than 0; in this case, set this to 0 (no pre-allocation) and so that DPDK will allocate it on-demand on the right NUMA node. + * `dpdk_iova_mode`: Specifies DPDK IO Virtual Address (IOVA) mode: + * `PA`: IOVA as Physical Address (PA) mode, where DPDK IOVA memory layout + corresponds directly to the physical memory layout. + * `VA`: IOVA as Virtual Address (VA) mode, where DPDK IOVA addresses do not + follow the physical memory layout. Uses IOMMU to remap physical memory. + Requires kernel support and IOMMU for address translation. + * If not specified, default value of "PA" is used (for backwards compabilibity; + it was hardcoded to PA in the past). However, we recommend using "VA" mode + as it offers several benefits. For a detailed explanation of DPDK IOVA, + including the advantages and disadvantages of each mode, refer to + [Memory in DPDK](https://www.dpdk.org/memory-in-dpdk-part-2-deep-dive-into-iova/) * `owdm_enable`: used for eCPRI One-Way Delay Measurements; it depends if the RU supports it; if not set to 1 (enabled), default value is 0 (disabled) * `fh_config`: parameters that need to match RU parameters * timing parameters (starting with `T`) depend on the RU: `Tadv_cp_dl` is a diff --git a/doc/tuning_and_security.md b/doc/tuning_and_security.md index 94b6ceb07c7..7e415e783da 100644 --- a/doc/tuning_and_security.md +++ b/doc/tuning_and_security.md @@ -146,6 +146,9 @@ on DPDK: - `IPC_LOCK` (becomes mandatory with DPDK) - `SYS_RESOURCE` - `NET_RAW` +- `SYS_ADMIN`: This is required by DPDK when using IOVA PA (Physical Address) + mode to read `/proc/self/pagemaps`. However, if DPDK EAL is configured to use + IOVA VA (Virtual Address) mode, this capability is no longer required. ## Capabilities with UHD diff --git a/radio/fhi_72/oran-config.c b/radio/fhi_72/oran-config.c index ea6d158f867..34da6f58908 100644 --- a/radio/fhi_72/oran-config.c +++ b/radio/fhi_72/oran-config.c @@ -472,7 +472,9 @@ static bool set_fh_io_cfg(struct xran_io_cfg *io_cfg, const paramdef_t *fhip, in } io_cfg->bbdev_dev[0] = NULL; // BBDev dev name; max devices = 1 io_cfg->bbdev_mode = XRAN_BBDEV_NOT_USED; // DPDK for BBDev - io_cfg->dpdkIoVaMode = 0; // IOVA mode + int dpdk_iova_mode_idx = config_paramidx_fromname((paramdef_t *)fhip, nump, ORAN_CONFIG_DPDK_IOVA_MODE); + AssertFatal(dpdk_iova_mode_idx >= 0,"Index for dpdk_iova_mode config option not found!"); + io_cfg->dpdkIoVaMode = config_get_processedint(config_get_if(), (paramdef_t *)&fhip[dpdk_iova_mode_idx]); // IOVA mode io_cfg->dpdkMemorySize = *gpd(fhip, nump, ORAN_CONFIG_DPDK_MEM_SIZE)->uptr; // DPDK max memory allocation /* the following core assignment is needed for rte_eal_init() function within xran library; @@ -586,7 +588,11 @@ static bool set_fh_init(struct xran_fh_init *fh_init, enum xran_category xran_ca } paramdef_t fhip[] = ORAN_GLOBALPARAMS_DESC; + checkedparam_t fhip_CheckParams[] = ORAN_GLOBALPARAMS_CHECK_DESC; + static_assert(sizeofArray(fhip) == sizeofArray(fhip_CheckParams), + "fhip and fhip_CheckParams should have the same size"); int nump = sizeofArray(fhip); + config_set_checkfunctions(fhip, fhip_CheckParams, nump); int ret = config_get(config_get_if(), fhip, nump, CONFIG_STRING_ORAN); if (ret <= 0) { printf("problem reading section \"%s\"\n", CONFIG_STRING_ORAN); diff --git a/radio/fhi_72/oran-params.h b/radio/fhi_72/oran-params.h index d7eaf47a3ba..20c3d71634b 100644 --- a/radio/fhi_72/oran-params.h +++ b/radio/fhi_72/oran-params.h @@ -37,6 +37,7 @@ #define ORAN_CONFIG_NETHPERPORT "eth_lines" #define ORAN_CONFIG_NETHSPEED "eth_speed" #define ORAN_CONFIG_DPDK_MEM_SIZE "dpdk_mem_size" +#define ORAN_CONFIG_DPDK_IOVA_MODE "dpdk_iova_mode" #define ORAN_CONFIG_ECPRI_OWDM "owdm_enable" // clang-format off @@ -53,8 +54,28 @@ {ORAN_CONFIG_NETHPERPORT, "number of links per port\n", 0, .uptr=NULL, .defuintval=1, TYPE_UINT, 0}, \ {ORAN_CONFIG_NETHSPEED, "ethernet speed link\n", 0, .uptr=NULL, .defuintval=10, TYPE_UINT, 0}, \ {ORAN_CONFIG_DPDK_MEM_SIZE, "DPDK huge page pre-allocation in MiB\n", 0, .uptr=NULL, .defuintval=8192, TYPE_UINT, 0}, \ + {ORAN_CONFIG_DPDK_IOVA_MODE, "DPDK IOVA mode\n", 0, .strptr=NULL, .defstrval="PA", TYPE_STRING, 0}, \ {ORAN_CONFIG_ECPRI_OWDM, "eCPRI One-Way Delay Measurements\n", PARAMFLAG_BOOL, .uptr=NULL, .defuintval=0, TYPE_UINT, 0}, \ } + +// clang-format off +#define ORAN_GLOBALPARAMS_CHECK_DESC { \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s3a = { config_checkstr_assign_integer, \ + {"PA", "VA"}, {0, 1}, 2} }, \ + { .s5 = { NULL } }, \ +} + + // clang-format on #define CONFIG_STRING_ORAN_FH "fh_config" -- GitLab