nr,sched: auto clear HARQs that exceeded maxretx, after the feedback has been processed

master
Francisco 3 years ago committed by Francisco Paisana
parent fbcffb84bd
commit 327687cbc2

@ -46,7 +46,7 @@ public:
int ack_info(uint32_t tb_idx, bool ack); int ack_info(uint32_t tb_idx, bool ack);
void new_slot(slot_point slot_rx); bool clear_if_maxretx(slot_point slot_rx);
void reset(); void reset();
bool new_tx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, uint32_t mcs, uint32_t max_retx); bool new_tx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, uint32_t mcs, uint32_t max_retx);
bool new_retx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant); bool new_retx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant);
@ -112,7 +112,7 @@ private:
class harq_entity class harq_entity
{ {
public: public:
explicit harq_entity(uint32_t nprb, uint32_t nof_harq_procs = SCHED_NR_MAX_HARQ); explicit harq_entity(uint16_t rnti, uint32_t nprb, uint32_t nof_harq_procs, srslog::basic_logger& logger);
void new_slot(slot_point slot_rx_); void new_slot(slot_point slot_rx_);
int dl_ack_info(uint32_t pid, uint32_t tb_idx, bool ack) { return dl_harqs[pid].ack_info(tb_idx, ack); } int dl_ack_info(uint32_t pid, uint32_t tb_idx, bool ack) { return dl_harqs[pid].ack_info(tb_idx, ack); }
@ -154,6 +154,9 @@ private:
return (it == ul_harqs.end()) ? nullptr : &(*it); return (it == ul_harqs.end()) ? nullptr : &(*it);
} }
uint16_t rnti;
srslog::basic_logger& logger;
slot_point slot_rx; slot_point slot_rx;
std::vector<dl_harq_proc> dl_harqs; std::vector<dl_harq_proc> dl_harqs;
std::vector<ul_harq_proc> ul_harqs; std::vector<ul_harq_proc> ul_harqs;

