From 76004a3054d511166b58b1eca2d4b55e0dfdcf3b Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 3 Jun 2021 09:30:22 +0100 Subject: [PATCH] enb,mac,refactor: mac::ue now uses byte_buffer_pool for UL PDUs --- srsenb/hdr/stack/mac/mac.h | 2 - srsenb/hdr/stack/mac/ue.h | 47 ++++++------ srsenb/src/stack/mac/mac.cc | 31 ++++---- srsenb/src/stack/mac/ue.cc | 140 ++++++++++-------------------------- 4 files changed, 73 insertions(+), 147 deletions(-) diff --git a/srsenb/hdr/stack/mac/mac.h b/srsenb/hdr/stack/mac/mac.h index 2755335cb..a3b782603 100644 --- a/srsenb/hdr/stack/mac/mac.h +++ b/srsenb/hdr/stack/mac/mac.h @@ -92,8 +92,6 @@ public: /* Handover-related */ uint16_t reserve_new_crnti(const sched_interface::ue_cfg_t& ue_cfg) override; - bool process_pdus(); - void get_metrics(mac_metrics_t& metrics); void toggle_padding(); diff --git a/srsenb/hdr/stack/mac/ue.h b/srsenb/hdr/stack/mac/ue.h index 7e7a945d1..6e43597d6 100644 --- a/srsenb/hdr/stack/mac/ue.h +++ b/srsenb/hdr/stack/mac/ue.h @@ -36,6 +36,7 @@ class rrc_interface_mac; class rlc_interface_mac; class phy_interface_stack_lte; +/// Class to manage the allocation, deallocation & access to UE carrier DL + UL softbuffers struct ue_cc_softbuffers { // List of Tx softbuffers for all HARQ processes of one carrier using cc_softbuffer_tx_list_t = std::vector; @@ -59,39 +60,35 @@ struct ue_cc_softbuffers { srsran_softbuffer_rx_t& get_rx(uint32_t tti) { return softbuffer_rx_list.at(tti % nof_rx_harq_proc); } }; +/// Class to manage the allocation, deallocation & access to pending UL HARQ buffers class cc_used_buffers_map { public: - explicit cc_used_buffers_map(srsran::pdu_queue& shared_pdu_queue_); + explicit cc_used_buffers_map(); ~cc_used_buffers_map(); + void clear() { pdu_map.clear(); } + uint8_t* request_pdu(tti_point tti, uint32_t len); - bool push_pdu(tti_point tti, uint32_t len, uint32_t grant_nof_prbs); + srsran::unique_byte_buffer_t release_pdu(tti_point tti, uint32_t len); void clear_old_pdus(tti_point current_tti); - bool try_deallocate_pdu(tti_point tti); - - void clear(); - uint8_t*& operator[](tti_point tti); bool has_tti(tti_point tti) const; private: - void remove_pdu(tti_point tti); - srslog::basic_logger* logger; - srsran::pdu_queue* shared_pdu_queue; - srsran::static_circular_map pdu_map; + srsran::static_circular_map pdu_map; }; class cc_buffer_handler { public: - explicit cc_buffer_handler(srsran::pdu_queue& shared_pdu_queue_); + explicit cc_buffer_handler(); ~cc_buffer_handler(); void reset(); @@ -117,11 +114,11 @@ private: // buffers cc_used_buffers_map rx_used_buffers; - // One buffer per TB per HARQ process and per carrier is needed for each UE. + // One buffer per TB per DL HARQ process and per carrier is needed for each UE. std::array, SRSRAN_FDD_NOF_HARQ> tx_payload_buffer; }; -class ue : public srsran::read_pdu_interface, public srsran::pdu_queue::process_callback, public mac_ta_ue_interface +class ue : public srsran::read_pdu_interface, public mac_ta_ue_interface { public: ue(uint16_t rnti, @@ -139,7 +136,7 @@ public: void start_pcap(srsran::mac_pcap* pcap_); void start_pcap_net(srsran::mac_pcap_net* pcap_net_); void set_tti(uint32_t tti); - uint16_t get_rnti() { return rnti; } + uint16_t get_rnti() const { return rnti; } uint32_t set_ta(int ta) override; void start_ta() { ta_fsm.start(); }; uint32_t set_ta_us(float ta_us) { return ta_fsm.push_value(ta_us); }; @@ -155,16 +152,13 @@ public: uint8_t* generate_mch_pdu(uint32_t harq_pid, sched_interface::dl_pdu_mch_t sched, uint32_t nof_pdu_elems, uint32_t grant_size); - srsran_softbuffer_tx_t* - get_tx_softbuffer(const uint32_t ue_cc_idx, const uint32_t harq_process, const uint32_t tb_idx); - srsran_softbuffer_rx_t* get_rx_softbuffer(const uint32_t ue_cc_idx, const uint32_t tti); + srsran_softbuffer_tx_t* get_tx_softbuffer(uint32_t ue_cc_idx, uint32_t harq_process, uint32_t tb_idx); + srsran_softbuffer_rx_t* get_rx_softbuffer(uint32_t ue_cc_idx, uint32_t tti); - bool process_pdus(); - uint8_t* request_buffer(uint32_t tti, uint32_t ue_cc_idx, const uint32_t len); - void process_pdu(uint8_t* pdu, uint32_t nof_bytes, srsran::pdu_queue::channel_t channel, int grant_nof_prbs) override; - void push_pdu(uint32_t tti, uint32_t ue_cc_idx, uint32_t len, uint32_t grant_nof_prbs); - void deallocate_pdu(uint32_t tti, uint32_t ue_cc_idx); - void clear_old_buffers(uint32_t tti); + uint8_t* request_buffer(uint32_t tti, uint32_t ue_cc_idx, const uint32_t len); + void process_pdu(srsran::unique_byte_buffer_t pdu, uint32_t grant_nof_prbs); + srsran::unique_byte_buffer_t release_pdu(uint32_t tti, uint32_t ue_cc_idx, uint32_t len); + void clear_old_buffers(uint32_t tti); void metrics_read(mac_ue_metrics_t* metrics_); void metrics_rx(bool crc, uint32_t tbs); @@ -179,7 +173,7 @@ public: private: void allocate_sdu(srsran::sch_pdu* pdu, uint32_t lcid, uint32_t sdu_len); - bool process_ce(srsran::sch_subh* subh, int grant_nof_prbs); + bool process_ce(srsran::sch_subh* subh, uint32_t grant_nof_prbs); void allocate_ce(srsran::sch_pdu* pdu, uint32_t lcid); rlc_interface_mac* rlc = nullptr; @@ -207,9 +201,8 @@ private: ta ta_fsm; // For UL there are multiple buffers per PID and are managed by pdu_queue - srsran::pdu_queue pdus; - srsran::sch_pdu mac_msg_dl, mac_msg_ul; - srsran::mch_pdu mch_mac_msg_dl; + srsran::sch_pdu mac_msg_dl, mac_msg_ul; + srsran::mch_pdu mch_mac_msg_dl; srsran::bounded_vector cc_buffers; diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index f8f4a2185..4068af05c 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -32,6 +32,7 @@ mac::mac(srsran::ext_task_sched_handle task_sched_, srslog::basic_logger& logger logger(logger), rar_payload(), common_buffers(SRSRAN_MAX_CARRIERS), task_sched(task_sched_) { pthread_rwlock_init(&rwlock, nullptr); + stack_task_queue = task_sched.make_task_queue(); } mac::~mac() @@ -58,8 +59,6 @@ bool mac::init(const mac_args_t& args_, args = args_; cells = cells_; - stack_task_queue = task_sched.make_task_queue(); - scheduler.init(rrc, args.sched); // Init softbuffer for SI messages @@ -364,14 +363,24 @@ int mac::push_pdu(uint32_t tti_rx, } uint32_t ue_cc_idx = enb_ue_cc_map[enb_cc_idx]; + srsran::unique_byte_buffer_t pdu = ue_db[rnti]->release_pdu(tti_rx, ue_cc_idx, nof_bytes); + if (pdu == nullptr) { + logger.warning("Could not find MAC UL PDU for rnti=0x%x, cc=%d, tti=%d", rnti, enb_cc_idx, tti_rx); + return SRSRAN_ERROR; + } + // push the pdu through the queue if received correctly if (crc) { logger.info("Pushing PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d", rnti, tti_rx, nof_bytes); - ue_db[rnti]->push_pdu(tti_rx, ue_cc_idx, nof_bytes, ul_nof_prbs); - stack_task_queue.push([this]() { process_pdus(); }); + auto process_pdu_task = [this, rnti, ul_nof_prbs](srsran::unique_byte_buffer_t& pdu) { + srsran::rwlock_read_guard lock(rwlock); + if (ue_db.contains(rnti)) { + ue_db[rnti]->process_pdu(std::move(pdu), ul_nof_prbs); + } + }; + auto ret = stack_task_queue.try_push(std::bind(process_pdu_task, std::move(pdu))); } else { - logger.debug("Discarting PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d", rnti, tti_rx, nof_bytes); - ue_db[rnti]->deallocate_pdu(tti_rx, ue_cc_idx); + logger.debug("Discarding PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d", rnti, tti_rx, nof_bytes); } return SRSRAN_SUCCESS; } @@ -1007,16 +1016,6 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list) return SRSRAN_SUCCESS; } -bool mac::process_pdus() -{ - srsran::rwlock_read_guard lock(rwlock); - bool ret = false; - for (auto& u : ue_db) { - ret |= u.second->process_pdus(); - } - return ret; -} - void mac::write_mcch(const srsran::sib2_mbms_t* sib2_, const srsran::sib13_t* sib13_, const srsran::mcch_msg_t* mcch_, diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index 0bc539178..ebbb03861 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -62,30 +62,26 @@ void ue_cc_softbuffers::clear() } } -cc_used_buffers_map::cc_used_buffers_map(srsran::pdu_queue& shared_pdu_queue_) : - shared_pdu_queue(&shared_pdu_queue_), logger(&srslog::fetch_basic_logger("MAC")) -{} +cc_used_buffers_map::cc_used_buffers_map() : logger(&srslog::fetch_basic_logger("MAC")) {} cc_used_buffers_map::~cc_used_buffers_map() { clear(); } -bool cc_used_buffers_map::push_pdu(tti_point tti, uint32_t len, uint32_t grant_nof_prbs) +srsran::unique_byte_buffer_t cc_used_buffers_map::release_pdu(tti_point tti, uint32_t len) { if (not has_tti(tti)) { - return false; - } - uint8_t* buffer = pdu_map[tti.to_uint()]; - if (len > 0) { - shared_pdu_queue->push(buffer, len, srsran::pdu_queue::DCH, grant_nof_prbs); - } else { - shared_pdu_queue->deallocate(buffer); - logger->error("Error pushing PDU: null length"); + return nullptr; } + + // Extract PDU from PDU map + srsran::unique_byte_buffer_t pdu = std::move(pdu_map[tti.to_uint()]); + srsran_expect(pdu->size() == len, "UL buffers: Inconsistent UL PDU length for tti=%d", tti.to_uint()); + // clear entry in map pdu_map.erase(tti.to_uint()); - return len > 0; + return pdu; } uint8_t* cc_used_buffers_map::request_pdu(tti_point tti, uint32_t len) @@ -95,15 +91,17 @@ uint8_t* cc_used_buffers_map::request_pdu(tti_point tti, uint32_t len) return nullptr; } - uint8_t* pdu = shared_pdu_queue->request(len); + srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); if (pdu == nullptr) { - logger->error("UE buffers: Requesting buffer from pool"); + logger->error("UE buffers: Requesting buffer from byte buffer pool"); return nullptr; } + srsran_assert(len < pdu->get_tailroom(), "Requested UL pdu doesn't fit in byte_buffer"); + pdu->N_bytes = len; - bool inserted = pdu_map.insert(tti.to_uint(), pdu); - srsran_assert(inserted, "Failure to allocate new buffer"); - return pdu; + auto inserted_elem = pdu_map.insert(tti.to_uint(), std::move(pdu)); + srsran_assert(inserted_elem.has_value(), "Failure to allocate new buffer in mac::ue"); + return inserted_elem.value()->second->data(); } void cc_used_buffers_map::clear_old_pdus(tti_point current_tti) @@ -115,40 +113,14 @@ void cc_used_buffers_map::clear_old_pdus(tti_point current_tti) tti_point t(pdu_pair.first); if (t < max_tti) { logger->warning("UE buffers: Removing old buffer tti=%d, interval=%d", t.to_uint(), current_tti - t); - remove_pdu(t); + pdu_map.erase(t.to_uint()); } } } -void cc_used_buffers_map::remove_pdu(tti_point tti) -{ - uint8_t* buffer = pdu_map[tti.to_uint()]; - // return pdus back to the queue - shared_pdu_queue->deallocate(buffer); - // clear entry in map - pdu_map.erase(tti.to_uint()); -} - -bool cc_used_buffers_map::try_deallocate_pdu(tti_point tti) -{ - if (has_tti(tti)) { - remove_pdu(tti); - return true; - } - return false; -} - -void cc_used_buffers_map::clear() -{ - for (auto& buffer : pdu_map) { - shared_pdu_queue->deallocate(buffer.second); - } - pdu_map.clear(); -} - uint8_t*& cc_used_buffers_map::operator[](tti_point tti) { - return pdu_map[tti.to_uint()]; + return pdu_map[tti.to_uint()]->msg; } bool cc_used_buffers_map::has_tti(tti_point tti) const @@ -158,7 +130,7 @@ bool cc_used_buffers_map::has_tti(tti_point tti) const //////////////// -cc_buffer_handler::cc_buffer_handler(srsran::pdu_queue& shared_pdu_queue_) : rx_used_buffers(shared_pdu_queue_) +cc_buffer_handler::cc_buffer_handler() { for (auto& harq_buffers : tx_payload_buffer) { for (srsran::unique_byte_buffer_t& tb_buffer : harq_buffers) { @@ -219,26 +191,15 @@ ue::ue(uint16_t rnti_, mac_msg_dl(20, logger_), mch_mac_msg_dl(10, logger_), mac_msg_ul(20, logger_), - pdus(logger_), ta_fsm(this), - softbuffer_pool(softbuffer_pool_) + softbuffer_pool(softbuffer_pool_), + cc_buffers(nof_cells_) { - for (size_t i = 0; i < nof_cells_; ++i) { - cc_buffers.emplace_back(pdus); - } - pdus.init(this); - // Allocate buffer for PCell cc_buffers[0].allocate_cc(softbuffer_pool->make()); } -ue::~ue() -{ - std::unique_lock lock(rx_buffers_mutex); - for (auto& cc : cc_buffers) { - cc.get_rx_used_buffers().clear(); - } -} +ue::~ue() {} void ue::reset() { @@ -260,7 +221,7 @@ void ue::start_pcap(srsran::mac_pcap* pcap_) pcap = pcap_; } -srsran_softbuffer_rx_t* ue::get_rx_softbuffer(const uint32_t ue_cc_idx, const uint32_t tti) +srsran_softbuffer_rx_t* ue::get_rx_softbuffer(uint32_t ue_cc_idx, uint32_t tti) { if ((size_t)ue_cc_idx >= cc_buffers.size()) { ERROR("UE CC Index (%d/%zd) out-of-range", ue_cc_idx, cc_buffers.size()); @@ -270,8 +231,7 @@ srsran_softbuffer_rx_t* ue::get_rx_softbuffer(const uint32_t ue_cc_idx, const ui return &cc_buffers[ue_cc_idx].get_rx_softbuffer(tti); } -srsran_softbuffer_tx_t* -ue::get_tx_softbuffer(const uint32_t ue_cc_idx, const uint32_t harq_process, const uint32_t tb_idx) +srsran_softbuffer_tx_t* ue::get_tx_softbuffer(uint32_t ue_cc_idx, uint32_t harq_process, uint32_t tb_idx) { if ((size_t)ue_cc_idx >= cc_buffers.size()) { ERROR("UE CC Index (%d/%zd) out-of-range", ue_cc_idx, cc_buffers.size()); @@ -283,31 +243,20 @@ ue::get_tx_softbuffer(const uint32_t ue_cc_idx, const uint32_t harq_process, con uint8_t* ue::request_buffer(uint32_t tti, uint32_t ue_cc_idx, const uint32_t len) { + srsran_assert(len > 0, "UE buffers: Requesting buffer for zero bytes"); std::unique_lock lock(rx_buffers_mutex); - uint8_t* pdu = nullptr; - if (len > 0) { - pdu = cc_buffers[ue_cc_idx].get_rx_used_buffers().request_pdu(tti_point(tti), len); - } else { - logger.error("UE buffers: Requesting buffer for zero bytes"); - } - return pdu; + return cc_buffers[ue_cc_idx].get_rx_used_buffers().request_pdu(tti_point(tti), len); } void ue::clear_old_buffers(uint32_t tti) { std::unique_lock lock(rx_buffers_mutex); - // remove old buffers for (auto& cc : cc_buffers) { cc.get_rx_used_buffers().clear_old_pdus(tti_point{tti}); } } -bool ue::process_pdus() -{ - return pdus.process_pdus(); -} - void ue::set_tti(uint32_t tti) { last_tti = tti; @@ -329,11 +278,11 @@ uint32_t ue::set_ta(int ta_) return nof_cmd; } -void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srsran::pdu_queue::channel_t channel, int grant_nof_prbs) +void ue::process_pdu(srsran::unique_byte_buffer_t pdu, uint32_t grant_nof_prbs) { // Unpack ULSCH MAC PDU - mac_msg_ul.init_rx(nof_bytes, true); - mac_msg_ul.parse_packet(pdu); + mac_msg_ul.init_rx(pdu->size(), true); + mac_msg_ul.parse_packet(pdu->data()); if (logger.info.enabled()) { fmt::memory_buffer str_buffer; @@ -341,16 +290,14 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srsran::pdu_queue::channe logger.info("0x%x %s", rnti, srsran::to_c_str(str_buffer)); } - if (pcap) { - pcap->write_ul_crnti(pdu, nof_bytes, rnti, true, last_tti, UL_CC_IDX); + if (pcap != nullptr) { + pcap->write_ul_crnti(pdu->data(), pdu->size(), rnti, true, last_tti, UL_CC_IDX); } - if (pcap_net) { - pcap_net->write_ul_crnti(pdu, nof_bytes, rnti, true, last_tti, UL_CC_IDX); + if (pcap_net != nullptr) { + pcap_net->write_ul_crnti(pdu->data(), pdu->size(), rnti, true, last_tti, UL_CC_IDX); } - pdus.deallocate(pdu); - uint32_t lcid_most_data = 0; int most_data = -99; @@ -386,7 +333,7 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srsran::pdu_queue::channe // Indicate DRB activity in UL to RRC if (mac_msg_ul.get()->get_sdu_lcid() > 2) { rrc->set_activity_user(rnti); - logger.debug("UL activity rnti=0x%x, n_bytes=%d", rnti, nof_bytes); + logger.debug("UL activity rnti=0x%x, n_bytes=%d", rnti, pdu->size()); } if ((int)mac_msg_ul.get()->get_payload_size() > most_data) { @@ -431,24 +378,13 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srsran::pdu_queue::channe logger.debug("MAC PDU processed"); } -void ue::deallocate_pdu(uint32_t tti, uint32_t ue_cc_idx) -{ - std::unique_lock lock(rx_buffers_mutex); - if (not cc_buffers[ue_cc_idx].get_rx_used_buffers().try_deallocate_pdu(tti_point(tti))) { - logger.warning( - "UE buffers: Null RX PDU pointer in deallocate_pdu for rnti=0x%x tti=%d cc_idx=%d", rnti, tti, ue_cc_idx); - } -} - -void ue::push_pdu(uint32_t tti, uint32_t ue_cc_idx, uint32_t len, uint32_t grant_nof_prbs) +srsran::unique_byte_buffer_t ue::release_pdu(uint32_t tti, uint32_t ue_cc_idx, uint32_t len) { - std::unique_lock lock(rx_buffers_mutex); - if (not cc_buffers[ue_cc_idx].get_rx_used_buffers().push_pdu(tti_point(tti), len, grant_nof_prbs)) { - logger.warning("UE buffers: Failed to push RX PDU for rnti=0x%x tti=%d cc_idx=%d", rnti, tti, ue_cc_idx); - } + std::lock_guard lock(rx_buffers_mutex); + return cc_buffers[ue_cc_idx].get_rx_used_buffers().release_pdu(tti_point(tti), len); } -bool ue::process_ce(srsran::sch_subh* subh, int grant_nof_prbs) +bool ue::process_ce(srsran::sch_subh* subh, uint32_t grant_nof_prbs) { uint32_t buff_size_idx[4] = {}; uint32_t buff_size_bytes[4] = {};