Merge pull request #2214 from softwareradiosystems/pr_mac_buffers

Limit the number of UL buffers in MAC and deallocate old ones
master
Ismael Gomez 4 years ago committed by GitHub
commit 47dbd6ed70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -180,12 +180,12 @@ public:
* *
* @param tti the given TTI * @param tti the given TTI
* @param rnti the UE identifier in the eNb * @param rnti the UE identifier in the eNb
* @param pdu_ptr pointer to the uplink buffer * @param enb_cc_idx the eNb Cell/Carrier identifier
* @param nof_bytes the number of grants carrierd by the PUSCH message * @param nof_bytes the number of grants carrierd by the PUSCH message
* @param crc_res the CRC check, set to true if the message was decoded succesfully * @param crc_res the CRC check, set to true if the message was decoded succesfully
* @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs
*/ */
virtual int push_pdu(uint32_t tti_rx, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc_res) = 0; virtual int push_pdu(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc_res) = 0;
virtual int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) = 0; virtual int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) = 0;
virtual int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) = 0; virtual int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) = 0;

@ -80,9 +80,9 @@ public:
{ {
return mac.crc_info(tti, rnti, enb_cc_idx, nof_bytes, crc_res); return mac.crc_info(tti, rnti, enb_cc_idx, nof_bytes, crc_res);
} }
int push_pdu(uint32_t tti, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc_res) final int push_pdu(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc_res) final
{ {
return mac.push_pdu(tti, rnti, pdu_ptr, nof_bytes, crc_res); return mac.push_pdu(tti, rnti, enb_cc_idx, nof_bytes, crc_res);
} }
int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) final { return mac.get_dl_sched(tti, dl_sched_res); } int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) final { return mac.get_dl_sched(tti, dl_sched_res); }
int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) final int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) final

@ -56,7 +56,7 @@ public:
int ta_info(uint32_t tti, uint16_t rnti, float ta_us) override; int ta_info(uint32_t tti, uint16_t rnti, float ta_us) override;
int ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) override; int ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) override;
int crc_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc_res) override; int crc_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc_res) override;
int push_pdu(uint32_t tti, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc_res) override; int push_pdu(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc_res) override;
int get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res) override; int get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res) override;
int get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res) override; int get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res) override;

@ -15,6 +15,7 @@
#include "mac_metrics.h" #include "mac_metrics.h"
#include "srslte/common/block_queue.h" #include "srslte/common/block_queue.h"
#include "srslte/adt/circular_array.h"
#include "srslte/common/log.h" #include "srslte/common/log.h"
#include "srslte/common/mac_pcap.h" #include "srslte/common/mac_pcap.h"
#include "srslte/interfaces/enb_interfaces.h" #include "srslte/interfaces/enb_interfaces.h"
@ -71,10 +72,11 @@ public:
srslte_softbuffer_rx_t* get_rx_softbuffer(const uint32_t ue_cc_idx, const uint32_t tti); srslte_softbuffer_rx_t* get_rx_softbuffer(const uint32_t ue_cc_idx, const uint32_t tti);
bool process_pdus(); bool process_pdus();
uint8_t* request_buffer(const uint32_t len); 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, srslte::pdu_queue::channel_t channel) override; void process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channel_t channel) override;
void push_pdu(const uint8_t* pdu_ptr, uint32_t len); void push_pdu(uint32_t tti, uint32_t ue_cc_idx, uint32_t len);
void deallocate_pdu(const uint8_t* pdu_ptr); void deallocate_pdu(uint32_t tti, uint32_t ue_cc_idx);
void clear_old_buffers(uint32_t tti);
void metrics_read(mac_ue_metrics_t* metrics_); void metrics_read(mac_ue_metrics_t* metrics_);
void metrics_rx(bool crc, uint32_t tbs); void metrics_rx(bool crc, uint32_t tbs);
@ -122,6 +124,8 @@ private:
std::vector<std::array<std::array<srslte::unique_byte_buffer_t, SRSLTE_MAX_TB>, SRSLTE_FDD_NOF_HARQ> > std::vector<std::array<std::array<srslte::unique_byte_buffer_t, SRSLTE_MAX_TB>, SRSLTE_FDD_NOF_HARQ> >
tx_payload_buffer; tx_payload_buffer;
std::vector<std::map<uint32_t, uint8_t*> > rx_used_buffers;
srslte::block_queue<uint32_t> pending_ta_commands; srslte::block_queue<uint32_t> pending_ta_commands;
ta ta_fsm; ta ta_fsm;

