Limit the number of UL buffers in MAC and deallocate old ones

master
Ismael Gomez 4 years ago
parent 0780f3caea
commit e413086576

@ -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,10 @@ 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, 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, const uint8_t* pdu_ptr, uint32_t len);
void deallocate_pdu(const uint8_t* pdu_ptr); void deallocate_pdu(uint32_t tti, const uint8_t* pdu_ptr);
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 +123,9 @@ 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;
// Save 2 buffers per HARQ process
srslte::circular_array<uint8_t*, 2 * SRSLTE_FDD_NOF_HARQ> 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;

@ -334,11 +334,11 @@ int mac::push_pdu(uint32_t tti_rx, uint16_t rnti, const uint8_t* pdu_ptr, uint32
// 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, pdu_ptr, 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, pdu_ptr);
} }
return SRSLTE_SUCCESS; return SRSLTE_SUCCESS;
} }
@ -906,7 +906,7 @@ 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].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 {

@ -161,14 +161,27 @@ 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, const uint32_t len)
{ {
uint8_t* pdu = nullptr;
if (len > 0) { if (len > 0) {
return pdus.request(len); pdu = pdus.request(len);
if (pdu) {
// Deallocate oldest buffer if we didn't deallocate it
if (rx_used_buffers[tti] != nullptr) {
pdus.deallocate(rx_used_buffers[tti]);
rx_used_buffers[tti] = nullptr;
log_h->warning("buffers: RX PDU of rnti=0x%x and pid=%d wasn't deallocated\n", rnti, tti % nof_rx_harq_proc);
}
rx_used_buffers[tti] = pdu;
log_h->info("RX PDU saved for pid=%d\n", tti % nof_rx_harq_proc);
} else { } else {
log_h->warning("Requesting buffer for zero bytes\n"); log_h->error("buffers: Requesting buffer from pool\n");
return nullptr; }
} else {
printf("buffers: Requesting buffer for zero bytes\n");
} }
return pdu;
} }
bool ue::process_pdus() bool ue::process_pdus()
@ -293,18 +306,28 @@ 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, const uint8_t* pdu_ptr)
{ {
if (pdu_ptr) { if (pdu_ptr) {
if (rx_used_buffers[tti] == pdu_ptr) {
rx_used_buffers[tti] = nullptr;
} else {
Warning("buffers: Unexpected RX PDU pointer in deallocate_pdu for rnti=0x%x pid=%d\n", rnti, tti % nof_rx_harq_proc);
}
pdus.deallocate(pdu_ptr); pdus.deallocate(pdu_ptr);
} else { } else {
Error("Error deallocating PDU: null ptr\n"); Error("Error deallocating PDU: null ptr\n");
} }
} }
void ue::push_pdu(const uint8_t* pdu_ptr, uint32_t len) void ue::push_pdu(uint32_t tti, const uint8_t* pdu_ptr, uint32_t len)
{ {
if (pdu_ptr && len > 0) { if (pdu_ptr && len > 0) {
if (rx_used_buffers[tti] == pdu_ptr) {
rx_used_buffers[tti] = nullptr;
} else {
Warning("buffers: Unexpected RX PDU pointer in push_pdu for rnti=0x%x pid=%d\n", rnti, tti % nof_rx_harq_proc);
}
pdus.push(pdu_ptr, len); pdus.push(pdu_ptr, len);
} else { } else {
Error("Error pushing PDU: ptr=%p, len=%d\n", pdu_ptr, len); Error("Error pushing PDU: ptr=%p, len=%d\n", pdu_ptr, len);

Loading…
Cancel
Save