@ -63,7 +63,11 @@ class ue_carrier
{ {
public: public:
ue_carrier(uint16_t rnti, const ue_cfg_t& cfg, const cell_params_t& cell_params_); ue_carrier(uint16_t rnti, const ue_cfg_t& cfg, const cell_params_t& cell_params_);
void set_cfg(const ue_cfg_t& ue_cfg); void set_cfg(const ue_cfg_t& ue_cfg);
/// Called after CC Feedback has been processed
void new_slot(slot_point slot_tx);
slot_ue try_reserve(slot_point pdcch_slot, uint32_t dl_harq_bytes, uint32_t ul_harq_bytes); slot_ue try_reserve(slot_point pdcch_slot, uint32_t dl_harq_bytes, uint32_t ul_harq_bytes);
const uint16_t rnti; const uint16_t rnti;

@ -28,11 +28,13 @@ int harq_proc::ack_info(uint32_t tb_idx, bool ack)
return ack ? tb[tb_idx].tbs : 0; return ack ? tb[tb_idx].tbs : 0;
} }
void harq_proc::new_slot(slot_point slot_rx) bool harq_proc::clear_if_maxretx(slot_point slot_rx)
{ {
if (has_pending_retx(slot_rx) and nof_retx() + 1 >= max_nof_retx()) { if (has_pending_retx(slot_rx) and nof_retx() + 1 > max_nof_retx()) {
tb[0].active = false; tb[0].active = false;
return true;
} }
return false;
} }
void harq_proc::reset() void harq_proc::reset()
@ -127,7 +129,8 @@ bool dl_harq_proc::new_tx(slot_point slot_tx,
return false; return false;
} }
harq_entity::harq_entity(uint32_t nprb, uint32_t nof_harq_procs) harq_entity::harq_entity(uint16_t rnti_, uint32_t nprb, uint32_t nof_harq_procs, srslog::basic_logger& logger_) :
rnti(rnti_), logger(logger_)
{ {
// Create HARQs // Create HARQs
dl_harqs.reserve(nof_harq_procs); dl_harqs.reserve(nof_harq_procs);
@ -142,10 +145,14 @@ void harq_entity::new_slot(slot_point slot_rx_)
{ {
slot_rx = slot_rx_; slot_rx = slot_rx_;
for (harq_proc& dl_h : dl_harqs) { for (harq_proc& dl_h : dl_harqs) {
dl_h.new_slot(slot_rx); if (dl_h.clear_if_maxretx(slot_rx)) {
logger.info("SCHED: discarding rnti=0x%x, DL TB pid=%d. Cause: Maximum number of retx exceeded (%d)");
}
} }
for (harq_proc& ul_h : ul_harqs) { for (harq_proc& ul_h : ul_harqs) {
ul_h.new_slot(slot_rx); if (ul_h.clear_if_maxretx(slot_rx)) {
logger.info("SCHED: discarding rnti=0x%x, UL TB pid=%d. Cause: Maximum number of retx exceeded (%d)");
}
} }
} }

@ -26,7 +26,7 @@ ue_carrier::ue_carrier(uint16_t rnti_, const ue_cfg_t& uecfg_, const cell_params
cc(cell_params_.cc), cc(cell_params_.cc),
bwp_cfg(rnti_, cell_params_.bwps[0], uecfg_), bwp_cfg(rnti_, cell_params_.bwps[0], uecfg_),
cell_params(cell_params_), cell_params(cell_params_),
harq_ent(cell_params_.nof_prb()) harq_ent(rnti_, cell_params_.nof_prb(), SCHED_NR_MAX_HARQ, cell_params_.bwps[0].logger)
{} {}
void ue_carrier::set_cfg(const ue_cfg_t& ue_cfg) void ue_carrier::set_cfg(const ue_cfg_t& ue_cfg)
@ -34,6 +34,11 @@ void ue_carrier::set_cfg(const ue_cfg_t& ue_cfg)
bwp_cfg = bwp_ue_cfg(rnti, cell_params.bwps[0], ue_cfg); bwp_cfg = bwp_ue_cfg(rnti, cell_params.bwps[0], ue_cfg);
} }
void ue_carrier::new_slot(slot_point slot_tx)
{
harq_ent.new_slot(slot_tx - TX_ENB_DELAY);
}
slot_ue ue_carrier::try_reserve(slot_point pdcch_slot, uint32_t dl_pending_bytes, uint32_t ul_pending_bytes) slot_ue ue_carrier::try_reserve(slot_point pdcch_slot, uint32_t dl_pending_bytes, uint32_t ul_pending_bytes)
{ {
slot_point slot_rx = pdcch_slot - TX_ENB_DELAY; slot_point slot_rx = pdcch_slot - TX_ENB_DELAY;
@ -103,14 +108,6 @@ void ue::new_slot(slot_point pdcch_slot)
{ {
last_pdcch_slot = pdcch_slot; last_pdcch_slot = pdcch_slot;
for (auto& ue_cc_cfg : ue_cfg.carriers) {
auto& cc = carriers[ue_cc_cfg.cc];
if (cc != nullptr) {
// Update CC HARQ state
cc->harq_ent.new_slot(pdcch_slot - TX_ENB_DELAY);
}
}
// Compute pending DL/UL bytes for {rnti, pdcch_slot} // Compute pending DL/UL bytes for {rnti, pdcch_slot}
if (sched_cfg.sched_cfg.auto_refill_buffer) { if (sched_cfg.sched_cfg.auto_refill_buffer) {
dl_pending_bytes = 1000000; dl_pending_bytes = 1000000;
@ -142,10 +139,7 @@ void ue::new_slot(slot_point pdcch_slot)
slot_ue ue::try_reserve(slot_point pdcch_slot, uint32_t cc) slot_ue ue::try_reserve(slot_point pdcch_slot, uint32_t cc)
{ {
if (carriers[cc] == nullptr) { srsran_assert(carriers[cc] != nullptr, "try_reserve() called for inexistent rnti=0x%x,cc=%d", rnti, cc);
return slot_ue();
}
return carriers[cc]->try_reserve(pdcch_slot, dl_pending_bytes, ul_pending_bytes); return carriers[cc]->try_reserve(pdcch_slot, dl_pending_bytes, ul_pending_bytes);
} }

@ -80,6 +80,9 @@ void slot_cc_worker::run(slot_point pdcch_slot, ue_map_t& ue_db)
continue; continue;
} }
// Update UE CC state
u.carriers[cfg.cc]->new_slot(pdcch_slot);
// info for a given UE on a slot to be process // info for a given UE on a slot to be process
slot_ues.insert(rnti, u.try_reserve(pdcch_slot, cfg.cc)); slot_ues.insert(rnti, u.try_reserve(pdcch_slot, cfg.cc));
if (slot_ues[rnti].empty()) { if (slot_ues[rnti].empty()) {
@ -374,7 +377,7 @@ void sched_worker_manager::get_metrics_nolocking(mac_metrics_t& metrics)
{ {
for (mac_ue_metrics_t& ue_metric : metrics.ues) { for (mac_ue_metrics_t& ue_metric : metrics.ues) {
if (ue_db.contains(ue_metric.rnti) and ue_db[ue_metric.rnti]->carriers[0] != nullptr) { if (ue_db.contains(ue_metric.rnti) and ue_db[ue_metric.rnti]->carriers[0] != nullptr) {
auto& ue_cc = *ue_db[ue_metric.rnti]->carriers[0]; auto& ue_cc = *ue_db[ue_metric.rnti]->carriers[0];
std::lock_guard<std::mutex> lock(ue_cc.metrics_mutex); std::lock_guard<std::mutex> lock(ue_cc.metrics_mutex);
ue_metric.tx_brate = ue_cc.metrics.tx_brate; ue_metric.tx_brate = ue_cc.metrics.tx_brate;
ue_metric.tx_errors = ue_cc.metrics.tx_errors; ue_metric.tx_errors = ue_cc.metrics.tx_errors;

@ -57,6 +57,7 @@ void test_single_prach()
auto run_slot = [&alloc, &rasched, &pdcch_slot, &slot_ues, &u]() -> const bwp_slot_grid* { auto run_slot = [&alloc, &rasched, &pdcch_slot, &slot_ues, &u]() -> const bwp_slot_grid* {
mac_logger.set_context(pdcch_slot.to_uint()); mac_logger.set_context(pdcch_slot.to_uint());
u.new_slot(pdcch_slot); u.new_slot(pdcch_slot);
u.carriers[0]->new_slot(pdcch_slot);
slot_ues.clear(); slot_ues.clear();
slot_ue sfu = u.try_reserve(pdcch_slot, 0); slot_ue sfu = u.try_reserve(pdcch_slot, 0);
if (not sfu.empty()) { if (not sfu.empty()) {

Loading…
Cancel
Save