From e5e047bc6368f7b458ad24bda7078555cdf24e53 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 29 Oct 2021 15:02:20 +0100 Subject: [PATCH] nr,gnb,sched: avoid that the nr sched handles the rach before it creates the ue object --- srsenb/hdr/stack/mac/nr/sched_nr.h | 3 +- srsenb/hdr/stack/mac/nr/sched_nr_worker.h | 2 + srsenb/src/stack/mac/nr/mac_nr.cc | 6 +-- srsenb/src/stack/mac/nr/sched_nr.cc | 51 +++++++++++++++++----- srsenb/src/stack/mac/nr/sched_nr_worker.cc | 5 +++ srsenb/test/mac/nr/sched_nr_sim_ue.cc | 3 +- 6 files changed, 52 insertions(+), 18 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr.h b/srsenb/hdr/stack/mac/nr/sched_nr.h index b1167309a..0eae3c7dc 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr.h @@ -44,7 +44,7 @@ public: void ue_cfg(uint16_t rnti, const ue_cfg_t& cfg) override; void ue_rem(uint16_t rnti) override; - int dl_rach_info(uint32_t cc, const rar_info_t& rar_info); + int dl_rach_info(const rar_info_t& rar_info, const ue_cfg_t& uecfg); void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) override; void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) override; @@ -61,6 +61,7 @@ public: private: void ue_cfg_impl(uint16_t rnti, const ue_cfg_t& cfg); + bool add_ue_impl(uint16_t rnti, std::unique_ptr u); // args sched_nr_impl::sched_params cfg; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_worker.h b/srsenb/hdr/stack/mac/nr/sched_nr_worker.h index a9318f3b7..4157fd215 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_worker.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_worker.h @@ -67,6 +67,8 @@ public: explicit cc_worker(const cell_params_t& params); + void dl_rach_info(const sched_nr_interface::rar_info_t& rar_info); + void run_slot(slot_point pdcch_slot, ue_map_t& ue_db_, dl_sched_res_t& dl_res, ul_sched_t& ul_res); // const params diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 0b0214256..fbcdd6490 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -161,7 +161,7 @@ void mac_nr::rach_detected(const rach_info_t& rach_info) sched_nr_ue_cfg_t uecfg = {}; uecfg.carriers.resize(1); uecfg.carriers[0].active = true; - uecfg.carriers[0].cc = 0; + uecfg.carriers[0].cc = enb_cc_idx; uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; srsran::phy_cfg_nr_default_t::reference_cfg_t ref_args{}; ref_args.duplex = cell_config[0].duplex.mode == SRSRAN_DUPLEX_MODE_TDD @@ -170,7 +170,7 @@ void mac_nr::rach_detected(const rach_info_t& rach_info) uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{ref_args}; uecfg.phy_cfg.csi = {}; // disable CSI until RA is complete - uint16_t rnti = reserve_rnti(enb_cc_idx, uecfg); + uint16_t rnti = alloc_ue(enb_cc_idx); // Log this event. ++detected_rachs[enb_cc_idx]; @@ -182,7 +182,7 @@ void mac_nr::rach_detected(const rach_info_t& rach_info) rar_info.ta_cmd = rach_info.time_adv; rar_info.prach_slot = slot_point{NUMEROLOGY_IDX, rach_info.slot_index}; // TODO: fill remaining fields as required - sched->dl_rach_info(enb_cc_idx, rar_info); + sched->dl_rach_info(rar_info, uecfg); rrc->add_user(rnti, uecfg); logger.info("RACH: slot=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x", diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index 655d6dc78..37d4b6583 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -15,6 +15,7 @@ #include "srsenb/hdr/stack/mac/nr/harq_softbuffer.h" #include "srsenb/hdr/stack/mac/nr/sched_nr_bwp.h" #include "srsenb/hdr/stack/mac/nr/sched_nr_worker.h" +#include "srsran/common/phy_cfg_nr_default.h" #include "srsran/common/string_helpers.h" #include "srsran/common/thread_pool.h" @@ -87,12 +88,15 @@ class sched_nr::common_event_manager public: explicit common_event_manager(srslog::basic_logger& logger_) : logger(logger_) {} + /// Enqueue an event that does not map into a ue method (e.g. rem_user, add_user) void enqueue_event(const char* event_name, srsran::move_callback ev, uint16_t rnti = SRSRAN_INVALID_RNTI) { std::lock_guard lock(event_mutex); next_slot_events.emplace_back(rnti, event_name, std::move(ev)); } + /// Enqueue an event that directly maps into a ue method (e.g. ul_sr_info, ul_bsr, etc.) + /// Note: these events can be processed sequentially or in parallel, depending on whether the UE supports CA template void enqueue_ue_event(uint16_t rnti, R (ue::*ue_action)(FmtArgs...), const char* fmt_str, FmtArgs... args) { @@ -111,7 +115,7 @@ public: next_slot_ue_events.emplace_back(rnti, std::move(callback)); } - /// Process events synchronized during slot_indication() that are directed at CA-enabled UEs + /// Process all events that are directed at CA-enabled UEs /// Note: non-CA UEs are updated later in get_dl_sched, to leverage parallelism void process_common(ue_map_t& ues) { @@ -146,7 +150,7 @@ public: } /// Process events synchronized during slot_indication() that are directed at non CA-enabled UEs - void process_carrier_events(ue_map_t& ues, uint32_t cc) + void process_single_cc_ue_events(ue_map_t& ues, uint32_t cc) { for (ue_event_t& ev : current_slot_ue_events) { if (ev.rnti == SRSRAN_INVALID_RNTI) { @@ -190,7 +194,9 @@ private: fmt::format_to(fmtbuf, "}}"); prefix = ", "; } - logger.debug("SCHED: Pending slot events: [%s%s]", srsran::to_c_str(common_fmtbuf), srsran::to_c_str(fmtbuf)); + if (common_fmtbuf.size() > 0 or fmtbuf.size() > 0) { + logger.debug("SCHED: Pending slot events: [%s%s]", srsran::to_c_str(common_fmtbuf), srsran::to_c_str(fmtbuf)); + } } srslog::basic_logger& logger; @@ -306,6 +312,7 @@ int sched_nr::config(const sched_args_t& sched_cfg, srsran::const_spaninfo("SCHED: New user rnti=0x%x, cc=%d", rnti, cfg.cells[0].cc); pending_events->enqueue_event( "ue_cfg", [this, rnti, uecfg]() { ue_cfg_impl(rnti, uecfg); }, rnti); } @@ -316,14 +323,20 @@ void sched_nr::ue_rem(uint16_t rnti) "ue_rem", [this, rnti]() { ue_db.erase(rnti); }, rnti); } +bool sched_nr::add_ue_impl(uint16_t rnti, std::unique_ptr u) +{ + auto ret = ue_db.insert(rnti, std::move(u)); + if (not ret.has_value()) { + logger->error("SCHED: Failed to create new user rnti=0x%x", rnti); + return false; + } + return true; +} + void sched_nr::ue_cfg_impl(uint16_t rnti, const ue_cfg_t& uecfg) { if (not ue_db.contains(rnti)) { - logger->info("SCHED: New user rnti=0x%x, cc=%d", rnti, cfg.cells[0].cc); - auto ret = ue_db.insert(rnti, std::unique_ptr(new ue{rnti, uecfg, cfg})); - if (not ret.has_value()) { - logger->error("SCHED: Failed to create new user rnti=0x%x", rnti); - } + add_ue_impl(rnti, std::unique_ptr(new ue{rnti, uecfg, cfg})); } else { ue_db[rnti]->set_cfg(uecfg); } @@ -363,7 +376,7 @@ int sched_nr::get_dl_sched(slot_point pdsch_tti, uint32_t cc, dl_res_t& result) ul_res_t& ul_res = pending_results->add_ul_result(pdsch_tti, cc); // process non-cc specific feedback if pending (e.g. SRs, buffer state updates, UE config) for non-CA UEs - pending_events->process_carrier_events(ue_db, cc); + pending_events->process_single_cc_ue_events(ue_db, cc); // prepare non-CA UEs internal state for new slot for (auto& u : ue_db) { @@ -405,10 +418,24 @@ void sched_nr::get_metrics(mac_metrics_t& metrics) metrics_handler->get_metrics(metrics); } -int sched_nr::dl_rach_info(uint32_t cc, const rar_info_t& rar_info) +int sched_nr::dl_rach_info(const rar_info_t& rar_info, const ue_cfg_t& uecfg) { - cc_workers[cc]->pending_feedback.enqueue_common_event( - [this, cc, rar_info]() { cc_workers[cc]->bwps[0].ra.dl_rach_info(rar_info); }); + // enqueue UE creation event + RACH handling + auto add_ue = [this, uecfg, rar_info]() { + // create user + // Note: UEs being created in sched main thread, which has higher priority + logger->info("SCHED: New user rnti=0x%x, cc=%d", rar_info.temp_crnti, uecfg.carriers[0].cc); + std::unique_ptr u{new ue{rar_info.temp_crnti, uecfg, cfg}}; + + uint16_t rnti = rar_info.temp_crnti; + if (add_ue_impl(rnti, std::move(u))) { + // RACH is handled in cc worker, once the UE object is created and inserted in the ue_db + uint32_t cc = uecfg.carriers[0].cc; + cc_workers[cc]->pending_feedback.enqueue_common_event( + [this, cc, rar_info]() { cc_workers[cc]->dl_rach_info(rar_info); }); + } + }; + pending_events->enqueue_event("dl_rach_info", add_ue); return SRSRAN_SUCCESS; } diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index 7078e7580..8018297ef 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -91,6 +91,11 @@ bool cc_worker::save_sched_result(dl_sched_res_t& dl_res, ul_sched_t& ul_res, sl return true; } +void cc_worker::dl_rach_info(const sched_nr_interface::rar_info_t& rar_info) +{ + bwps[0].ra.dl_rach_info(rar_info); +} + /// Called within a locked context, to generate {slot, cc} scheduling decision void cc_worker::run_slot(slot_point pdcch_slot, ue_map_t& ue_db, dl_sched_res_t& dl_res, ul_sched_t& ul_res) { diff --git a/srsenb/test/mac/nr/sched_nr_sim_ue.cc b/srsenb/test/mac/nr/sched_nr_sim_ue.cc index 904d2908f..6c7dabf7b 100644 --- a/srsenb/test/mac/nr/sched_nr_sim_ue.cc +++ b/srsenb/test/mac/nr/sched_nr_sim_ue.cc @@ -146,7 +146,6 @@ int sched_nr_base_tester::add_user(uint16_t rnti, uint32_t preamble_idx) { sem_wait(&slot_sem); - sched_ptr->ue_cfg(rnti, ue_cfg_); TESTASSERT(ue_db.count(rnti) == 0); @@ -157,7 +156,7 @@ int sched_nr_base_tester::add_user(uint16_t rnti, rach_info.prach_slot = tti_rx; rach_info.preamble_idx = preamble_idx; rach_info.msg3_size = 7; - sched_ptr->dl_rach_info(ue_cfg_.carriers[0].cc, rach_info); + sched_ptr->dl_rach_info(rach_info, ue_cfg_); sem_post(&slot_sem);