From b6ea78dfd351253b483fc8313feb887b39962e59 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 5 Oct 2021 17:22:36 +0200 Subject: [PATCH] Fix gNb PHY-Stack UL-DL time paradox (#3365) * Fix gNb PHY-Stack UL-DL time paradox * Fix clang compilation --- srsenb/hdr/phy/nr/slot_worker.h | 24 +++++++++++++++++++++++- srsenb/hdr/phy/nr/worker_pool.h | 7 ++++++- srsenb/src/phy/nr/slot_worker.cc | 19 ++++++++++++++++--- srsenb/src/phy/nr/worker_pool.cc | 5 ++++- test/phy/dummy_gnb_stack.h | 13 ++----------- test/phy/dummy_rx_harq_proc.h | 2 +- test/phy/dummy_ue_stack.h | 16 +++++++++++++--- test/phy/nr_phy_test.cc | 2 +- 8 files changed, 66 insertions(+), 22 deletions(-) diff --git a/srsenb/hdr/phy/nr/slot_worker.h b/srsenb/hdr/phy/nr/slot_worker.h index 7222e553a..3bb515dbe 100644 --- a/srsenb/hdr/phy/nr/slot_worker.h +++ b/srsenb/hdr/phy/nr/slot_worker.h @@ -31,6 +31,24 @@ namespace nr { class slot_worker final : public srsran::thread_pool::worker { public: + /** + * @brief Slot worker synchronization interface + */ + class sync_interface + { + public: + /** + * @brief Wait for the worker to start DL scheduler + * @param w Worker pointer + */ + virtual void wait(slot_worker* w) = 0; + + /** + * @brief Releases the current worker + */ + virtual void release() = 0; + }; + struct args_t { uint32_t cell_index = 0; uint32_t nof_max_prb = SRSRAN_MAX_PRB_NR; @@ -42,7 +60,10 @@ public: double srate_hz = 0.0; }; - slot_worker(srsran::phy_common_interface& common_, stack_interface_phy_nr& stack_, srslog::basic_logger& logger); + slot_worker(srsran::phy_common_interface& common_, + stack_interface_phy_nr& stack_, + sync_interface& sync_, + srslog::basic_logger& logger); ~slot_worker(); bool init(const args_t& args); @@ -78,6 +99,7 @@ private: srsran::phy_common_interface& common; stack_interface_phy_nr& stack; srslog::basic_logger& logger; + sync_interface& sync; uint32_t sf_len = 0; uint32_t cell_index = 0; diff --git a/srsenb/hdr/phy/nr/worker_pool.h b/srsenb/hdr/phy/nr/worker_pool.h index 2bcbe704e..300c43fc4 100644 --- a/srsenb/hdr/phy/nr/worker_pool.h +++ b/srsenb/hdr/phy/nr/worker_pool.h @@ -17,15 +17,20 @@ #include "srsenb/hdr/phy/phy_interfaces.h" #include "srsenb/hdr/phy/prach_worker.h" #include "srsran/common/thread_pool.h" +#include "srsran/common/tti_sempahore.h" #include "srsran/interfaces/enb_mac_interfaces.h" #include "srsran/interfaces/gnb_interfaces.h" namespace srsenb { namespace nr { -class worker_pool +class worker_pool final : private slot_worker::sync_interface { private: + srsran::tti_semaphore slot_sync; ///< Slot synchronization semaphore + void wait(slot_worker* w) override { slot_sync.wait(w); } + void release() override { slot_sync.release(); } + class prach_stack_adaptor_t : public stack_interface_phy_lte { private: diff --git a/srsenb/src/phy/nr/slot_worker.cc b/srsenb/src/phy/nr/slot_worker.cc index a75e010aa..c0fcb4827 100644 --- a/srsenb/src/phy/nr/slot_worker.cc +++ b/srsenb/src/phy/nr/slot_worker.cc @@ -18,8 +18,9 @@ namespace srsenb { namespace nr { slot_worker::slot_worker(srsran::phy_common_interface& common_, stack_interface_phy_nr& stack_, + sync_interface& sync_, srslog::basic_logger& logger_) : - common(common_), stack(stack_), logger(logger_) + common(common_), stack(stack_), sync(sync_), logger(logger_) { // Do nothing } @@ -243,9 +244,18 @@ bool slot_worker::work_ul() bool slot_worker::work_dl() { + // The Scheduler interface needs to be called synchronously, wait for the sync to be available + sync.wait(this); + // Retrieve Scheduling for the current processing DL slot - stack_interface_phy_nr::dl_sched_t dl_sched = {}; - if (stack.get_dl_sched(dl_slot_cfg, dl_sched) < SRSRAN_SUCCESS) { + stack_interface_phy_nr::dl_sched_t dl_sched = {}; + bool dl_sched_fail = stack.get_dl_sched(dl_slot_cfg, dl_sched) < SRSRAN_SUCCESS; + + // Releases synchronization lock and allow next worker to retrieve scheduling results + sync.release(); + + // Abort if the scheduling failed + if (dl_sched_fail) { logger.error("Error retrieving DL scheduling"); return false; } @@ -367,6 +377,9 @@ void slot_worker::work_imp() // Process uplink if (not work_ul()) { + // Wait and release synchronization + sync.wait(this); + sync.release(); common.worker_end(context, false, tx_rf_buffer); return; } diff --git a/srsenb/src/phy/nr/worker_pool.cc b/srsenb/src/phy/nr/worker_pool.cc index fde8aa6a6..0563c6e1c 100644 --- a/srsenb/src/phy/nr/worker_pool.cc +++ b/srsenb/src/phy/nr/worker_pool.cc @@ -50,7 +50,7 @@ bool worker_pool::init(const args_t& args, const phy_cell_cfg_list_nr_t& cell_li log.set_level(log_level); log.set_hex_dump_max_size(args.log.phy_hex_limit); - auto w = new slot_worker(common, stack, log); + auto w = new slot_worker(common, stack, *this, log); pool.init_worker(i, w, args.prio); workers.push_back(std::unique_ptr(w)); @@ -74,6 +74,9 @@ bool worker_pool::init(const args_t& args, const phy_cell_cfg_list_nr_t& cell_li void worker_pool::start_worker(slot_worker* w) { + // Push worker into synchronization queue + slot_sync.push(w); + // Feed PRACH detection before start processing prach.new_tti(0, current_tti, w->get_buffer_rx(0)); diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index 546d0dbdb..83c7d7659 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -80,7 +80,6 @@ private: srsenb::rrc_nr_dummy rrc_obj; srsenb::rlc_dummy rlc_obj; std::unique_ptr mac; - srsran::slot_point pdsch_slot, pusch_slot; srslog::basic_logger& sched_logger; bool autofill_pdsch_bsr = false; @@ -441,11 +440,6 @@ public: { logger.set_context(slot_cfg.idx); sched_logger.set_context(slot_cfg.idx); - if (not pdsch_slot.valid()) { - pdsch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; - } else { - pdsch_slot++; - } if (not use_dummy_sched) { if (autofill_pdsch_bsr) { @@ -514,11 +508,6 @@ public: { logger.set_context(slot_cfg.idx); sched_logger.set_context(slot_cfg.idx); - if (not pusch_slot.valid()) { - pusch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; - } else { - pusch_slot++; - } if (not use_dummy_sched) { int ret = mac->get_ul_sched(slot_cfg, ul_sched); @@ -601,6 +590,7 @@ public: { if (not use_dummy_sched) { mac->pucch_info(slot_cfg, pucch_info); + return SRSRAN_SUCCESS; } // Handle UCI data @@ -615,6 +605,7 @@ public: } // Handle PHY metrics + std::unique_lock lock(metrics_mutex); metrics.pucch.epre_db_avg = SRSRAN_VEC_CMA(pucch_info.csi.epre_dB, metrics.pucch.epre_db_avg, metrics.pucch.count); metrics.pucch.epre_db_min = SRSRAN_MIN(metrics.pucch.epre_db_min, pucch_info.csi.epre_dB); metrics.pucch.epre_db_max = SRSRAN_MAX(metrics.pucch.epre_db_max, pucch_info.csi.epre_dB); diff --git a/test/phy/dummy_rx_harq_proc.h b/test/phy/dummy_rx_harq_proc.h index 064a927f8..9a7a918a6 100644 --- a/test/phy/dummy_rx_harq_proc.h +++ b/test/phy/dummy_rx_harq_proc.h @@ -25,7 +25,7 @@ class dummy_rx_harq_proc private: srsran::byte_buffer_t data; srsran_softbuffer_rx_t softbuffer = {}; - uint32_t tbs = {0}; + std::atomic tbs = {0}; bool first = true; uint32_t ndi = 0; diff --git a/test/phy/dummy_ue_stack.h b/test/phy/dummy_ue_stack.h index ea5fc307e..07254f1ee 100644 --- a/test/phy/dummy_ue_stack.h +++ b/test/phy/dummy_ue_stack.h @@ -28,6 +28,7 @@ public: }; private: + std::mutex rnti_mutex; srsran_rnti_type_t dl_rnti_type = srsran_rnti_type_c; uint16_t rnti = 0; bool valid = false; @@ -73,9 +74,17 @@ public: } } int sf_indication(const uint32_t tti) override { return 0; } - sched_rnti_t get_dl_sched_rnti_nr(const uint32_t tti) override { return {rnti, dl_rnti_type}; } - sched_rnti_t get_ul_sched_rnti_nr(const uint32_t tti) override { return {rnti, srsran_rnti_type_c}; } - void new_grant_dl(const uint32_t cc_idx, const mac_nr_grant_dl_t& grant, tb_action_dl_t* action) override + sched_rnti_t get_dl_sched_rnti_nr(const uint32_t tti) override + { + std::unique_lock lock(rnti_mutex); + return {rnti, dl_rnti_type}; + } + sched_rnti_t get_ul_sched_rnti_nr(const uint32_t tti) override + { + std::unique_lock lock(rnti_mutex); + return {rnti, srsran_rnti_type_c}; + } + void new_grant_dl(const uint32_t cc_idx, const mac_nr_grant_dl_t& grant, tb_action_dl_t* action) override { action->tb.enabled = true; action->tb.softbuffer = &rx_harq_proc[grant.pid].get_softbuffer(grant.ndi, grant.tbs); @@ -92,6 +101,7 @@ public: } void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id) override { + std::unique_lock lock(rnti_mutex); dl_rnti_type = srsran_rnti_type_ra; rnti = 1 + s_id + 14 * t_id + 14 * 80 * f_id + 14 * 80 * 8 * ul_carrier_id; } diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc index 2e7959e99..3303e9402 100644 --- a/test/phy/nr_phy_test.cc +++ b/test/phy/nr_phy_test.cc @@ -30,7 +30,7 @@ test_bench::args_t::args_t(int argc, char** argv) bpo::options_description options_ue_stack("UE stack options"); bpo::options_description options_ue_phy("UE stack options"); - uint16_t rnti = 0x1234; + uint16_t rnti = 17921; gnb_stack.pdsch.slots = "0,1,2,3,4,5"; gnb_stack.pusch.slots = "6,7,8,9";