@ -374,7 +374,7 @@ void cc_worker::decode_pusch(stack_interface_phy_lte::ul_sched_grant_t* grants,
// Inform MAC about the CRC result // Inform MAC about the CRC result
phy->stack->crc_info(tti_rx, rnti, cc_idx, ul_cfg.pusch.grant.tb.tbs / 8, pusch_res.crc); phy->stack->crc_info(tti_rx, rnti, cc_idx, ul_cfg.pusch.grant.tb.tbs / 8, pusch_res.crc);
// Push PDU buffer // Push PDU buffer
phy->stack->push_pdu(tti_rx, rnti, grants[i].data, ul_cfg.pusch.grant.tb.tbs / 8, pusch_res.crc); phy->stack->push_pdu(tti_rx, rnti, cc_idx, ul_cfg.pusch.grant.tb.tbs / 8, pusch_res.crc);
// Logging // Logging
if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) {
char str[512]; char str[512];

@ -323,7 +323,7 @@ int mac::crc_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t
return scheduler.ul_crc_info(tti_rx, rnti, enb_cc_idx, crc); return scheduler.ul_crc_info(tti_rx, rnti, enb_cc_idx, crc);
} }
int mac::push_pdu(uint32_t tti_rx, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc) int mac::push_pdu(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc)
{ {
srslte::rwlock_read_guard lock(rwlock); srslte::rwlock_read_guard lock(rwlock);
@ -331,14 +331,21 @@ int mac::push_pdu(uint32_t tti_rx, uint16_t rnti, const uint8_t* pdu_ptr, uint32
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
std::array<int, SRSLTE_MAX_CARRIERS> enb_ue_cc_map = scheduler.get_enb_ue_cc_map(rnti);
if (enb_ue_cc_map[enb_cc_idx] < 0) {
Error("User rnti=0x%x is not activated for carrier %d\n", rnti, enb_cc_idx);
return SRSLTE_ERROR;
}
uint32_t ue_cc_idx = enb_ue_cc_map[enb_cc_idx];
// push the pdu through the queue if received correctly // push the pdu through the queue if received correctly
if (crc) { if (crc) {
Info("Pushing PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes); Info("Pushing PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes);
ue_db[rnti]->push_pdu(pdu_ptr, nof_bytes); ue_db[rnti]->push_pdu(tti_rx, ue_cc_idx, nof_bytes);
stack_task_queue.push([this]() { process_pdus(); }); stack_task_queue.push([this]() { process_pdus(); });
} else { } else {
Debug("Discarting PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes); Debug("Discarting PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes);
ue_db[rnti]->deallocate_pdu(pdu_ptr); ue_db[rnti]->deallocate_pdu(tti_rx, ue_cc_idx);
} }
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
@ -906,7 +913,8 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list)
if (sched_result.pusch[n].current_tx_nb == 0) { if (sched_result.pusch[n].current_tx_nb == 0) {
srslte_softbuffer_rx_reset_tbs(phy_ul_sched_res->pusch[n].softbuffer_rx, sched_result.pusch[i].tbs * 8); srslte_softbuffer_rx_reset_tbs(phy_ul_sched_res->pusch[n].softbuffer_rx, sched_result.pusch[i].tbs * 8);
} }
phy_ul_sched_res->pusch[n].data = ue_db[rnti]->request_buffer(sched_result.pusch[i].tbs); phy_ul_sched_res->pusch[n].data =
ue_db[rnti]->request_buffer(tti_tx_ul, sched_result.pusch[i].dci.ue_cc_idx, sched_result.pusch[i].tbs);
if (phy_ul_sched_res->pusch[n].data) { if (phy_ul_sched_res->pusch[n].data) {
phy_ul_sched_res->nof_grants++; phy_ul_sched_res->nof_grants++;
} else { } else {
@ -932,6 +940,10 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list)
} }
phy_ul_sched_res->nof_phich = sched_result.nof_phich_elems; phy_ul_sched_res->nof_phich = sched_result.nof_phich_elems;
} }
// clear old buffers from all users
for (auto& u : ue_db) {
u.second->clear_old_buffers(tti_tx_ul);
}
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }

