From 639557ce42a58c3bdd0eb250ffcac5b67bd567c5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 18 Oct 2023 14:44:14 +0200 Subject: [PATCH 01/27] docker,readme: fix docker compose command arg --- docker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/README.md b/docker/README.md index 48dc77105a..15742abf8b 100644 --- a/docker/README.md +++ b/docker/README.md @@ -45,7 +45,7 @@ where service is either `gnb` for the srsRAN Project gNB or `5gc` for Open5GS. For a more advanced parametrization of the Open5GS container, e.g. to load subscriber data from a csv-file the `open5gs.env` file in `srsgnb/docker/open5gs` can be used by running: ```bash -docker compose -f docker/docker-compose.yml --env_file open5gs/open5gs.env up +docker compose -f docker/docker-compose.yml --env-file open5gs/open5gs.env up ``` In [open5gs.env](open5gs/open5gs.env) the following parameters can be set: From b7877c25266d10d6805d553990c954be0432e736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alfredo=20S=C3=A1ez?= Date: Thu, 19 Oct 2023 07:12:01 +0000 Subject: [PATCH 02/27] docker,readme: fix docker compose command arg path --- docker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/README.md b/docker/README.md index 15742abf8b..8e72362dc8 100644 --- a/docker/README.md +++ b/docker/README.md @@ -45,7 +45,7 @@ where service is either `gnb` for the srsRAN Project gNB or `5gc` for Open5GS. For a more advanced parametrization of the Open5GS container, e.g. to load subscriber data from a csv-file the `open5gs.env` file in `srsgnb/docker/open5gs` can be used by running: ```bash -docker compose -f docker/docker-compose.yml --env-file open5gs/open5gs.env up +docker compose -f docker/docker-compose.yml --env-file docker/open5gs/open5gs.env up ``` In [open5gs.env](open5gs/open5gs.env) the following parameters can be set: From ae545a7b895c608dd8bae76220d24558acebb2b3 Mon Sep 17 00:00:00 2001 From: asaezper Date: Wed, 18 Oct 2023 12:01:26 +0200 Subject: [PATCH 03/27] ci: .github ci added to private branches --- .github/ISSUE_TEMPLATE.md | 24 +++++++++++ .github/codeql/codeql-config.yml | 2 + .github/workflows/ccpp.yml | 18 +++++++++ .github/workflows/codeql.yml | 69 ++++++++++++++++++++++++++++++++ 4 files changed, 113 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/codeql/codeql-config.yml create mode 100644 .github/workflows/ccpp.yml create mode 100644 .github/workflows/codeql.yml diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..6d66af1a2c --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,24 @@ + + +## Issue Description ## +[Describe the issue in detail] + +## Setup Details ## +[Specify details of the test setup. This would help us reproduce the problem reliably] +e.g. Network configuration, Operation System, Hardware, RF front-end, library and driver versions + +## Expected Behavior ## +[What you expect to happen] + +## Actual Behaviour ## +[What happens instead e.g. error message] + +## Steps to reproduce the problem ## +[Tell us how to reproduce this issue e.g. RF setup, application config files] + +## Additional Information ## +[Any additional information, configuration or data that might be necessary to reproduce the issue] + diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml new file mode 100644 index 0000000000..da332ecca3 --- /dev/null +++ b/.github/codeql/codeql-config.yml @@ -0,0 +1,2 @@ +name: "CodeQL config" +ram: 6500 diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml new file mode 100644 index 0000000000..dbaaba487d --- /dev/null +++ b/.github/workflows/ccpp.yml @@ -0,0 +1,18 @@ +name: C/C++ CI +on: push +jobs: + x86_ubuntu_build: + name: Build on x86 + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-22.04, ubuntu-20.04] + compiler: [gcc, clang] + steps: + - uses: actions/checkout@v3 + - name: Build srsRAN Project on x86 ${{ matrix.os }} + run: | + sudo apt update + sudo apt install -y cmake make gcc g++ pkg-config libfftw3-dev libmbedtls-dev libsctp-dev libyaml-cpp-dev libgtest-dev ninja-build + mkdir build && cd build && cmake -DENABLE_UHD=False -GNinja .. && ninja && ctest \ No newline at end of file diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..57b0a83cf6 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,69 @@ +name: "CodeQL" + +on: + push: + branches: [ "main" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "main" ] + schedule: + - cron: '38 10 * * 2' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'cpp' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install dependencies + run: | + sudo apt update + sudo apt install -y \ + build-essential \ + cmake \ + libfftw3-dev \ + libmbedtls-dev \ + libyaml-cpp-dev \ + libgtest-dev \ + libsctp-dev \ + libuhd-dev \ + ninja-build + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql/codeql-config.yml + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" From ac2ef1238a6a5caf54c21ce1b080fdd876c28a9e Mon Sep 17 00:00:00 2001 From: asaezper Date: Wed, 18 Oct 2023 12:02:24 +0200 Subject: [PATCH 04/27] ci,github: remove codeql cron --- .github/workflows/codeql.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 57b0a83cf6..44f2f840d5 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -6,8 +6,6 @@ on: pull_request: # The branches below must be a subset of the branches above branches: [ "main" ] - schedule: - - cron: '38 10 * * 2' jobs: analyze: From 42e3df27dcdaae45e09535f540d3c610eca59274 Mon Sep 17 00:00:00 2001 From: asaezper Date: Thu, 19 Oct 2023 09:19:11 +0200 Subject: [PATCH 05/27] readme: remove codeql badge --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 9596d20344..a4cf2db24c 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ srsRAN ====== [![Build Status](https://github.com/srsran/srsRAN_Project/actions/workflows/ccpp.yml/badge.svg?branch=main)](https://github.com/srsran/srsRAN_Project/actions/workflows/ccpp.yml) -[![CodeQL](https://github.com/srsran/srsRAN_Project/actions/workflows/codeql.yml/badge.svg?branch=main)](https://github.com/srsran/srsRAN_Project/actions/workflows/codeql.yml) [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/7868/badge)](https://www.bestpractices.dev/projects/7868) srsRAN is a complete 5G RAN solution, featuring an ORAN-native CU/DU developed by [SRS](http://www.srs.io). From 3ff4e5b7b8df9d7d78399ab7204d2d3bf9e075c0 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Tue, 17 Oct 2023 12:32:27 +0200 Subject: [PATCH 06/27] sched: disable PUCCH HARQ-ACK and CSI mplex for mimo Signed-off-by: Carlo Galiotto --- lib/scheduler/uci_scheduling/uci_allocator_impl.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/scheduler/uci_scheduling/uci_allocator_impl.cpp b/lib/scheduler/uci_scheduling/uci_allocator_impl.cpp index 1747a6f9bf..774837ca0e 100644 --- a/lib/scheduler/uci_scheduling/uci_allocator_impl.cpp +++ b/lib/scheduler/uci_scheduling/uci_allocator_impl.cpp @@ -232,9 +232,11 @@ uci_allocation uci_allocator_impl::alloc_uci_harq_ue(cell_resource_allocator& } if (csi_helper::is_csi_reporting_slot(ue_cell_cfg.cfg_dedicated(), uci_slot)) { - // NOTE: For TX with more than 2 antenna, the reported CSI is 11 bit, so we avoid multiplexing HARQ-ACK with CSI - // in the slots for CSI. - if (cell_cfg.dl_carrier.nof_ant > 2U) { + // NOTE: For TX with more than 1 antenna, we avoid multiplexing HARQ-ACK with CSI in the slots for CSI for the + // following reasons: + // - The multiplexing does not work well with the current implementation of PUCCH allocator. + // - For MIMO 4x4, the CSI report is 11 bit, and the current PUCCH F2 capacity is exactly 11 bits. + if (cell_cfg.dl_carrier.nof_ant > 1U) { continue; } // NOTE: This is only to avoid allocating more than 2 HARQ bits in PUCCH that are expected to carry CSI reporting. From 8e2fdbf0186f4813b8c47e75dd4410fc87e2da96 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Martinez Date: Wed, 18 Oct 2023 11:19:44 +0200 Subject: [PATCH 07/27] phy: make PDSCH DM-RS processor a thread local pool --- .../channel_processor_factories.cpp | 47 +++++++++---------- .../pdsch_processor_concurrent_impl.cpp | 2 +- .../pdsch_processor_concurrent_impl.h | 20 ++++---- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/lib/phy/upper/channel_processors/channel_processor_factories.cpp b/lib/phy/upper/channel_processors/channel_processor_factories.cpp index 0fe838c5c0..6937e4706c 100644 --- a/lib/phy/upper/channel_processors/channel_processor_factories.cpp +++ b/lib/phy/upper/channel_processors/channel_processor_factories.cpp @@ -305,39 +305,22 @@ class pdsch_processor_factory_sw : public pdsch_processor_factory class pdsch_processor_concurrent_factory_sw : public pdsch_processor_factory { -private: - std::shared_ptr crc_factory; - std::shared_ptr encoder_factory; - std::shared_ptr rate_matcher_factory; - std::shared_ptr prg_factory; - std::shared_ptr modulator_factory; - std::shared_ptr dmrs_factory; - task_executor& executor; - std::shared_ptr cb_processor_pool; - public: - pdsch_processor_concurrent_factory_sw(std::shared_ptr crc_factory_, - std::shared_ptr encoder_factory_, - std::shared_ptr rate_matcher_factory_, + pdsch_processor_concurrent_factory_sw(std::shared_ptr crc_factory, + std::shared_ptr encoder_factory, + std::shared_ptr rate_matcher_factory, std::shared_ptr prg_factory_, - std::shared_ptr modulator_factory_, - std::shared_ptr dmrs_factory_, + std::shared_ptr modulator_factory, + std::shared_ptr dmrs_factory, task_executor& executor_, unsigned nof_concurrent_threads) : - crc_factory(std::move(crc_factory_)), - encoder_factory(std::move(encoder_factory_)), - rate_matcher_factory(std::move(rate_matcher_factory_)), - prg_factory(std::move(prg_factory_)), - modulator_factory(std::move(modulator_factory_)), - dmrs_factory(std::move(dmrs_factory_)), - executor(executor_) + prg_factory(std::move(prg_factory_)), executor(executor_) { srsran_assert(crc_factory, "Invalid CRC calculator factory."); srsran_assert(encoder_factory, "Invalid encoder factory."); srsran_assert(rate_matcher_factory, "Invalid rate matcher factory."); srsran_assert(prg_factory, "Invalid PRG factory."); srsran_assert(modulator_factory, "Invalid modulator factory."); - srsran_assert(dmrs_factory, "Invalid DM-RS factory."); srsran_assert(nof_concurrent_threads > 1, "Number of concurrent threads must be greater than one."); // Create vector of codeblock processors. @@ -356,18 +339,34 @@ class pdsch_processor_concurrent_factory_sw : public pdsch_processor_factory // Create pool of codeblock processors. It is common for all PDSCH processors. cb_processor_pool = std::make_shared(std::move(cb_processors)); + + // Create vector of PDSCH DM-RS generators. + std::vector> dmrs_generators; + for (unsigned i_encoder = 0; i_encoder != nof_concurrent_threads; ++i_encoder) { + dmrs_generators.emplace_back(dmrs_factory->create()); + } + + // Create pool of PDSCH DM-RS generators. It is common for all PDSCH processors. + dmrs_generator_pool = + std::make_shared(std::move(dmrs_generators)); } std::unique_ptr create() override { return std::make_unique( - cb_processor_pool, prg_factory->create(), dmrs_factory->create(), executor); + cb_processor_pool, prg_factory->create(), dmrs_generator_pool, executor); } std::unique_ptr create_validator() override { return std::make_unique(); } + +private: + std::shared_ptr prg_factory; + task_executor& executor; + std::shared_ptr cb_processor_pool; + std::shared_ptr dmrs_generator_pool; }; class pdsch_processor_lite_factory_sw : public pdsch_processor_factory diff --git a/lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.cpp b/lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.cpp index 3e094460e6..86cd35f017 100644 --- a/lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.cpp +++ b/lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.cpp @@ -382,7 +382,7 @@ void pdsch_processor_concurrent_impl::process_dmrs() dmrs_config.precoding = config.precoding; // Put DM-RS. - dmrs->map(*mapper, dmrs_config); + dmrs_generator_pool->get().map(*mapper, dmrs_config); // Decrement asynchronous task counter. if (async_task_counter.fetch_sub(1) == 1) { diff --git a/lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.h b/lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.h index 3c258a91e5..5983684e6c 100644 --- a/lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.h +++ b/lib/phy/upper/channel_processors/pdsch_processor_concurrent_impl.h @@ -27,6 +27,8 @@ class pdsch_processor_concurrent_impl : public pdsch_processor public: /// Codeblock processor pool type. using codeblock_processor_pool = concurrent_thread_local_object_pool; + /// PDSCH DM-RS generator pool type. + using pdsch_dmrs_generator_pool = concurrent_thread_local_object_pool; /// \brief Creates a concurrent PDSCH processor with all the dependencies. /// \param[in] segmenter_ LDPC transmitter segmenter. @@ -34,19 +36,19 @@ class pdsch_processor_concurrent_impl : public pdsch_processor /// \param[in] scrambler_ Scrambling pseudo-random generator. /// \param[in] dmrs_ DM-RS for PDSCH generator. /// \param[in] executor_ Asynchronous task executor. - pdsch_processor_concurrent_impl(std::shared_ptr cb_processor_pool_, - std::unique_ptr scrambler_, - std::unique_ptr dmrs_, - task_executor& executor_) : + pdsch_processor_concurrent_impl(std::shared_ptr cb_processor_pool_, + std::unique_ptr scrambler_, + std::shared_ptr dmrs_generator_pool_, + task_executor& executor_) : scrambler(std::move(scrambler_)), cb_processor_pool(std::move(cb_processor_pool_)), - dmrs(std::move(dmrs_)), + dmrs_generator_pool(std::move(dmrs_generator_pool_)), executor(executor_), temp_codeword(pdsch_constants::CODEWORD_MAX_SYMBOLS) { - srsran_assert(scrambler != nullptr, "Invalid scrambler pointer."); - srsran_assert(cb_processor_pool != nullptr, "Invalid CB processor pool pointer."); - srsran_assert(dmrs != nullptr, "Invalid DM-RS pointer."); + srsran_assert(scrambler, "Invalid scrambler pointer."); + srsran_assert(cb_processor_pool, "Invalid CB processor pool pointer."); + srsran_assert(dmrs_generator_pool, "Invalid DM-RS pointer."); } // See interface for documentation. @@ -91,7 +93,7 @@ class pdsch_processor_concurrent_impl : public pdsch_processor /// Pool of code block processors. std::shared_ptr cb_processor_pool; /// DM-RS processor. - std::unique_ptr dmrs; + std::shared_ptr dmrs_generator_pool; /// Asynchronous task executor. task_executor& executor; From cdd5c3c78cd988f33f875e0e3b8024f63cce395b Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Martinez Date: Wed, 18 Oct 2023 11:37:49 +0200 Subject: [PATCH 08/27] phy: redduce EVM calculator memory footprint --- .../evm_calculator_generic_impl.cpp | 45 +++++++++++++++---- .../evm_calculator_generic_impl.h | 2 +- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.cpp b/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.cpp index 34987808c4..7acad90148 100644 --- a/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.cpp +++ b/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.cpp @@ -19,15 +19,42 @@ float evm_calculator_generic_impl::calculate(span so span symbols, modulation_scheme modulation) { - // Perform hard-decision. - bit_buffer hard_bits = temp_hard_bits.first(soft_bits.size()); - hard_decision(hard_bits, soft_bits); + // Get modulation order. + unsigned bits_per_symbol = get_bits_per_symbol(modulation); - // Modulate. - span modulated = temp_modulated.first(symbols.size()); - modulator->modulate(modulated, hard_bits, modulation); + // Verify that soft bits and symbols dimensions are consistent. + srsran_assert(soft_bits.size() == symbols.size() * bits_per_symbol, + "The number of soft bits (i.e., {}) is not consistent with the number of symbols (i.e., {}) and " + "modulation (i.e., {}).", + soft_bits.size(), + symbols.size(), + to_string(modulation)); - // Calculate EVM. - srsvec::subtract(modulated, symbols, modulated); - return std::sqrt(srsvec::average_power(modulated)); + unsigned nof_symbols = symbols.size(); + float avg_power = 0.0; + + while (!soft_bits.empty()) { + unsigned block_nof_symbols = std::min(static_cast(symbols.size()), MAX_NOF_SYMBOLS); + unsigned block_nof_bits = block_nof_symbols * bits_per_symbol; + + // Perform hard-decision. + bit_buffer hard_bits = temp_hard_bits.first(block_nof_bits); + hard_decision(hard_bits, soft_bits.first(block_nof_bits)); + + // Modulate. + span modulated = temp_modulated.first(block_nof_symbols); + modulator->modulate(modulated, hard_bits, modulation); + + // Calculate EVM. + srsvec::subtract(modulated, symbols.first(block_nof_symbols), modulated); + + // Accumulate power. + avg_power += std::real(srsvec::dot_prod(modulated, modulated)); + + // Pop bits and symbols. + symbols = symbols.last(symbols.size() - block_nof_symbols); + soft_bits = soft_bits.last(soft_bits.size() - block_nof_bits); + } + + return std::sqrt(avg_power / static_cast(nof_symbols)); } diff --git a/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.h b/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.h index 9e4bdc03e6..1979158b31 100644 --- a/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.h +++ b/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.h @@ -34,7 +34,7 @@ class evm_calculator_generic_impl : public evm_calculator private: /// Maximum number of symbols assuming 156 RE/RB, 275 RB and 4 layers. - static constexpr unsigned MAX_NOF_SYMBOLS = 156 * 275 * 4; + static constexpr unsigned MAX_NOF_SYMBOLS = 4096; /// Maximum number of bits. static constexpr unsigned MAX_NOF_BITS = MAX_NOF_SYMBOLS * 8; /// Internal modulator. From 9e32d74502d06d2e17f24fd610c062dc916d3d68 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Martinez Date: Wed, 18 Oct 2023 12:26:43 +0200 Subject: [PATCH 09/27] gnb: adjust PUSCH concurrency levels to reduce memory usage --- apps/gnb/gnb_appconfig_translators.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/gnb/gnb_appconfig_translators.cpp b/apps/gnb/gnb_appconfig_translators.cpp index 68cdd4a5a1..ed31a44681 100644 --- a/apps/gnb/gnb_appconfig_translators.cpp +++ b/apps/gnb/gnb_appconfig_translators.cpp @@ -1269,8 +1269,15 @@ std::vector srsran::generate_du_low_config(const gnb_appconfig const prach_configuration prach_cfg = prach_configuration_get(frequency_range::FR1, duplex, cell.prach_cfg.prach_config_index.value()); - // Maximum number of HARQ processes for a PUSCH HARQ process. - static constexpr unsigned max_nof_pusch_harq = 16; + // Maximum time that can take to decode a PUSCH transmission in slots. + static constexpr unsigned max_nof_pusch_harq = 8; + + // Maximum concurrent PUSCH processing. If there are no dedicated threads for PUSCH decoding, set the maximum + // concurrency to one. + unsigned max_pusch_concurrency = config.common_cell_cfg.pusch_cfg.max_puschs_per_slot * max_nof_pusch_harq; + if (config.expert_execution_cfg.threads.upper_threads.nof_pusch_decoder_threads == 0) { + max_pusch_concurrency = 1; + } cfg.log_level = srslog::str_to_basic_level(config.log_cfg.phy_level); cfg.enable_logging_broadcast = config.log_cfg.broadcast_enabled; @@ -1286,7 +1293,7 @@ std::vector srsran::generate_du_low_config(const gnb_appconfig cfg.nof_slots_ul_rg = ul_pipeline_depth; cfg.nof_ul_processors = ul_pipeline_depth; cfg.max_ul_thread_concurrency = config.expert_execution_cfg.threads.upper_threads.nof_ul_threads + 1; - cfg.max_pusch_concurrency = MAX_UE_PDUS_PER_SLOT * max_nof_pusch_harq; + cfg.max_pusch_concurrency = max_pusch_concurrency; cfg.nof_pusch_decoder_threads = config.expert_execution_cfg.threads.upper_threads.nof_pusch_decoder_threads + config.expert_execution_cfg.threads.upper_threads.nof_ul_threads; cfg.nof_prach_buffer = prach_pipeline_depth * nof_slots_per_subframe; From ccd90237af11af48bcc4d7ab32383d9b2d98ffae Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Martinez Date: Wed, 18 Oct 2023 12:42:33 +0200 Subject: [PATCH 10/27] phy: use variant in upper PHY for PUSCH and PUCCH PDUs --- .../phy/upper/uplink_slot_pdu_repository.h | 28 +++---------------- .../upper_phy_rx_symbol_handler_impl.cpp | 24 +++++++++------- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/include/srsran/phy/upper/uplink_slot_pdu_repository.h b/include/srsran/phy/upper/uplink_slot_pdu_repository.h index 4637573bba..6eebdbcb0b 100644 --- a/include/srsran/phy/upper/uplink_slot_pdu_repository.h +++ b/include/srsran/phy/upper/uplink_slot_pdu_repository.h @@ -10,6 +10,7 @@ #pragma once +#include "srsran/adt/variant.h" #include "srsran/phy/upper/uplink_processor.h" #include "srsran/ran/slot_pdu_capacity_constants.h" #include @@ -17,18 +18,7 @@ namespace srsran { /// Defines an entry of the uplink slot PDU repository. -struct uplink_slot_pdu_entry { - /// Labels for the supported PDU types. - enum class pdu_type { PUSCH, PUCCH }; - - /// PDU type. - pdu_type type; - // :TODO: convert this to variant. - /// PUSCH PDU. - uplink_processor::pusch_pdu pusch; - /// PUCCH PDU. - uplink_processor::pucch_pdu pucch; -}; +using uplink_slot_pdu_entry = variant; /// \brief Uplink slot PDU repository. /// @@ -47,23 +37,13 @@ class uplink_slot_pdu_repository /// Adds the given PUSCH PDU to the repository at the given slot. void add_pusch_pdu(slot_point slot, const uplink_processor::pusch_pdu& pdu) { - uplink_slot_pdu_entry entry; - entry.type = uplink_slot_pdu_entry::pdu_type::PUSCH; - entry.pusch = pdu; - entry.pucch = {}; - - repository[slot.to_uint() % nof_slots].push_back(entry); + repository[slot.to_uint() % nof_slots].push_back(pdu); } /// Adds the given PUCCH PDU to the repository at the given slot. void add_pucch_pdu(slot_point slot, const uplink_processor::pucch_pdu& pdu) { - uplink_slot_pdu_entry entry; - entry.type = uplink_slot_pdu_entry::pdu_type::PUCCH; - entry.pucch = pdu; - entry.pusch = {}; - - repository[slot.to_uint() % nof_slots].push_back(entry); + repository[slot.to_uint() % nof_slots].push_back(pdu); } /// Clears the given slot of the registry. diff --git a/lib/phy/upper/upper_phy_rx_symbol_handler_impl.cpp b/lib/phy/upper/upper_phy_rx_symbol_handler_impl.cpp index 2086160304..52da794915 100644 --- a/lib/phy/upper/upper_phy_rx_symbol_handler_impl.cpp +++ b/lib/phy/upper/upper_phy_rx_symbol_handler_impl.cpp @@ -66,9 +66,14 @@ void upper_phy_rx_symbol_handler_impl::handle_rx_symbol(const upper_phy_rx_symbo } const uplink_slot_pdu_entry& first_entry = pdus.front(); - unsigned nof_symbols = - get_nsymb_per_slot((first_entry.type == uplink_slot_pdu_entry::pdu_type::PUSCH) ? first_entry.pusch.pdu.cp - : get_cp(first_entry.pucch)); + unsigned nof_symbols = 0; + if (variant_holds_alternative(first_entry)) { + const uplink_processor::pusch_pdu& pdu = variant_get(first_entry); + nof_symbols = get_nsymb_per_slot(pdu.pdu.cp); + } else { + const uplink_processor::pucch_pdu& pdu = variant_get(first_entry); + nof_symbols = get_nsymb_per_slot(get_cp(pdu)); + } unsigned last_symbol_id = nof_symbols - 1U; // Process the PDUs when all symbols of the slot have been received. @@ -81,13 +86,12 @@ void upper_phy_rx_symbol_handler_impl::handle_rx_symbol(const upper_phy_rx_symbo // Process all the PDUs from the pool. for (const auto& pdu : pdus) { - switch (pdu.type) { - case uplink_slot_pdu_entry::pdu_type::PUSCH: - process_pusch(pdu.pusch, ul_processor, grid, context.slot); - break; - case uplink_slot_pdu_entry::pdu_type::PUCCH: - ul_processor.process_pucch(rx_results_notifier, grid, pdu.pucch); - break; + if (variant_holds_alternative(pdu)) { + const uplink_processor::pusch_pdu& pusch_pdu = variant_get(pdu); + process_pusch(pusch_pdu, ul_processor, grid, context.slot); + } else if (variant_holds_alternative(pdu)) { + const uplink_processor::pucch_pdu& pucch_pdu = variant_get(pdu); + ul_processor.process_pucch(rx_results_notifier, grid, pucch_pdu); } } } From d6984621ccd991171a20fbcb9f9acef1dbc95e42 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Martinez Date: Wed, 18 Oct 2023 14:26:44 +0200 Subject: [PATCH 11/27] phy: fix PUSCH data buffer pool --- include/srsran/phy/upper/uplink_processor.h | 4 ++-- lib/fapi_adaptor/phy/messages/pusch.cpp | 2 +- lib/phy/upper/upper_phy_rx_symbol_handler_impl.h | 15 +++++++++------ .../phy/messages/ul_pusch_pdu_test.cpp | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/include/srsran/phy/upper/uplink_processor.h b/include/srsran/phy/upper/uplink_processor.h index c035b821d9..48b6645083 100644 --- a/include/srsran/phy/upper/uplink_processor.h +++ b/include/srsran/phy/upper/uplink_processor.h @@ -40,8 +40,8 @@ class uplink_processor struct pusch_pdu { /// HARQ process number. unsigned harq_id; - /// Transport block size in bytes. - unsigned tb_size; + /// Transport block size. + units::bytes tb_size; /// PUSCH processor PDU. pusch_processor::pdu_t pdu; }; diff --git a/lib/fapi_adaptor/phy/messages/pusch.cpp b/lib/fapi_adaptor/phy/messages/pusch.cpp index 3bdc505cdf..ee530023af 100644 --- a/lib/fapi_adaptor/phy/messages/pusch.cpp +++ b/lib/fapi_adaptor/phy/messages/pusch.cpp @@ -26,7 +26,7 @@ static void fill_codeword(uplink_processor::pusch_pdu& pdu, const fapi::ul_pusch cw.new_data = fapi_pdu.pusch_data.new_data; pdu.harq_id = fapi_pdu.pusch_data.harq_process_id; - pdu.tb_size = fapi_pdu.pusch_data.tb_size.value(); + pdu.tb_size = fapi_pdu.pusch_data.tb_size; pdu.pdu.codeword = optional(std::move(cw)); } diff --git a/lib/phy/upper/upper_phy_rx_symbol_handler_impl.h b/lib/phy/upper/upper_phy_rx_symbol_handler_impl.h index a33ea85b37..b22b2f7a81 100644 --- a/lib/phy/upper/upper_phy_rx_symbol_handler_impl.h +++ b/lib/phy/upper/upper_phy_rx_symbol_handler_impl.h @@ -27,21 +27,24 @@ class upper_phy_rx_results_notifier; class rx_payload_buffer_pool { /// Maximum number of payloads contained by the pool. - static const size_t MAX_NUM_PAYLOAD = 4096U; - static const size_t MAX_BUFFER_SIZE = MAX_RB * 156 * 8; + static constexpr size_t MAX_NUM_PAYLOAD = 4096U; + static constexpr units::bits MAX_BUFFER_SIZE = units::bits(MAX_RB * 156 * 8); public: /// Returns the next available buffer from the pool. - span acquire_payload_buffer(size_t size) + span acquire_payload_buffer(units::bytes size) { - srsran_assert(size <= MAX_BUFFER_SIZE, "Buffer size (i.e., {}) exceeds maximum {}.", size, pool[index].size()); + srsran_assert(size.to_bits() <= static_cast(MAX_BUFFER_SIZE), + "Buffer size (i.e., {}) exceeds maximum {}.", + size, + pool[index].size()); unsigned i = index++ % MAX_NUM_PAYLOAD; - return span(pool[i]).first(size); + return span(pool[i]).first(size.value()); } private: /// Buffer pool. - circular_array, MAX_NUM_PAYLOAD> pool; + circular_array, MAX_NUM_PAYLOAD> pool; /// Index used to retrieve the next container. unsigned index = 0; }; diff --git a/tests/unittests/fapi_adaptor/phy/messages/ul_pusch_pdu_test.cpp b/tests/unittests/fapi_adaptor/phy/messages/ul_pusch_pdu_test.cpp index 0687c94bb8..1776b47cde 100644 --- a/tests/unittests/fapi_adaptor/phy/messages/ul_pusch_pdu_test.cpp +++ b/tests/unittests/fapi_adaptor/phy/messages/ul_pusch_pdu_test.cpp @@ -86,6 +86,6 @@ TEST(fapi_phy_ul_pusch_adaptor_test, valid_pdu_pass) ASSERT_EQ(fapi_pdu.pusch_data.rv_index, phy_pdu.codeword.value().rv); ASSERT_EQ(fapi_pdu.pusch_data.new_data, phy_pdu.codeword.value().new_data); ASSERT_EQ(fapi_pdu.pusch_maintenance_v3.ldpc_base_graph, phy_pdu.codeword.value().ldpc_base_graph); - ASSERT_EQ(fapi_pdu.pusch_data.tb_size.value(), pdu.tb_size); + ASSERT_EQ(fapi_pdu.pusch_data.tb_size.value(), pdu.tb_size.value()); ASSERT_EQ(fapi_pdu.pusch_data.harq_process_id, pdu.harq_id); } From 0ecf050235fa87cbfe83a7c6b5abe373904497f5 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Martinez Date: Wed, 18 Oct 2023 15:06:24 +0200 Subject: [PATCH 12/27] gnb: review number of concurrent PUSCH processors --- apps/gnb/gnb_appconfig_translators.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/gnb/gnb_appconfig_translators.cpp b/apps/gnb/gnb_appconfig_translators.cpp index ed31a44681..1e07baeec6 100644 --- a/apps/gnb/gnb_appconfig_translators.cpp +++ b/apps/gnb/gnb_appconfig_translators.cpp @@ -1269,11 +1269,12 @@ std::vector srsran::generate_du_low_config(const gnb_appconfig const prach_configuration prach_cfg = prach_configuration_get(frequency_range::FR1, duplex, cell.prach_cfg.prach_config_index.value()); - // Maximum time that can take to decode a PUSCH transmission in slots. - static constexpr unsigned max_nof_pusch_harq = 8; + // Maximum number of HARQ processes for a PUSCH HARQ process. + static constexpr unsigned max_nof_pusch_harq = 16; // Maximum concurrent PUSCH processing. If there are no dedicated threads for PUSCH decoding, set the maximum - // concurrency to one. + // concurrency to one. Otherwise, assume every possible PUSCH transmission for the maximum number of HARQ could be + // enqueued. unsigned max_pusch_concurrency = config.common_cell_cfg.pusch_cfg.max_puschs_per_slot * max_nof_pusch_harq; if (config.expert_execution_cfg.threads.upper_threads.nof_pusch_decoder_threads == 0) { max_pusch_concurrency = 1; From 9cd59ab2364940c2abcdf8324c1b9d2283bf4d45 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Martinez Date: Wed, 18 Oct 2023 16:23:00 +0200 Subject: [PATCH 13/27] phy: review memory related phy: fix compilation --- .../upper/channel_modulation/evm_calculator_generic_impl.cpp | 5 +++-- .../upper/channel_modulation/evm_calculator_generic_impl.h | 4 ++-- .../upper/channel_processors/channel_processor_factories.cpp | 1 + lib/phy/upper/upper_phy_rx_symbol_handler_impl.h | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.cpp b/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.cpp index 7acad90148..82de33aa60 100644 --- a/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.cpp +++ b/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.cpp @@ -34,8 +34,9 @@ float evm_calculator_generic_impl::calculate(span so float avg_power = 0.0; while (!soft_bits.empty()) { - unsigned block_nof_symbols = std::min(static_cast(symbols.size()), MAX_NOF_SYMBOLS); - unsigned block_nof_bits = block_nof_symbols * bits_per_symbol; + unsigned block_nof_symbols = + std::min(static_cast(symbols.size()), static_cast(MAX_NOF_SYMBOLS)); + unsigned block_nof_bits = block_nof_symbols * bits_per_symbol; // Perform hard-decision. bit_buffer hard_bits = temp_hard_bits.first(block_nof_bits); diff --git a/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.h b/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.h index 1979158b31..d1d1d18d2a 100644 --- a/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.h +++ b/lib/phy/upper/channel_modulation/evm_calculator_generic_impl.h @@ -33,9 +33,9 @@ class evm_calculator_generic_impl : public evm_calculator modulation_scheme modulation) override; private: - /// Maximum number of symbols assuming 156 RE/RB, 275 RB and 4 layers. + /// Maximum processing block size in number of symbols. static constexpr unsigned MAX_NOF_SYMBOLS = 4096; - /// Maximum number of bits. + /// Maximum processing block size in number of bits. static constexpr unsigned MAX_NOF_BITS = MAX_NOF_SYMBOLS * 8; /// Internal modulator. std::unique_ptr modulator; diff --git a/lib/phy/upper/channel_processors/channel_processor_factories.cpp b/lib/phy/upper/channel_processors/channel_processor_factories.cpp index 6937e4706c..36777d3d58 100644 --- a/lib/phy/upper/channel_processors/channel_processor_factories.cpp +++ b/lib/phy/upper/channel_processors/channel_processor_factories.cpp @@ -321,6 +321,7 @@ class pdsch_processor_concurrent_factory_sw : public pdsch_processor_factory srsran_assert(rate_matcher_factory, "Invalid rate matcher factory."); srsran_assert(prg_factory, "Invalid PRG factory."); srsran_assert(modulator_factory, "Invalid modulator factory."); + srsran_assert(dmrs_factory, "Invalid DM-RS factory."); srsran_assert(nof_concurrent_threads > 1, "Number of concurrent threads must be greater than one."); // Create vector of codeblock processors. diff --git a/lib/phy/upper/upper_phy_rx_symbol_handler_impl.h b/lib/phy/upper/upper_phy_rx_symbol_handler_impl.h index b22b2f7a81..f40ee9eec2 100644 --- a/lib/phy/upper/upper_phy_rx_symbol_handler_impl.h +++ b/lib/phy/upper/upper_phy_rx_symbol_handler_impl.h @@ -34,7 +34,7 @@ class rx_payload_buffer_pool /// Returns the next available buffer from the pool. span acquire_payload_buffer(units::bytes size) { - srsran_assert(size.to_bits() <= static_cast(MAX_BUFFER_SIZE), + srsran_assert(size.to_bits().value() <= pool[index].size(), "Buffer size (i.e., {}) exceeds maximum {}.", size, pool[index].size()); From 6485bce1fa5836875a54fcd24f7953e26891902d Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Martinez Date: Thu, 19 Oct 2023 12:39:57 +0200 Subject: [PATCH 14/27] phy: fix bit/byte vector size --- lib/phy/upper/upper_phy_rx_symbol_handler_impl.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/phy/upper/upper_phy_rx_symbol_handler_impl.h b/lib/phy/upper/upper_phy_rx_symbol_handler_impl.h index f40ee9eec2..8f6861991a 100644 --- a/lib/phy/upper/upper_phy_rx_symbol_handler_impl.h +++ b/lib/phy/upper/upper_phy_rx_symbol_handler_impl.h @@ -34,10 +34,8 @@ class rx_payload_buffer_pool /// Returns the next available buffer from the pool. span acquire_payload_buffer(units::bytes size) { - srsran_assert(size.to_bits().value() <= pool[index].size(), - "Buffer size (i.e., {}) exceeds maximum {}.", - size, - pool[index].size()); + srsran_assert( + size.value() <= pool[index].size(), "Buffer size (i.e., {}) exceeds maximum {}.", size, pool[index].size()); unsigned i = index++ % MAX_NUM_PAYLOAD; return span(pool[i]).first(size.value()); } From 8c860bdf520be97268a009a5aa5e0decce669844 Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Wed, 18 Oct 2023 15:39:30 +0200 Subject: [PATCH 15/27] gnb: add the promiscuous flag to the gNB app configuration. Defined defaults value for the expert threads configuration --- apps/gnb/gnb_appconfig.h | 48 +++++++++++++++---- apps/gnb/gnb_appconfig_cli11_schema.cpp | 2 + apps/gnb/gnb_appconfig_translators.cpp | 3 +- .../srsran/ofh/ethernet/ethernet_factories.h | 1 + .../srsran/ofh/ethernet/ethernet_gw_config.h | 2 + include/srsran/ofh/ofh_sector_config.h | 2 + include/srsran/ru/ru_ofh_configuration.h | 2 + .../ethernet/dpdk/dpdk_ethernet_factories.cpp | 4 +- .../ethernet/dpdk/dpdk_ethernet_factories.h | 3 +- .../dpdk/dpdk_ethernet_transmitter.cpp | 19 ++++---- .../ethernet/dpdk/dpdk_ethernet_transmitter.h | 4 +- lib/ofh/ethernet/ethernet_factories.cpp | 3 +- lib/ofh/ethernet/ethernet_receiver_impl.cpp | 21 ++++---- lib/ofh/ethernet/ethernet_receiver_impl.h | 1 + lib/ofh/ofh_factories.cpp | 15 ++++-- lib/ru/ofh/ru_ofh_factory.cpp | 31 ++++++------ 16 files changed, 108 insertions(+), 53 deletions(-) diff --git a/apps/gnb/gnb_appconfig.h b/apps/gnb/gnb_appconfig.h index deca16d7f9..fcefc86d0f 100644 --- a/apps/gnb/gnb_appconfig.h +++ b/apps/gnb/gnb_appconfig.h @@ -741,7 +741,7 @@ struct expert_upper_phy_appconfig { /// Higher values increase the downlink processing pipeline length, which improves performance and stability for /// demanding cell configurations, such as using large bandwidths or higher order MIMO. Higher values also increase /// the round trip latency of the radio link. - unsigned max_processing_delay_slots = 2U; + unsigned max_processing_delay_slots = 5U; /// Number of PUSCH LDPC decoder iterations. unsigned pusch_decoder_max_iterations = 6; /// Set to true to enable the PUSCH LDPC decoder early stop. @@ -887,6 +887,8 @@ struct ru_ofh_cell_appconfig { ru_ofh_base_cell_appconfig cell; /// Ethernet network interface name. std::string network_interface = "enp1s0f0"; + /// Promiscuous mode flag. + bool enable_promiscuous_mode = true; /// Radio Unit MAC address. std::string ru_mac_address = "70:b3:d5:e1:5b:06"; /// Distributed Unit MAC address. @@ -962,15 +964,6 @@ struct upper_phy_threads_appconfig { /// Lower PHY thread configuration fo the gNB. struct lower_phy_threads_appconfig { - lower_phy_threads_appconfig() - { - // Set the lower PHY thread profile according to the number of CPU cores. - if (srsran::compute_host_nof_hardware_threads() >= 8U) { - execution_profile = lower_phy_thread_profile::quad; - } else { - execution_profile = lower_phy_thread_profile::dual; - } - } /// \brief Lower physical layer thread profile. /// /// If not configured, a default value is selected based on the number of available CPU cores. @@ -984,6 +977,41 @@ struct ofh_threads_appconfig { /// Expert threads configuration of the gNB app. struct expert_threads_appconfig { + expert_threads_appconfig() + { + unsigned nof_threads = compute_host_nof_hardware_threads(); + + if (nof_threads < 4) { + upper_threads.nof_ul_threads = 1; + upper_threads.nof_pusch_decoder_threads = 0; + upper_threads.nof_pdsch_threads = 1; + upper_threads.nof_dl_threads = 1; + lower_threads.execution_profile = lower_phy_thread_profile::single; + ofh_threads.is_downlink_parallelized = false; + } else if (nof_threads < 8) { + upper_threads.nof_ul_threads = 1; + upper_threads.nof_pusch_decoder_threads = 1; + upper_threads.nof_pdsch_threads = 2; + upper_threads.nof_dl_threads = 2; + lower_threads.execution_profile = lower_phy_thread_profile::dual; + ofh_threads.is_downlink_parallelized = true; + } else if (nof_threads < 16) { + upper_threads.nof_ul_threads = 1; + upper_threads.nof_pusch_decoder_threads = 1; + upper_threads.nof_pdsch_threads = 4; + upper_threads.nof_dl_threads = 2; + lower_threads.execution_profile = lower_phy_thread_profile::quad; + ofh_threads.is_downlink_parallelized = true; + } else { + upper_threads.nof_ul_threads = 2; + upper_threads.nof_pusch_decoder_threads = 2; + upper_threads.nof_pdsch_threads = 8; + upper_threads.nof_dl_threads = 4; + lower_threads.execution_profile = lower_phy_thread_profile::quad; + ofh_threads.is_downlink_parallelized = true; + } + } + /// Upper PHY thread configuration of the gNB app. upper_phy_threads_appconfig upper_threads; /// Lower PHY thread configuration of the gNB app. diff --git a/apps/gnb/gnb_appconfig_cli11_schema.cpp b/apps/gnb/gnb_appconfig_cli11_schema.cpp index cb9f915bf4..8fe6c4619e 100644 --- a/apps/gnb/gnb_appconfig_cli11_schema.cpp +++ b/apps/gnb/gnb_appconfig_cli11_schema.cpp @@ -1644,6 +1644,8 @@ static void configure_cli11_ru_ofh_cells_args(CLI::App& app, ru_ofh_cell_appconf { configure_cli11_ru_ofh_base_cell_args(app, config.cell); app.add_option("--network_interface", config.network_interface, "Network interface")->capture_default_str(); + app.add_option("--enable_promiscuous", config.enable_promiscuous_mode, "Promiscuous mode flag") + ->capture_default_str(); app.add_option("--ru_mac_addr", config.ru_mac_address, "Radio Unit MAC address")->capture_default_str(); app.add_option("--du_mac_addr", config.du_mac_address, "Distributed Unit MAC address")->capture_default_str(); app.add_option("--vlan_tag", config.vlan_tag, "V-LAN identifier")->capture_default_str()->check(CLI::Range(1, 4094)); diff --git a/apps/gnb/gnb_appconfig_translators.cpp b/apps/gnb/gnb_appconfig_translators.cpp index 1e07baeec6..48da679ad1 100644 --- a/apps/gnb/gnb_appconfig_translators.cpp +++ b/apps/gnb/gnb_appconfig_translators.cpp @@ -1157,7 +1157,8 @@ generate_ru_ofh_config(ru_ofh_configuration& out_cfg, const gnb_appconfig& confi out_cfg.sector_configs.emplace_back(); ru_ofh_sector_configuration& sector_cfg = out_cfg.sector_configs.back(); - sector_cfg.interface = cell_cfg.network_interface; + sector_cfg.interface = cell_cfg.network_interface; + sector_cfg.is_promiscuous_mode_enabled = cell_cfg.enable_promiscuous_mode; if (!parse_mac_address(cell_cfg.du_mac_address, sector_cfg.mac_src_address)) { srsran_terminate("Invalid Distributed Unit MAC address"); } diff --git a/include/srsran/ofh/ethernet/ethernet_factories.h b/include/srsran/ofh/ethernet/ethernet_factories.h index 730fb64388..ba73095782 100644 --- a/include/srsran/ofh/ethernet/ethernet_factories.h +++ b/include/srsran/ofh/ethernet/ethernet_factories.h @@ -31,6 +31,7 @@ std::unique_ptr create_gateway(const gw_config& config, srslog::basic_l /// Creates an Ethernet receiver. std::unique_ptr create_receiver(const std::string& interface, + bool is_promiscuous_mode_enabled, task_executor& executor, frame_notifier& notifier, srslog::basic_logger& logger); diff --git a/include/srsran/ofh/ethernet/ethernet_gw_config.h b/include/srsran/ofh/ethernet/ethernet_gw_config.h index 7ddeecdc3e..c73c088787 100644 --- a/include/srsran/ofh/ethernet/ethernet_gw_config.h +++ b/include/srsran/ofh/ethernet/ethernet_gw_config.h @@ -19,6 +19,8 @@ namespace ether { struct gw_config { /// Interface name. std::string interface; + /// Promiscuous mode flag. + bool is_promiscuous_mode_enabled; /// Destination MAC address. mac_address mac_dst_address; }; diff --git a/include/srsran/ofh/ofh_sector_config.h b/include/srsran/ofh/ofh_sector_config.h index 8d29939ac6..7e229a7298 100644 --- a/include/srsran/ofh/ofh_sector_config.h +++ b/include/srsran/ofh/ofh_sector_config.h @@ -42,6 +42,8 @@ struct sector_configuration { /// Ethernet interface name. std::string interface; + /// Promiscuous mode flag. + bool is_promiscuous_mode_enabled; /// Destination MAC address, corresponds to the Radio Unit MAC address. ether::mac_address mac_dst_address; /// Source MAC address, corresponds to the Distributed Unit MAC address. diff --git a/include/srsran/ru/ru_ofh_configuration.h b/include/srsran/ru/ru_ofh_configuration.h index 10b12f7e08..0bd75ddeb0 100644 --- a/include/srsran/ru/ru_ofh_configuration.h +++ b/include/srsran/ru/ru_ofh_configuration.h @@ -68,6 +68,8 @@ struct ru_ofh_sector_configuration { /// Ethernet interface name. std::string interface; + /// Promiscuous mode flag. + bool is_promiscuous_mode_enabled; /// Destination MAC address, corresponds to Radio Unit MAC address. ether::mac_address mac_dst_address; /// Source MAC address, corresponds to Distributed Unit MAC address. diff --git a/lib/ofh/ethernet/dpdk/dpdk_ethernet_factories.cpp b/lib/ofh/ethernet/dpdk/dpdk_ethernet_factories.cpp index 3021a9421a..096308d4ab 100644 --- a/lib/ofh/ethernet/dpdk/dpdk_ethernet_factories.cpp +++ b/lib/ofh/ethernet/dpdk/dpdk_ethernet_factories.cpp @@ -15,9 +15,9 @@ using namespace srsran; using namespace ether; -std::unique_ptr srsran::ether::create_dpdk_gateway(srslog::basic_logger& logger) +std::unique_ptr srsran::ether::create_dpdk_gateway(const gw_config& config, srslog::basic_logger& logger) { - return std::make_unique(logger); + return std::make_unique(config, logger); } std::unique_ptr diff --git a/lib/ofh/ethernet/dpdk/dpdk_ethernet_factories.h b/lib/ofh/ethernet/dpdk/dpdk_ethernet_factories.h index 120c552f28..79630d7656 100644 --- a/lib/ofh/ethernet/dpdk/dpdk_ethernet_factories.h +++ b/lib/ofh/ethernet/dpdk/dpdk_ethernet_factories.h @@ -22,9 +22,10 @@ class task_executor; namespace ether { class frame_notifier; +struct gw_config; /// Creates a DPDK Ethernet gateway. -std::unique_ptr create_dpdk_gateway(srslog::basic_logger& logger); +std::unique_ptr create_dpdk_gateway(const gw_config& config, srslog::basic_logger& logger); /// Creates a DPDK Ethernet receiver. std::unique_ptr diff --git a/lib/ofh/ethernet/dpdk/dpdk_ethernet_transmitter.cpp b/lib/ofh/ethernet/dpdk/dpdk_ethernet_transmitter.cpp index 8034f8e69e..c3c6046c86 100644 --- a/lib/ofh/ethernet/dpdk/dpdk_ethernet_transmitter.cpp +++ b/lib/ofh/ethernet/dpdk/dpdk_ethernet_transmitter.cpp @@ -10,6 +10,7 @@ #include "dpdk_ethernet_transmitter.h" #include "srsran/adt/static_vector.h" +#include "srsran/ofh/ethernet/ethernet_gw_config.h" #include using namespace srsran; @@ -24,7 +25,7 @@ static constexpr unsigned TX_RING_SIZE = 1024; static constexpr unsigned NUM_MBUFS = 8191; /// DPDK port initialization routine. -static bool port_init(::rte_mempool* mbuf_pool, unsigned port) +static bool port_init(const gw_config& config, ::rte_mempool* mbuf_pool, unsigned port) { uint16_t nb_rxd = RX_RING_SIZE; uint16_t nb_txd = TX_RING_SIZE; @@ -84,16 +85,18 @@ static bool port_init(::rte_mempool* mbuf_pool, unsigned port) } // Enable RX in promiscuous mode for the Ethernet device. - if (::rte_eth_promiscuous_enable(port) != 0) { - fmt::print("Error enabling promiscuous mode\n"); - return false; + if (config.is_promiscuous_mode_enabled) { + if (::rte_eth_promiscuous_enable(port) != 0) { + fmt::print("Error enabling promiscuous mode\n"); + return false; + } } return true; } /// Configures an Ethernet port using DPDK. -static void dpdk_port_configure(::rte_mempool*& mbuf_pool) +static void dpdk_port_configure(const gw_config& config, ::rte_mempool*& mbuf_pool) { if (::rte_eth_dev_count_avail() != 1) { ::rte_exit(EXIT_FAILURE, "Error: number of ports must be one\n"); @@ -110,7 +113,7 @@ static void dpdk_port_configure(::rte_mempool*& mbuf_pool) unsigned portid; RTE_ETH_FOREACH_DEV(portid) { - if (!port_init(mbuf_pool, portid)) { + if (!port_init(config, mbuf_pool, portid)) { ::rte_exit(EXIT_FAILURE, "Cannot init port\n"); } } @@ -143,7 +146,7 @@ void dpdk_transmitter_impl::send(span> frames) ::rte_eth_tx_burst(port_id, 0, mbufs.data(), mbufs.size()); } -dpdk_transmitter_impl::dpdk_transmitter_impl(srslog::basic_logger& logger_) : logger(logger_) +dpdk_transmitter_impl::dpdk_transmitter_impl(const gw_config& config, srslog::basic_logger& logger_) : logger(logger_) { - dpdk_port_configure(mbuf_pool); + dpdk_port_configure(config, mbuf_pool); } diff --git a/lib/ofh/ethernet/dpdk/dpdk_ethernet_transmitter.h b/lib/ofh/ethernet/dpdk/dpdk_ethernet_transmitter.h index 4f53e9acac..fdd10c99fb 100644 --- a/lib/ofh/ethernet/dpdk/dpdk_ethernet_transmitter.h +++ b/lib/ofh/ethernet/dpdk/dpdk_ethernet_transmitter.h @@ -18,11 +18,13 @@ struct rte_mempool; namespace srsran { namespace ether { +struct gw_config; + /// DPDK Ethernet transmitter implementation. class dpdk_transmitter_impl : public gateway { public: - explicit dpdk_transmitter_impl(srslog::basic_logger& logger_); + explicit dpdk_transmitter_impl(const gw_config& config, srslog::basic_logger& logger_); // See interface for documentation. void send(span> frames) override; diff --git a/lib/ofh/ethernet/ethernet_factories.cpp b/lib/ofh/ethernet/ethernet_factories.cpp index 62abd6de8e..e67313a8a5 100644 --- a/lib/ofh/ethernet/ethernet_factories.cpp +++ b/lib/ofh/ethernet/ethernet_factories.cpp @@ -23,11 +23,12 @@ std::unique_ptr srsran::ether::create_gateway(const gw_config& config, } std::unique_ptr srsran::ether::create_receiver(const std::string& interface, + bool is_promiscuous_mode_enabled, task_executor& executor, frame_notifier& notifier, srslog::basic_logger& logger) { - return std::make_unique(interface, executor, notifier, logger); + return std::make_unique(interface, is_promiscuous_mode_enabled, executor, notifier, logger); } std::unique_ptr srsran::ether::create_vlan_frame_builder() diff --git a/lib/ofh/ethernet/ethernet_receiver_impl.cpp b/lib/ofh/ethernet/ethernet_receiver_impl.cpp index 10677c4f7e..48913b5af0 100644 --- a/lib/ofh/ethernet/ethernet_receiver_impl.cpp +++ b/lib/ofh/ethernet/ethernet_receiver_impl.cpp @@ -23,6 +23,7 @@ using namespace srsran; using namespace ether; receiver_impl::receiver_impl(const std::string& interface, + bool is_promiscuous_mode_enabled, task_executor& executor_, frame_notifier& notifier_, srslog::basic_logger& logger_) : @@ -33,15 +34,17 @@ receiver_impl::receiver_impl(const std::string& interface, report_error("Unable to open socket for Ethernet receiver"); } - // Set interface to promiscuous mode. - ::ifreq if_opts; - ::strncpy(if_opts.ifr_name, interface.c_str(), IFNAMSIZ - 1); - if (::ioctl(socket_fd, SIOCGIFFLAGS, &if_opts) < 0) { - report_error("Unable to get flags for NIC interface in the Ethernet receiver"); - } - if_opts.ifr_flags |= IFF_PROMISC; - if (::ioctl(socket_fd, SIOCSIFFLAGS, &if_opts) < 0) { - report_error("Unable to set flags for NIC interface in the Ethernet receiver"); + if (is_promiscuous_mode_enabled) { + // Set interface to promiscuous mode. + ::ifreq if_opts; + ::strncpy(if_opts.ifr_name, interface.c_str(), IFNAMSIZ - 1); + if (::ioctl(socket_fd, SIOCGIFFLAGS, &if_opts) < 0) { + report_error("Unable to get flags for NIC interface in the Ethernet receiver"); + } + if_opts.ifr_flags |= IFF_PROMISC; + if (::ioctl(socket_fd, SIOCSIFFLAGS, &if_opts) < 0) { + report_error("Unable to set flags for NIC interface in the Ethernet receiver"); + } } // Bind to device. diff --git a/lib/ofh/ethernet/ethernet_receiver_impl.h b/lib/ofh/ethernet/ethernet_receiver_impl.h index 2830bafa66..3e84a98b84 100644 --- a/lib/ofh/ethernet/ethernet_receiver_impl.h +++ b/lib/ofh/ethernet/ethernet_receiver_impl.h @@ -26,6 +26,7 @@ class receiver_impl : public receiver { public: receiver_impl(const std::string& interface, + bool is_promiscuous_mode_enabled, task_executor& executor_, frame_notifier& notifier_, srslog::basic_logger& logger_); diff --git a/lib/ofh/ofh_factories.cpp b/lib/ofh/ofh_factories.cpp index 99859e4cc2..ace4a810b1 100644 --- a/lib/ofh/ofh_factories.cpp +++ b/lib/ofh/ofh_factories.cpp @@ -298,11 +298,12 @@ resolve_transmitter_dependencies(const sector_configuration& *sector_cfg.downlink_executors.front()); ether::gw_config eth_cfg; - eth_cfg.interface = sector_cfg.interface; - eth_cfg.mac_dst_address = sector_cfg.mac_dst_address; + eth_cfg.interface = sector_cfg.interface; + eth_cfg.is_promiscuous_mode_enabled = sector_cfg.is_promiscuous_mode_enabled; + eth_cfg.mac_dst_address = sector_cfg.mac_dst_address; #ifdef DPDK_FOUND if (sector_cfg.uses_dpdk) { - dependencies.eth_gateway = ether::create_dpdk_gateway(*sector_cfg.logger); + dependencies.eth_gateway = ether::create_dpdk_gateway(eth_cfg, *sector_cfg.logger); } else { dependencies.eth_gateway = ether::create_gateway(eth_cfg, *sector_cfg.logger); } @@ -338,12 +339,16 @@ std::unique_ptr srsran::ofh::create_ofh_sector(const sector_configuratio receiver->get_ethernet_frame_notifier(), *sector_cfg.logger) : ether::create_receiver(sector_cfg.interface, + sector_cfg.is_promiscuous_mode_enabled, *sector_cfg.receiver_executor, receiver->get_ethernet_frame_notifier(), *sector_cfg.logger); #else - auto eth_receiver = ether::create_receiver( - sector_cfg.interface, *sector_cfg.receiver_executor, receiver->get_ethernet_frame_notifier(), *sector_cfg.logger); + auto eth_receiver = ether::create_receiver(sector_cfg.interface, + sector_cfg.is_promiscuous_mode_enabled, + *sector_cfg.receiver_executor, + receiver->get_ethernet_frame_notifier(), + *sector_cfg.logger); #endif return std::make_unique(std::move(receiver), diff --git a/lib/ru/ofh/ru_ofh_factory.cpp b/lib/ru/ofh/ru_ofh_factory.cpp index aa60361ffe..10819620e8 100644 --- a/lib/ru/ofh/ru_ofh_factory.cpp +++ b/lib/ru/ofh/ru_ofh_factory.cpp @@ -27,21 +27,22 @@ static ofh::sector_configuration generate_sector_configuration(const ru_ofh_conf // Prepare sector configuration. ofh::sector_configuration ofh_sector_config; - ofh_sector_config.logger = config.logger; - ofh_sector_config.transmitter_executor = sector_cfg.transmitter_executor; - ofh_sector_config.receiver_executor = sector_cfg.receiver_executor; - ofh_sector_config.downlink_executors = sector_cfg.downlink_executors; - ofh_sector_config.notifier = notifier; - ofh_sector_config.interface = sector_cfg.interface; - ofh_sector_config.mac_dst_address = sector_cfg.mac_dst_address; - ofh_sector_config.mac_src_address = sector_cfg.mac_src_address; - ofh_sector_config.tci = sector_cfg.tci; - ofh_sector_config.tx_window_timing_params = sector_cfg.tx_window_timing_params; - ofh_sector_config.rx_window_timing_params = sector_cfg.rx_window_timing_params; - ofh_sector_config.cp = sector_cfg.cp; - ofh_sector_config.scs = sector_cfg.scs; - ofh_sector_config.bw = sector_cfg.bw; - ofh_sector_config.nof_antennas_ul = sector_cfg.nof_antennas_ul; + ofh_sector_config.logger = config.logger; + ofh_sector_config.transmitter_executor = sector_cfg.transmitter_executor; + ofh_sector_config.receiver_executor = sector_cfg.receiver_executor; + ofh_sector_config.downlink_executors = sector_cfg.downlink_executors; + ofh_sector_config.notifier = notifier; + ofh_sector_config.interface = sector_cfg.interface; + ofh_sector_config.is_promiscuous_mode_enabled = sector_cfg.is_promiscuous_mode_enabled; + ofh_sector_config.mac_dst_address = sector_cfg.mac_dst_address; + ofh_sector_config.mac_src_address = sector_cfg.mac_src_address; + ofh_sector_config.tci = sector_cfg.tci; + ofh_sector_config.tx_window_timing_params = sector_cfg.tx_window_timing_params; + ofh_sector_config.rx_window_timing_params = sector_cfg.rx_window_timing_params; + ofh_sector_config.cp = sector_cfg.cp; + ofh_sector_config.scs = sector_cfg.scs; + ofh_sector_config.bw = sector_cfg.bw; + ofh_sector_config.nof_antennas_ul = sector_cfg.nof_antennas_ul; ofh_sector_config.ru_operating_bw = sector_cfg.ru_operating_bw ? sector_cfg.ru_operating_bw.value() : sector_cfg.bw; ofh_sector_config.prach_eaxc = sector_cfg.prach_eaxc; ofh_sector_config.dl_eaxc = sector_cfg.dl_eaxc; From 3cefbe4544dd30274ffb49b1d971856dfda2f382 Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Thu, 19 Oct 2023 09:32:40 +0200 Subject: [PATCH 16/27] gnb: limit the number of PDSCH and PUSCH workers in zmq --- apps/gnb/gnb_appconfig_cli11_schema.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/apps/gnb/gnb_appconfig_cli11_schema.cpp b/apps/gnb/gnb_appconfig_cli11_schema.cpp index 8fe6c4619e..0bf24a0e65 100644 --- a/apps/gnb/gnb_appconfig_cli11_schema.cpp +++ b/apps/gnb/gnb_appconfig_cli11_schema.cpp @@ -1976,6 +1976,23 @@ static void manage_hal_optional(CLI::App& app, gnb_appconfig& gnb_cfg) } } +static void manage_expert_execution_threads(CLI::App& app, gnb_appconfig& gnb_cfg) +{ + if (!variant_holds_alternative(gnb_cfg.ru_cfg)) { + return; + } + + // Ignore the default settings based in the number of CPU cores for ZMQ. + if (variant_get(gnb_cfg.ru_cfg).device_driver == "zmq") { + upper_phy_threads_appconfig& upper = gnb_cfg.expert_execution_cfg.threads.upper_threads; + upper.nof_pdsch_threads = 1; + upper.nof_pusch_decoder_threads = 0; + upper.nof_ul_threads = 1; + upper.nof_dl_threads = 1; + gnb_cfg.expert_execution_cfg.threads.lower_threads.execution_profile = lower_phy_thread_profile::blocking; + } +} + void srsran::configure_cli11_with_gnb_appconfig_schema(CLI::App& app, gnb_appconfig& gnb_cfg) { app.add_option("--gnb_id", gnb_cfg.gnb_id, "gNodeB identifier")->capture_default_str(); @@ -2111,5 +2128,6 @@ void srsran::configure_cli11_with_gnb_appconfig_schema(CLI::App& app, gnb_appcon app.callback([&]() { manage_ru_variant(app, gnb_cfg, sdr_cfg, ofh_cfg); manage_hal_optional(app, gnb_cfg); + manage_expert_execution_threads(app, gnb_cfg); }); } From 11907c274ad40c825eadcea30e5c98913fe58643 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 17 Oct 2023 18:09:47 +0100 Subject: [PATCH 17/27] gtpu: make queue size configurable --- apps/gnb/gnb_appconfig.h | 6 ++++++ apps/gnb/gnb_appconfig_cli11_schema.cpp | 9 +++++++++ apps/gnb/gnb_worker_manager.cpp | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/gnb/gnb_appconfig.h b/apps/gnb/gnb_appconfig.h index fcefc86d0f..0413ae783f 100644 --- a/apps/gnb/gnb_appconfig.h +++ b/apps/gnb/gnb_appconfig.h @@ -656,6 +656,10 @@ struct cu_cp_appconfig { security_appconfig security_config; }; +struct cu_up_appconfig { + unsigned gtpu_queue_size = 2048; +}; + struct log_appconfig { std::string filename = "/tmp/gnb.log"; // Path to write log file or "stdout" to print to console. std::string all_level = "warning"; // Default log level for all layers. @@ -1052,6 +1056,8 @@ struct gnb_appconfig { amf_appconfig amf_cfg; /// CU-CP configuration. cu_cp_appconfig cu_cp_cfg; + /// CU-CP configuration. + cu_up_appconfig cu_up_cfg; /// \brief E2 configuration. e2_appconfig e2_cfg; /// Radio Unit configuration. diff --git a/apps/gnb/gnb_appconfig_cli11_schema.cpp b/apps/gnb/gnb_appconfig_cli11_schema.cpp index 0bf24a0e65..0c83ad57fa 100644 --- a/apps/gnb/gnb_appconfig_cli11_schema.cpp +++ b/apps/gnb/gnb_appconfig_cli11_schema.cpp @@ -376,6 +376,11 @@ static void configure_cli11_cu_cp_args(CLI::App& app, cu_cp_appconfig& cu_cp_par configure_cli11_security_args(*security_subcmd, cu_cp_params.security_config); } +static void configure_cli11_cu_up_args(CLI::App& app, cu_up_appconfig& cu_up_params) +{ + app.add_option("--gtpu_queue_size", cu_up_params.gtpu_queue_size, "GTP-U queue size, in PDUs")->capture_default_str(); +} + static void configure_cli11_expert_phy_args(CLI::App& app, expert_upper_phy_appconfig& expert_phy_params) { auto pusch_sinr_method_check = [](const std::string& value) -> std::string { @@ -2025,6 +2030,10 @@ void srsran::configure_cli11_with_gnb_appconfig_schema(CLI::App& app, gnb_appcon CLI::App* cu_cp_subcmd = app.add_subcommand("cu_cp", "CU-CP parameters")->configurable(); configure_cli11_cu_cp_args(*cu_cp_subcmd, gnb_cfg.cu_cp_cfg); + // CU-UP section + CLI::App* cu_up_subcmd = app.add_subcommand("cu_up", "CU-CP parameters")->configurable(); + configure_cli11_cu_up_args(*cu_up_subcmd, gnb_cfg.cu_up_cfg); + // NOTE: CLI11 needs that the life of the variable lasts longer than the call of this function. As both options need // to be added and a variant is used to store the Radio Unit configuration, the configuration is parsed in a helper // variable, but as it is requested later, the variable needs to be static. diff --git a/apps/gnb/gnb_worker_manager.cpp b/apps/gnb/gnb_worker_manager.cpp index a43e737502..b1d3080f3a 100644 --- a/apps/gnb/gnb_worker_manager.cpp +++ b/apps/gnb/gnb_worker_manager.cpp @@ -122,7 +122,7 @@ void worker_manager::create_du_cu_executors(const gnb_appconfig& appcfg) {{concurrent_queue_policy::lockfree_mpmc, task_worker_queue_size}, {concurrent_queue_policy::lockfree_mpmc, task_worker_queue_size}, // The IO-broker is currently single threaded, so we can use a SPSC. - {concurrent_queue_policy::lockfree_spsc, task_worker_queue_size}}, + {concurrent_queue_policy::lockfree_spsc, appcfg.cu_up_cfg.gtpu_queue_size}}, std::chrono::microseconds{200}, {{"ue_up_ctrl_exec", task_priority::max}, {"ue_ul_exec", task_priority::max - 1, false}, From bde1fe65e0179db22a78bd9bf4ef9486501faa6b Mon Sep 17 00:00:00 2001 From: asaezper Date: Thu, 19 Oct 2023 15:20:54 +0200 Subject: [PATCH 18/27] ci,e2e: allow failure some amari+b200 tests --- .gitlab/ci/e2e.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitlab/ci/e2e.yml b/.gitlab/ci/e2e.yml index 073e3b2098..2c18a13287 100644 --- a/.gitlab/ci/e2e.yml +++ b/.gitlab/ci/e2e.yml @@ -268,18 +268,21 @@ rf: variables: KEYWORDS: "not iperf" E2E_LOG_LEVEL: "info" + allow_failure: true rf-iperf-udp: extends: .rf variables: KEYWORDS: "iperf and udp" E2E_LOG_LEVEL: "info" + allow_failure: true rf-iperf-tcp: extends: .rf variables: KEYWORDS: "iperf and tcp" E2E_LOG_LEVEL: "info" + allow_failure: true rf-tsan: extends: .rf @@ -289,6 +292,7 @@ rf-tsan: - job: "smoke tsan update cache" artifacts: true - *retina-needs + retry: 2 rf-asan: extends: .rf From a751a6d2df3f5261bcb2a9f4f0cc52bb49cc8eed Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 19 Oct 2023 12:05:03 +0200 Subject: [PATCH 19/27] cu-cp: stop() cu-cp from within cu-cp executor --- apps/gnb/gnb.cpp | 3 +++ include/srsran/cu_cp/cu_cp.h | 1 + lib/cu_cp/cu_cp_impl.cpp | 25 ++++++++++++++++++++++++- lib/cu_cp/cu_cp_impl.h | 4 ++-- 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/apps/gnb/gnb.cpp b/apps/gnb/gnb.cpp index 513736c78b..9b233a32d0 100644 --- a/apps/gnb/gnb.cpp +++ b/apps/gnb/gnb.cpp @@ -549,6 +549,9 @@ int main(int argc, char** argv) // Stop CU-UP activity. cu_up_obj->stop(); + // Stop CU-CP activity. + cu_cp_obj->stop(); + if (not gnb_cfg.amf_cfg.no_core) { gnb_logger.info("Closing network connections..."); ngap_adapter->disconnect_gateway(); diff --git a/include/srsran/cu_cp/cu_cp.h b/include/srsran/cu_cp/cu_cp.h index a23801fd81..21c631fa96 100644 --- a/include/srsran/cu_cp/cu_cp.h +++ b/include/srsran/cu_cp/cu_cp.h @@ -80,6 +80,7 @@ class cu_cp_interface : public cu_cp_ngap_connection_interface, virtual cu_cp_cu_up_connection_interface& get_cu_cp_cu_up_connection_interface() = 0; virtual void start() = 0; + virtual void stop() = 0; }; } // namespace srs_cu_cp diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index 08b28d6a1c..bd7b88974b 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -112,7 +112,30 @@ void cu_cp_impl::start() } } -void cu_cp_impl::stop() {} +void cu_cp_impl::stop() +{ + logger.info("Stopping CU-CP..."); + std::promise p; + std::future fut = p.get_future(); + + // Shut down components from within CU-CP executor. + while (not cfg.cu_cp_executor->execute([this, &p]() { + statistics_report_timer.stop(); + + routine_mng.reset(); + + // Signal back that CU-CP is stopped. + p.set_value(); + })) { + // Keep dispatching until the task is accepted. + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + // Block waiting for CU-CP stop to complete. + fut.wait(); + + logger.info("CU-CP stopped successfully."); +} size_t cu_cp_impl::get_nof_cu_ups() const { diff --git a/lib/cu_cp/cu_cp_impl.h b/lib/cu_cp/cu_cp_impl.h index b1932a315d..dfe886b256 100644 --- a/lib/cu_cp/cu_cp_impl.h +++ b/lib/cu_cp/cu_cp_impl.h @@ -39,10 +39,10 @@ class cu_cp_impl final : public cu_cp_interface, public cu_cp_impl_interface { public: explicit cu_cp_impl(const cu_cp_configuration& config_); - ~cu_cp_impl(); + ~cu_cp_impl() override; void start() override; - void stop(); + void stop() override; // CU-CP CU-UP interface size_t get_nof_cu_ups() const override; From 512368a6d7fe628b0748df0685dc31d72f32cd89 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 19 Oct 2023 16:33:09 +0200 Subject: [PATCH 20/27] cu-cp: avoid that cu-cp stop task runs more than once --- lib/cu_cp/cu_cp_impl.cpp | 9 +++++++-- lib/cu_cp/cu_cp_impl.h | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/cu_cp/cu_cp_impl.cpp b/lib/cu_cp/cu_cp_impl.cpp index bd7b88974b..3158ea0a3f 100644 --- a/lib/cu_cp/cu_cp_impl.cpp +++ b/lib/cu_cp/cu_cp_impl.cpp @@ -114,19 +114,24 @@ void cu_cp_impl::start() void cu_cp_impl::stop() { + bool already_stopped = stopped.exchange(true); + if (already_stopped) { + return; + } + logger.info("Stopping CU-CP..."); std::promise p; std::future fut = p.get_future(); // Shut down components from within CU-CP executor. while (not cfg.cu_cp_executor->execute([this, &p]() { + // Stop statistics gathering. statistics_report_timer.stop(); - routine_mng.reset(); - // Signal back that CU-CP is stopped. p.set_value(); })) { + logger.debug("Failed to dispatch CU-CP stop task. Retrying..."); // Keep dispatching until the task is accepted. std::this_thread::sleep_for(std::chrono::milliseconds(100)); } diff --git a/lib/cu_cp/cu_cp_impl.h b/lib/cu_cp/cu_cp_impl.h index dfe886b256..7c79bde4bb 100644 --- a/lib/cu_cp/cu_cp_impl.h +++ b/lib/cu_cp/cu_cp_impl.h @@ -170,6 +170,8 @@ class cu_cp_impl final : public cu_cp_interface, public cu_cp_impl_interface std::atomic amf_connected = {false}; unique_timer statistics_report_timer; + + std::atomic stopped{false}; }; } // namespace srs_cu_cp From 5df5125cc7ef25adc0c753afe8c046a7412b196f Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 6 Oct 2023 14:07:49 +0100 Subject: [PATCH 21/27] rlc: add queue size configuration parameters --- apps/gnb/gnb_appconfig.h | 3 ++- apps/gnb/gnb_appconfig_cli11_schema.cpp | 13 ++++++++----- apps/gnb/gnb_appconfig_translators.cpp | 2 ++ include/srsran/du/du_cell_config_helpers.h | 3 +++ include/srsran/rlc/rlc_config.h | 7 +++++-- lib/du_manager/converters/rlc_config_helpers.cpp | 1 + lib/rlc/rlc_tx_am_entity.cpp | 1 + lib/rlc/rlc_tx_um_entity.cpp | 1 + tests/unittests/rlc/rlc_tx_am_test.cpp | 1 + tests/unittests/rlc/rlc_um_test.cpp | 1 + 10 files changed, 25 insertions(+), 8 deletions(-) diff --git a/apps/gnb/gnb_appconfig.h b/apps/gnb/gnb_appconfig.h index 0413ae783f..3f39e75a78 100644 --- a/apps/gnb/gnb_appconfig.h +++ b/apps/gnb/gnb_appconfig.h @@ -484,7 +484,7 @@ struct cell_appconfig { /// RLC UM TX configuration struct rlc_tx_um_appconfig { uint16_t sn_field_length; ///< Number of bits used for sequence number - int32_t t_reassembly; ///< Timer used by rx to detect PDU loss (ms) + uint32_t queue_size; ///< RLC SDU queue size }; /// RLC UM RX configuration @@ -507,6 +507,7 @@ struct rlc_tx_am_appconfig { int32_t poll_pdu; ///< Insert poll bit after this many PDUs int32_t poll_byte; ///< Insert poll bit after this much data (bytes) uint32_t max_window = 0; ///< Custom parameter to limit the maximum window size for memory reasons. 0 means no limit. + uint32_t queue_size = 4096; ///< RLC SDU queue size }; /// RLC UM RX configuration diff --git a/apps/gnb/gnb_appconfig_cli11_schema.cpp b/apps/gnb/gnb_appconfig_cli11_schema.cpp index 0c83ad57fa..82cebdfc65 100644 --- a/apps/gnb/gnb_appconfig_cli11_schema.cpp +++ b/apps/gnb/gnb_appconfig_cli11_schema.cpp @@ -1281,6 +1281,8 @@ static void configure_cli11_rlc_um_args(CLI::App& app, rlc_um_appconfig& rlc_um_ { CLI::App* rlc_tx_um_subcmd = app.add_subcommand("tx", "UM TX parameters"); rlc_tx_um_subcmd->add_option("--sn", rlc_um_params.tx.sn_field_length, "RLC UM TX SN")->capture_default_str(); + rlc_tx_um_subcmd->add_option("--queue-size", rlc_um_params.tx.queue_size, "RLC UM TX SDU queue size") + ->capture_default_str(); CLI::App* rlc_rx_um_subcmd = app.add_subcommand("rx", "UM TX parameters"); rlc_rx_um_subcmd->add_option("--sn", rlc_um_params.rx.sn_field_length, "RLC UM RX SN")->capture_default_str(); rlc_rx_um_subcmd->add_option("--t-reassembly", rlc_um_params.rx.t_reassembly, "RLC UM t-Reassembly") @@ -1297,11 +1299,12 @@ static void configure_cli11_rlc_am_args(CLI::App& app, rlc_am_appconfig& rlc_am_ ->capture_default_str(); rlc_tx_am_subcmd->add_option("--poll-pdu", rlc_am_params.tx.poll_pdu, "RLC AM TX PollPdu")->capture_default_str(); rlc_tx_am_subcmd->add_option("--poll-byte", rlc_am_params.tx.poll_byte, "RLC AM TX PollByte")->capture_default_str(); - rlc_tx_am_subcmd - ->add_option("--max_window", - rlc_am_params.tx.max_window, - "Non-standard parameter that limits the tx window size. Can be used for limiting memory usage with " - "large windows. 0 means no limits other than the SN size (i.e. 2^[sn_size-1]).") + rlc_tx_am_subcmd->add_option( + "--max_window", + rlc_am_params.tx.max_window, + "Non-standard parameter that limits the tx window size. Can be used for limiting memory usage with " + "large windows. 0 means no limits other than the SN size (i.e. 2^[sn_size-1])."); + rlc_tx_am_subcmd->add_option("--queue-size", rlc_am_params.tx.queue_size, "RLC AM TX SDU queue size") ->capture_default_str(); CLI::App* rlc_rx_am_subcmd = app.add_subcommand("rx", "AM RX parameters"); rlc_rx_am_subcmd->add_option("--sn", rlc_am_params.rx.sn_field_length, "RLC AM RX SN")->capture_default_str(); diff --git a/apps/gnb/gnb_appconfig_translators.cpp b/apps/gnb/gnb_appconfig_translators.cpp index 48da679ad1..178bc96442 100644 --- a/apps/gnb/gnb_appconfig_translators.cpp +++ b/apps/gnb/gnb_appconfig_translators.cpp @@ -865,6 +865,7 @@ std::map srsran::generate_du_qos_config(const gnb_appc if (!from_number(out_rlc.um.tx.sn_field_length, qos.rlc.um.tx.sn_field_length)) { report_error("Invalid RLC UM TX SN: 5QI={}, SN={}\n", qos.five_qi, qos.rlc.um.tx.sn_field_length); } + out_rlc.um.tx.queue_size = qos.rlc.um.tx.queue_size; } else if (out_rlc.mode == rlc_mode::am) { // AM Config //< TX SN @@ -876,6 +877,7 @@ std::map srsran::generate_du_qos_config(const gnb_appc out_rlc.am.tx.poll_pdu = qos.rlc.am.tx.poll_pdu; out_rlc.am.tx.poll_byte = qos.rlc.am.tx.poll_byte; out_rlc.am.tx.max_window = qos.rlc.am.tx.max_window; + out_rlc.am.tx.queue_size = qos.rlc.am.tx.queue_size; //< RX SN if (!from_number(out_rlc.am.rx.sn_field_length, qos.rlc.am.rx.sn_field_length)) { report_error("Invalid RLC AM RX SN: 5QI={}, SN={}\n", qos.five_qi, qos.rlc.am.rx.sn_field_length); diff --git a/include/srsran/du/du_cell_config_helpers.h b/include/srsran/du/du_cell_config_helpers.h index 24eb92de00..fa5833b858 100644 --- a/include/srsran/du/du_cell_config_helpers.h +++ b/include/srsran/du/du_cell_config_helpers.h @@ -130,6 +130,7 @@ inline std::map make_default_du_qos_config_list(int rl cfg.rlc.um.tx.sn_field_length = rlc_um_sn_size::size12bits; cfg.rlc.um.rx.sn_field_length = rlc_um_sn_size::size12bits; cfg.rlc.um.rx.t_reassembly = 100; + cfg.rlc.um.tx.queue_size = 4096; cfg.rlc.metrics_period = std::chrono::milliseconds(rlc_metrics_report); // F1-U cfg.f1u.t_notify = 10; @@ -146,6 +147,8 @@ inline std::map make_default_du_qos_config_list(int rl cfg.rlc.am.tx.poll_pdu = 16; cfg.rlc.am.tx.poll_byte = 6500; cfg.rlc.am.tx.max_retx_thresh = 16; + cfg.rlc.am.tx.max_window = 0; + cfg.rlc.am.tx.queue_size = 4096; cfg.rlc.am.rx.sn_field_length = rlc_am_sn_size::size18bits; cfg.rlc.am.rx.t_reassembly = 40; cfg.rlc.am.rx.t_status_prohibit = 50; diff --git a/include/srsran/rlc/rlc_config.h b/include/srsran/rlc/rlc_config.h index 6f41a44565..5041b59769 100644 --- a/include/srsran/rlc/rlc_config.h +++ b/include/srsran/rlc/rlc_config.h @@ -156,6 +156,7 @@ struct rlc_tx_am_config { int32_t poll_byte; ///< Insert poll bit after this much data (bytes) // Custom non-standard parameters + uint32_t queue_size; ///< SDU queue size uint32_t max_window; ///< Custom parameter to limit the maximum window size for memory reasons. 0 means no limit. }; @@ -177,6 +178,7 @@ struct rlc_rx_um_config { /// Ref: 3GPP TS 38.322 v15.3.0 Section 7 struct rlc_tx_um_config { rlc_um_sn_size sn_field_length; ///< Number of bits used for sequence number + uint32_t queue_size; ///< SDU queue size }; /// \brief Configurable parameters for RLC UM @@ -303,7 +305,7 @@ struct formatter { template auto format(srsran::rlc_tx_um_config cfg, FormatContext& ctx) -> decltype(std::declval().out()) { - return format_to(ctx.out(), "tx_sn_size={}", cfg.sn_field_length); + return format_to(ctx.out(), "tx_sn_size={}, queue_size={}", cfg.sn_field_length, cfg.queue_size); } }; @@ -352,12 +354,13 @@ struct formatter { auto format(srsran::rlc_tx_am_config cfg, FormatContext& ctx) -> decltype(std::declval().out()) { return format_to(ctx.out(), - "tx_sn_size={} t_poll_retx={} max_retx={} poll_pdu={} poll_byte={} max_window={}", + "tx_sn_size={} t_poll_retx={} max_retx={} poll_pdu={} poll_byte={} queue_size={} max_window={}", cfg.sn_field_length, cfg.t_poll_retx, cfg.max_retx_thresh, cfg.poll_pdu, cfg.poll_byte, + cfg.queue_size, cfg.max_window); } }; diff --git a/lib/du_manager/converters/rlc_config_helpers.cpp b/lib/du_manager/converters/rlc_config_helpers.cpp index c819485d6d..2fcfb340cc 100644 --- a/lib/du_manager/converters/rlc_config_helpers.cpp +++ b/lib/du_manager/converters/rlc_config_helpers.cpp @@ -22,6 +22,7 @@ rlc_config srsran::srs_du::make_default_srb_rlc_config() cfg.am.tx.poll_pdu = -1; cfg.am.tx.poll_byte = -1; cfg.am.tx.max_retx_thresh = 8; + cfg.am.tx.queue_size = 256; cfg.am.rx.sn_field_length = rlc_am_sn_size::size12bits; cfg.am.rx.t_reassembly = 35; cfg.am.rx.t_status_prohibit = 0; diff --git a/lib/rlc/rlc_tx_am_entity.cpp b/lib/rlc/rlc_tx_am_entity.cpp index 064fc05afe..1121b39375 100644 --- a/lib/rlc/rlc_tx_am_entity.cpp +++ b/lib/rlc/rlc_tx_am_entity.cpp @@ -29,6 +29,7 @@ rlc_tx_am_entity::rlc_tx_am_entity(du_ue_index_t du_index task_executor& ue_executor_) : rlc_tx_entity(du_index, rb_id, upper_dn_, upper_cn_, lower_dn_), cfg(config), + sdu_queue(cfg.queue_size), retx_queue(window_size(to_number(cfg.sn_field_length))), mod(cardinality(to_number(cfg.sn_field_length))), am_window_size(window_size(to_number(cfg.sn_field_length))), diff --git a/lib/rlc/rlc_tx_um_entity.cpp b/lib/rlc/rlc_tx_um_entity.cpp index 2e605a275d..7e3946032e 100644 --- a/lib/rlc/rlc_tx_um_entity.cpp +++ b/lib/rlc/rlc_tx_um_entity.cpp @@ -23,6 +23,7 @@ rlc_tx_um_entity::rlc_tx_um_entity(du_ue_index_t du_index task_executor& pcell_executor_) : rlc_tx_entity(du_index, rb_id, upper_dn_, upper_cn_, lower_dn_), cfg(config), + sdu_queue(cfg.queue_size), mod(cardinality(to_number(cfg.sn_field_length))), head_len_full(rlc_um_pdu_header_size_complete_sdu), head_len_first(rlc_um_pdu_header_size_no_so(cfg.sn_field_length)), diff --git a/tests/unittests/rlc/rlc_tx_am_test.cpp b/tests/unittests/rlc/rlc_tx_am_test.cpp index 2bd8acd350..373f526222 100644 --- a/tests/unittests/rlc/rlc_tx_am_test.cpp +++ b/tests/unittests/rlc/rlc_tx_am_test.cpp @@ -88,6 +88,7 @@ class rlc_tx_am_test : public ::testing::Test, public ::testing::WithParamInterf config.poll_pdu = 4; config.poll_byte = 25; config.max_window = 0; + config.queue_size = 4096; // Create test frame tester = std::make_unique(config.sn_field_length); diff --git a/tests/unittests/rlc/rlc_um_test.cpp b/tests/unittests/rlc/rlc_um_test.cpp index f706f82366..e30dd3802f 100644 --- a/tests/unittests/rlc/rlc_um_test.cpp +++ b/tests/unittests/rlc/rlc_um_test.cpp @@ -80,6 +80,7 @@ class rlc_um_test : public ::testing::Test, public ::testing::WithParamInterface // Set Tx config config.tx.sn_field_length = sn_size; + config.tx.queue_size = 4096; // Create RLC entities rlc1 = std::make_unique(du_ue_index_t::MIN_DU_UE_INDEX, From bab747e81871c9b93a640cdcb3b392b4dcfa0d5c Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 19 Oct 2023 15:15:55 +0200 Subject: [PATCH 22/27] mac: fix test mode initialization of test mode ue --- lib/du_high/mac_test_mode_adapter.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/du_high/mac_test_mode_adapter.cpp b/lib/du_high/mac_test_mode_adapter.cpp index c005dc59aa..1364659d92 100644 --- a/lib/du_high/mac_test_mode_adapter.cpp +++ b/lib/du_high/mac_test_mode_adapter.cpp @@ -161,7 +161,8 @@ class test_cell_adapter : public mac_cell_control_information_handler { static constexpr size_t CQI_BITLEN = 4; - if (ue_cfg_req.cells->empty() or not(*ue_cfg_req.cells)[0].serv_cell_cfg.csi_meas_cfg.has_value()) { + if (not ue_cfg_req.cells.has_value() or ue_cfg_req.cells->empty() or + not(*ue_cfg_req.cells)[0].serv_cell_cfg.csi_meas_cfg.has_value()) { return; } payload.resize(0); @@ -195,7 +196,7 @@ class test_cell_adapter : public mac_cell_control_information_handler mac_cell_control_information_handler& adapted; mac_pdu_handler& pdu_handler; std::function dl_bs_notifier; - sched_ue_config_request ue_cfg_req; + const sched_ue_config_request& ue_cfg_req; bool msg4_rx_flag = false; }; @@ -257,22 +258,25 @@ mac_test_mode_adapter::adapt_bearers(const std::vector mac_test_mode_adapter::handle_ue_create_request(const mac_ue_create_request& cfg) { - mac_ue_create_request cfg_adapted = cfg; - if (cfg_adapted.crnti == test_ue.rnti) { + if (cfg.crnti == test_ue.rnti) { // It is the test UE. + mac_ue_create_request cfg_copy = cfg; // Save UE index. - test_ue_index = cfg_adapted.ue_index; + test_ue_index = cfg_copy.ue_index; // Add adapters to the UE config bearers before passing it to MAC. - cfg_adapted.bearers = adapt_bearers(cfg.bearers); + cfg_copy.bearers = adapt_bearers(cfg.bearers); // Save config of test mode UE. - test_ue_cfg = cfg_adapted.sched_cfg; + test_ue_cfg = cfg_copy.sched_cfg; + + // Forward test UE creation request to MAC. + return mac_adapted->get_ue_configurator().handle_ue_create_request(cfg_copy); } - // Forward UE creation request to MAC. - return mac_adapted->get_ue_configurator().handle_ue_create_request(cfg_adapted); + // Forward normal UE creation request to MAC. + return mac_adapted->get_ue_configurator().handle_ue_create_request(cfg); } async_task From 58f000998b74da67dd1a155c335cad318e431db4 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 19 Oct 2023 15:25:57 +0200 Subject: [PATCH 23/27] mac: assert if the test UE is not correctly created --- lib/du_high/mac_test_mode_adapter.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/du_high/mac_test_mode_adapter.cpp b/lib/du_high/mac_test_mode_adapter.cpp index 1364659d92..0ff36240e9 100644 --- a/lib/du_high/mac_test_mode_adapter.cpp +++ b/lib/du_high/mac_test_mode_adapter.cpp @@ -79,6 +79,7 @@ class test_cell_adapter : public mac_cell_control_information_handler // It is not the test UE. continue; } + srsran_assert(ue_cfg_req.cells.has_value(), "CRC received for test mode which is not yet created"); // Force CRC=OK for test UE. crc.tb_crc_success = true; @@ -101,6 +102,7 @@ class test_cell_adapter : public mac_cell_control_information_handler // It is not the test UE. continue; } + srsran_assert(ue_cfg_req.cells.has_value(), "UCI received for test mode which is not yet created"); // In case of test UE, set HARQ-Info always equal to ACK. if (variant_holds_alternative(uci.pdu)) { @@ -161,8 +163,7 @@ class test_cell_adapter : public mac_cell_control_information_handler { static constexpr size_t CQI_BITLEN = 4; - if (not ue_cfg_req.cells.has_value() or ue_cfg_req.cells->empty() or - not(*ue_cfg_req.cells)[0].serv_cell_cfg.csi_meas_cfg.has_value()) { + if (ue_cfg_req.cells->empty() or not(*ue_cfg_req.cells)[0].serv_cell_cfg.csi_meas_cfg.has_value()) { return; } payload.resize(0); From 456e1b135e8a206a18300a2c802310b67c91010f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 19 Oct 2023 17:39:36 +0200 Subject: [PATCH 24/27] all: update readme and version --- CHANGELOG | 9 +++++++++ cmake/modules/version.cmake | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 0246ff61ec..4ebca2e22c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,15 @@ Change Log for Releases ======================= +## 23.10 + * Added downlink MIMO (up to 4 layers) + * Added Open Fronthaul (OFH) interface for split 7.2 ORAN radio units (optionally using DPDK) + * Added E2 interface including KPM and RAN control (RC) service model + * Added Timing Advance support + * Added Docker files + * Expose many more config parameters + * Other bug-fixes and improved stability and performance in all parts + ## 23.5 * Updated ASN.1 of RRC/NGAP/F1AP/E1AP to 3GPP Release 17.4 * Add UE capability transfer procedure diff --git a/cmake/modules/version.cmake b/cmake/modules/version.cmake index 7aa339a004..bdbd7434e4 100644 --- a/cmake/modules/version.cmake +++ b/cmake/modules/version.cmake @@ -7,6 +7,6 @@ # set(SRSRAN_VERSION_MAJOR 23) -set(SRSRAN_VERSION_MINOR 5) +set(SRSRAN_VERSION_MINOR 10) set(SRSRAN_VERSION_PATCH 0) set(SRSRAN_VERSION_STRING "${SRSRAN_VERSION_MAJOR}.${SRSRAN_VERSION_MINOR}.${SRSRAN_VERSION_PATCH}") \ No newline at end of file From 0fefca58d2065643c8c2c1776a8ceb0f56ecbbe4 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 19 Oct 2023 15:39:47 +0100 Subject: [PATCH 25/27] rlc: tune default rlc configs to be more agressive in getting status reports --- include/srsran/du/du_cell_config_helpers.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/srsran/du/du_cell_config_helpers.h b/include/srsran/du/du_cell_config_helpers.h index fa5833b858..8915d99b20 100644 --- a/include/srsran/du/du_cell_config_helpers.h +++ b/include/srsran/du/du_cell_config_helpers.h @@ -143,15 +143,15 @@ inline std::map make_default_du_qos_config_list(int rl // RLC cfg.rlc.mode = rlc_mode::am; cfg.rlc.am.tx.sn_field_length = rlc_am_sn_size::size18bits; - cfg.rlc.am.tx.t_poll_retx = 100; + cfg.rlc.am.tx.t_poll_retx = 20; cfg.rlc.am.tx.poll_pdu = 16; - cfg.rlc.am.tx.poll_byte = 6500; - cfg.rlc.am.tx.max_retx_thresh = 16; + cfg.rlc.am.tx.poll_byte = -1; + cfg.rlc.am.tx.max_retx_thresh = 32; cfg.rlc.am.tx.max_window = 0; cfg.rlc.am.tx.queue_size = 4096; cfg.rlc.am.rx.sn_field_length = rlc_am_sn_size::size18bits; - cfg.rlc.am.rx.t_reassembly = 40; - cfg.rlc.am.rx.t_status_prohibit = 50; + cfg.rlc.am.rx.t_reassembly = 20; + cfg.rlc.am.rx.t_status_prohibit = 10; cfg.rlc.metrics_period = std::chrono::milliseconds(rlc_metrics_report); // F1-U cfg.f1u.t_notify = 10; From 7bcfaaea0c536cb03718274df103ef5a180cb4a4 Mon Sep 17 00:00:00 2001 From: Supreeth Herle Date: Thu, 19 Oct 2023 14:50:12 +0200 Subject: [PATCH 26/27] app: set default PRACH index for FDD and TDD --- apps/gnb/gnb_appconfig_translators.cpp | 13 ++++--------- apps/gnb/gnb_appconfig_validators.cpp | 2 +- include/srsran/ran/prach/prach_helper.h | 6 ++++-- lib/ran/prach/prach_helper.cpp | 6 ++++-- .../config/serving_cell_config_factory.cpp | 13 ++++++++----- 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/apps/gnb/gnb_appconfig_translators.cpp b/apps/gnb/gnb_appconfig_translators.cpp index 178bc96442..ae28eee341 100644 --- a/apps/gnb/gnb_appconfig_translators.cpp +++ b/apps/gnb/gnb_appconfig_translators.cpp @@ -1445,18 +1445,13 @@ static void derive_cell_auto_params(base_cell_appconfig& cell_cfg) cell_cfg.tdd_ul_dl_cfg->pattern1.nof_ul_symbols = 0; } - // If PRACH configuration Index not set, derive a valid one. + // If PRACH configuration Index not set, a default one is assigned. if (not cell_cfg.prach_cfg.prach_config_index.has_value()) { if (band_helper::get_duplex_mode(cell_cfg.band.value()) == duplex_mode::FDD) { - cell_cfg.prach_cfg.prach_config_index = 1; + cell_cfg.prach_cfg.prach_config_index = 16; } else { - // TDD case. Ensure the PRACH falls in UL slots. - optional index_found = prach_helper::find_valid_prach_config_index( - cell_cfg.common_scs, generate_tdd_pattern(cell_cfg.common_scs, cell_cfg.tdd_ul_dl_cfg.value())); - if (not index_found.has_value()) { - report_error("Failed to auto-derive PRACH configuration index"); - } - cell_cfg.prach_cfg.prach_config_index = *index_found; + // Valid for TDD period of 5 ms. And, PRACH index 159 is well tested. + cell_cfg.prach_cfg.prach_config_index = 159; } } } diff --git a/apps/gnb/gnb_appconfig_validators.cpp b/apps/gnb/gnb_appconfig_validators.cpp index b5e4a9fa90..bcf12e2619 100644 --- a/apps/gnb/gnb_appconfig_validators.cpp +++ b/apps/gnb/gnb_appconfig_validators.cpp @@ -206,7 +206,7 @@ static bool validate_pucch_cell_app_config(const base_cell_appconfig& config) /// Validates the given PRACH cell application configuration. Returns true on success, otherwise false. static bool validate_prach_cell_app_config(const prach_appconfig& config, nr_band band) { - srsran_assert(config.prach_config_index.has_value(), "The PRACH configuration index must be set or auto-derived."); + srsran_assert(config.prach_config_index.has_value(), "The PRACH configuration index must be set."); auto code = prach_helper::prach_config_index_is_valid(config.prach_config_index.value(), band_helper::get_duplex_mode(band)); diff --git a/include/srsran/ran/prach/prach_helper.h b/include/srsran/ran/prach/prach_helper.h index 2cf19dfdf7..f54c381adb 100644 --- a/include/srsran/ran/prach/prach_helper.h +++ b/include/srsran/ran/prach/prach_helper.h @@ -38,7 +38,9 @@ error_type> prach_fits_in_tdd_pattern(subcarrier_spacing pusch_scs, uint8_t prach_cfg_idx, const tdd_ul_dl_config_common& tdd_cfg); /// \brief Finds a PRACH configuration index that ensures that PRACH falls in an TDD UL slot. -optional find_valid_prach_config_index(subcarrier_spacing pusch_scs, const tdd_ul_dl_config_common& tdd_cfg); +optional find_valid_prach_config_index(subcarrier_spacing pusch_scs, + uint8_t zero_correlation_zone, + const tdd_ul_dl_config_common& tdd_cfg); } // namespace prach_helper -} // namespace srsran \ No newline at end of file +} // namespace srsran diff --git a/lib/ran/prach/prach_helper.cpp b/lib/ran/prach/prach_helper.cpp index 51841e21c4..02734ada5b 100644 --- a/lib/ran/prach/prach_helper.cpp +++ b/lib/ran/prach/prach_helper.cpp @@ -54,7 +54,7 @@ error_type srsran::prach_helper::zero_correlation_zone_is_valid(uin if ((prach_config.format == prach_format_type::B4) && (zero_correlation_zone != 0) && (zero_correlation_zone != 14)) { return fmt::format( - "PRACH Zero Correlation Zone index (i.e., {}) with Format B4 is not supported for FDD. Use 0 or 14.\n", + "PRACH Zero Correlation Zone index (i.e., {}) with Format B4 is not supported for TDD. Use 0 or 14.\n", zero_correlation_zone); } } @@ -93,7 +93,8 @@ error_type> srsran::prach_helper::prach_fits_in_tdd_pattern(su return {}; } -optional srsran::prach_helper::find_valid_prach_config_index(subcarrier_spacing pusch_scs, +optional srsran::prach_helper::find_valid_prach_config_index(subcarrier_spacing pusch_scs, + uint8_t zero_correlation_zone, const tdd_ul_dl_config_common& tdd_cfg) { static constexpr size_t NOF_PRACH_CONFIG_INDEXES = 256; @@ -101,6 +102,7 @@ optional srsran::prach_helper::find_valid_prach_config_index(subcarrier // Iterate over different PRACH configuration indexes until a valid one is found. for (unsigned prach_cfg_idx = 0; prach_cfg_idx != NOF_PRACH_CONFIG_INDEXES; ++prach_cfg_idx) { if (prach_config_index_is_valid(prach_cfg_idx, duplex_mode::TDD).has_value() and + zero_correlation_zone_is_valid(zero_correlation_zone, prach_cfg_idx, duplex_mode::TDD).has_value() and prach_fits_in_tdd_pattern(pusch_scs, prach_cfg_idx, tdd_cfg).has_value()) { return prach_cfg_idx; } diff --git a/lib/scheduler/config/serving_cell_config_factory.cpp b/lib/scheduler/config/serving_cell_config_factory.cpp index 86716b51ac..4a8739487c 100644 --- a/lib/scheduler/config/serving_cell_config_factory.cpp +++ b/lib/scheduler/config/serving_cell_config_factory.cpp @@ -338,10 +338,13 @@ srsran::config_helpers::make_default_ul_config_common(const cell_config_builder_ cfg.freq_info_ul.freq_band_list.back().band = *params.band; cfg.init_ul_bwp.generic_params = make_default_init_bwp(params); cfg.init_ul_bwp.rach_cfg_common.emplace(); - cfg.init_ul_bwp.rach_cfg_common->rach_cfg_generic.prach_config_index = 1; + cfg.init_ul_bwp.rach_cfg_common->rach_cfg_generic.zero_correlation_zone_config = 15; + cfg.init_ul_bwp.rach_cfg_common->rach_cfg_generic.prach_config_index = 16; if (band_helper::get_duplex_mode(params.band.value()) == duplex_mode::TDD) { - optional idx_found = - prach_helper::find_valid_prach_config_index(params.scs_common, *params.tdd_ul_dl_cfg_common); + optional idx_found = prach_helper::find_valid_prach_config_index( + params.scs_common, + cfg.init_ul_bwp.rach_cfg_common->rach_cfg_generic.zero_correlation_zone_config, + *params.tdd_ul_dl_cfg_common); srsran_assert(idx_found.has_value(), "Unable to find a PRACH config index for the given TDD pattern"); cfg.init_ul_bwp.rach_cfg_common->rach_cfg_generic.prach_config_index = idx_found.value(); } @@ -365,8 +368,8 @@ srsran::config_helpers::make_default_ul_config_common(const cell_config_builder_ cfg.init_ul_bwp.rach_cfg_common->msg3_transform_precoder = false; cfg.init_ul_bwp.rach_cfg_common->rach_cfg_generic.msg1_fdm = 1; // Add +3 PRBS to the MSG1 frequency start, which act as a guardband between the PUCCH and PRACH. - cfg.init_ul_bwp.rach_cfg_common->rach_cfg_generic.msg1_frequency_start = 6; - cfg.init_ul_bwp.rach_cfg_common->rach_cfg_generic.zero_correlation_zone_config = 15; + cfg.init_ul_bwp.rach_cfg_common->rach_cfg_generic.msg1_frequency_start = 6; + cfg.init_ul_bwp.rach_cfg_common->rach_cfg_generic.ra_resp_window = 10U << to_numerology_value(params.scs_common); cfg.init_ul_bwp.rach_cfg_common->rach_cfg_generic.preamble_rx_target_pw = -100; cfg.init_ul_bwp.pusch_cfg_common.emplace(); From 549661c438dd8664b81449d8892734ca21a7ccf6 Mon Sep 17 00:00:00 2001 From: Alejandro Leal Date: Fri, 20 Oct 2023 13:45:48 +0200 Subject: [PATCH 27/27] gnb: updated the default max proc delay property based on the duplex mode. Updated the iq_scaling parameter for the Benetel and Foxconn RUs --- apps/gnb/gnb_appconfig_cli11_schema.cpp | 26 ++++++++++++++++++++ configs/gnb_ru_picocom_scb_tdd_n78_20mhz.yml | 2 +- configs/gnb_ru_ran550_tdd_n78_100mhz_2x2.yml | 2 +- configs/gnb_ru_ran550_tdd_n78_20mhz.yml | 2 +- configs/gnb_ru_rpqn4800e_tdd_n78_20mhz.yml | 2 +- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/apps/gnb/gnb_appconfig_cli11_schema.cpp b/apps/gnb/gnb_appconfig_cli11_schema.cpp index 82cebdfc65..d749cd4a9f 100644 --- a/apps/gnb/gnb_appconfig_cli11_schema.cpp +++ b/apps/gnb/gnb_appconfig_cli11_schema.cpp @@ -10,6 +10,7 @@ #include "gnb_appconfig_cli11_schema.h" #include "gnb_appconfig.h" +#include "srsran/ran/duplex_mode.h" #include "srsran/ran/pdsch/pdsch_mcs.h" #include "srsran/support/cli11_utils.h" #include "srsran/support/config_parsers.h" @@ -2001,6 +2002,30 @@ static void manage_expert_execution_threads(CLI::App& app, gnb_appconfig& gnb_cf } } +static void manage_processing_delay(CLI::App& app, gnb_appconfig& gnb_cfg) +{ + // If max proc delay property is present in the config, do nothing. + CLI::App* expert_cmd = app.get_subcommand("expert_phy"); + if (expert_cmd->count_all() >= 1 && expert_cmd->count("--max_proc_delay") >= 1) { + return; + } + + // As processing delay is not cell related, use the first cell to update the value. + const auto& cell = gnb_cfg.cells_cfg.front().cell; + nr_band band = cell.band ? cell.band.value() : band_helper::get_band_from_dl_arfcn(cell.dl_arfcn); + + switch (band_helper::get_duplex_mode(band)) { + case duplex_mode::TDD: + gnb_cfg.expert_phy_cfg.max_processing_delay_slots = 5; + break; + case duplex_mode::FDD: + gnb_cfg.expert_phy_cfg.max_processing_delay_slots = 2; + break; + default: + break; + } +} + void srsran::configure_cli11_with_gnb_appconfig_schema(CLI::App& app, gnb_appconfig& gnb_cfg) { app.add_option("--gnb_id", gnb_cfg.gnb_id, "gNodeB identifier")->capture_default_str(); @@ -2141,5 +2166,6 @@ void srsran::configure_cli11_with_gnb_appconfig_schema(CLI::App& app, gnb_appcon manage_ru_variant(app, gnb_cfg, sdr_cfg, ofh_cfg); manage_hal_optional(app, gnb_cfg); manage_expert_execution_threads(app, gnb_cfg); + manage_processing_delay(app, gnb_cfg); }); } diff --git a/configs/gnb_ru_picocom_scb_tdd_n78_20mhz.yml b/configs/gnb_ru_picocom_scb_tdd_n78_20mhz.yml index 1ea45b73b8..a40a8f03b9 100644 --- a/configs/gnb_ru_picocom_scb_tdd_n78_20mhz.yml +++ b/configs/gnb_ru_picocom_scb_tdd_n78_20mhz.yml @@ -20,7 +20,7 @@ ru_ofh: compr_bitwidth_dl: 9 # Downlink IQ samples bitwidth after compression. compr_method_prach: bfp # PRACH compression method. compr_bitwidth_prach: 9 # PRACH IQ samples bitwidth after compression. - iq_scaling: 1.0 # IQ samples scaling factor applied before compression, should be a positive value smaller than 1. + iq_scaling: 1.0 # IQ samples scaling factor applied before compression, should be a positive value smaller than 10. cells: - network_interface: enp1s0f0 # Ethernet interface name used to communicate with the RU. ru_mac_addr: ce:fc:6c:09:a6:cd # RU MAC address. diff --git a/configs/gnb_ru_ran550_tdd_n78_100mhz_2x2.yml b/configs/gnb_ru_ran550_tdd_n78_100mhz_2x2.yml index 4a2fd99d0d..37cd0ca795 100644 --- a/configs/gnb_ru_ran550_tdd_n78_100mhz_2x2.yml +++ b/configs/gnb_ru_ran550_tdd_n78_100mhz_2x2.yml @@ -23,7 +23,7 @@ ru_ofh: compr_bitwidth_prach: 9 # PRACH IQ samples bitwidth after compression. enable_ul_static_compr_hdr: true # Configures if the compression header is present for uplink User-Plane messages (false) or not present (true). enable_dl_static_compr_hdr: true # Configures if the compression header is present for downlink User-Plane messages (false) or not present (true). - iq_scaling: 0.10 # IQ samples scaling factor applied before compression, should be a positive value smaller than 1. + iq_scaling: 5.5 # IQ samples scaling factor applied before compression, should be a positive value smaller than 10. cells: - network_interface: enp1s0f0 # Ethernet interface name used to communicate with the RU. ru_mac_addr: 70:b3:d5:e1:5b:06 # RU MAC address. diff --git a/configs/gnb_ru_ran550_tdd_n78_20mhz.yml b/configs/gnb_ru_ran550_tdd_n78_20mhz.yml index 16dfb8784e..7991292553 100644 --- a/configs/gnb_ru_ran550_tdd_n78_20mhz.yml +++ b/configs/gnb_ru_ran550_tdd_n78_20mhz.yml @@ -24,7 +24,7 @@ ru_ofh: compr_bitwidth_dl: 9 # Downlink IQ samples bitwidth after compression. enable_ul_static_compr_hdr: true # Configures if the compression header is present for uplink User-Plane messages (false) or not present (true). enable_dl_static_compr_hdr: true # Configures if the compression header is present for downlink User-Plane messages (false) or not present (true). - iq_scaling: 0.27 # IQ samples scaling factor applied before compression, should be a positive value smaller than 1. + iq_scaling: 5.5 # IQ samples scaling factor applied before compression, should be a positive value smaller than 10. cells: - network_interface: enp1s0f0 # Ethernet interface name used to communicate with the RU. ru_mac_addr: 70:b3:d5:e1:5b:06 # RU MAC address. diff --git a/configs/gnb_ru_rpqn4800e_tdd_n78_20mhz.yml b/configs/gnb_ru_rpqn4800e_tdd_n78_20mhz.yml index 638ca89b42..c7a69839e7 100644 --- a/configs/gnb_ru_rpqn4800e_tdd_n78_20mhz.yml +++ b/configs/gnb_ru_rpqn4800e_tdd_n78_20mhz.yml @@ -27,7 +27,7 @@ ru_ofh: compr_bitwidth_prach: 9 # PRACH IQ samples bitwidth after compression. enable_ul_static_compr_hdr: false # Configures if the compression header is present for uplink User-Plane messages (false) or not present (true). enable_dl_static_compr_hdr: false # Configures if the compression header is present for downlink User-Plane messages (false) or not present (true). - iq_scaling: 1.0 # IQ samples scaling factor applied before compression, should be a positive value smaller than 1. + iq_scaling: 0.8 # IQ samples scaling factor applied before compression, should be a positive value smaller than 10. cells: - network_interface: enp1s0f1 # Ethernet interface name used to communicate with the RU. ru_mac_addr: 6c:ad:ad:00:08:c4 # RU MAC address.