@ -44,6 +44,7 @@ ue::ue(uint16_t rnti_,
pdus(128), pdus(128),
nof_rx_harq_proc(nof_rx_harq_proc_), nof_rx_harq_proc(nof_rx_harq_proc_),
nof_tx_harq_proc(nof_tx_harq_proc_), nof_tx_harq_proc(nof_tx_harq_proc_),
rx_used_buffers(nof_cells_),
ta_fsm(this) ta_fsm(this)
{ {
srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance(); srslte::byte_buffer_pool* pool = srslte::byte_buffer_pool::get_instance();
@ -76,6 +77,12 @@ ue::~ue()
srslte_softbuffer_tx_free(&buffer); srslte_softbuffer_tx_free(&buffer);
} }
} }
for (auto& rx_buffers_cc : rx_used_buffers) {
for (auto& q : rx_buffers_cc) {
pdus.deallocate(q.second);
}
rx_buffers_cc.clear();
}
} }
void ue::reset() void ue::reset()
@ -161,13 +168,40 @@ ue::get_tx_softbuffer(const uint32_t ue_cc_idx, const uint32_t harq_process, con
return &softbuffer_tx.at(ue_cc_idx).at((harq_process * SRSLTE_MAX_TB + tb_idx) % nof_tx_harq_proc); return &softbuffer_tx.at(ue_cc_idx).at((harq_process * SRSLTE_MAX_TB + tb_idx) % nof_tx_harq_proc);
} }
uint8_t* ue::request_buffer(const uint32_t len) uint8_t* ue::request_buffer(uint32_t tti, uint32_t ue_cc_idx, const uint32_t len)
{ {
uint8_t* pdu = nullptr;
if (len > 0) { if (len > 0) {
return pdus.request(len); // Deallocate oldest buffer if we didn't deallocate it
if (!rx_used_buffers.at(ue_cc_idx).count(tti)) {
pdu = pdus.request(len);
if (pdu) {
rx_used_buffers.at(ue_cc_idx).emplace(tti, pdu);
} else { } else {
log_h->warning("Requesting buffer for zero bytes\n"); Error("UE buffers: Requesting buffer from pool\n");
return nullptr; }
} else {
Error("UE buffers: buffer for tti=%d already allocated\n", tti);
}
} else {
Error("UE buffers: Requesting buffer for zero bytes\n");
}
return pdu;
}
void ue::clear_old_buffers(uint32_t tti)
{
// remove old buffers
for (auto& rx_buffer_cc : rx_used_buffers) {
for (auto it = rx_buffer_cc.begin(); it != rx_buffer_cc.end();) {
if (srslte_tti_interval(tti, it->first) > 20) {
Warning("UE buffers: Removing old buffer tti=%d, rnti=%d, now is %d\n", it->first, rnti, tti);
pdus.deallocate(it->second);
it = rx_buffer_cc.erase(it);
} else {
++it;
}
}
} }
} }
@ -293,21 +327,33 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channe
Debug("MAC PDU processed\n"); Debug("MAC PDU processed\n");
} }
void ue::deallocate_pdu(const uint8_t* pdu_ptr) void ue::deallocate_pdu(uint32_t tti, uint32_t ue_cc_idx)
{ {
if (pdu_ptr) { if (rx_used_buffers.at(ue_cc_idx).count(tti)) {
pdus.deallocate(pdu_ptr); pdus.deallocate(rx_used_buffers.at(ue_cc_idx).at(tti));
rx_used_buffers.at(ue_cc_idx).erase(tti);
} else { } else {
Error("Error deallocating PDU: null ptr\n"); Warning("UE buffers: Null RX PDU pointer in deallocate_pdu for rnti=0x%x pid=%d cc_idx=%d\n",
rnti,
tti % nof_rx_harq_proc,
ue_cc_idx);
} }
} }
void ue::push_pdu(const uint8_t* pdu_ptr, uint32_t len) void ue::push_pdu(uint32_t tti, uint32_t ue_cc_idx, uint32_t len)
{ {
if (pdu_ptr && len > 0) { if (rx_used_buffers.at(ue_cc_idx).count(tti)) {
pdus.push(pdu_ptr, len); if (len > 0) {
pdus.push(rx_used_buffers.at(ue_cc_idx).at(tti), len);
} else {
Error("Error pushing PDU: null length\n");
}
rx_used_buffers.at(ue_cc_idx).erase(tti);
} else { } else {
Error("Error pushing PDU: ptr=%p, len=%d\n", pdu_ptr, len); Warning("UE buffers: Null RX PDU pointer in push_pdu for rnti=0x%x pid=%d cc_idx=%d\n",
rnti,
tti % nof_rx_harq_proc,
ue_cc_idx);
} }
} }

@ -493,7 +493,7 @@ public:
return 0; return 0;
} }
int push_pdu(uint32_t tti, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc_res) override int push_pdu(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t nof_bytes, bool crc_res) override
{ {
log_h.info("Received push_pdu tti=%d; rnti=0x%x; ack=%d;\n", tti, rnti, crc_res); log_h.info("Received push_pdu tti=%d; rnti=0x%x; ack=%d;\n", tti, rnti, crc_res);
notify_push_pdu(); notify_push_pdu();

Loading…
Cancel
Save