auto scheduler ConRes CE when the DL CCCH buffer is filled

master
Francisco 3 years ago committed by Francisco Paisana
parent dface7e4af
commit afd7bb8631

@ -40,8 +40,7 @@ struct sched_nr_ue_cc_cfg_t {
};
struct sched_nr_ue_cfg_t {
bool is_temp_crnti = false;
uint32_t maxharq_tx = 4;
uint32_t maxharq_tx = 4;
srsran::bounded_vector<sched_nr_ue_cc_cfg_t, SCHED_NR_MAX_CARRIERS> carriers;
std::array<mac_lc_ch_cfg_t, SCHED_NR_MAX_LCID> ue_bearers = {};
srsran::phy_cfg_nr_t phy_cfg = {};

@ -56,9 +56,9 @@ public:
srsran::deque<ce_t> pending_ces;
/// Protected, thread-safe interface of "ue_buffer_manager" for "slot_ue"
struct slot_itf {
slot_itf() = default;
explicit slot_itf(uint32_t cc_, ue_buffer_manager& parent_) : cc(cc_), parent(&parent_) {}
struct pdu_builder {
pdu_builder() = default;
explicit pdu_builder(uint32_t cc_, ue_buffer_manager& parent_) : cc(cc_), parent(&parent_) {}
void alloc_subpdus(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu);
private:
@ -76,7 +76,10 @@ class slot_ue;
class ue_carrier
{
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_,
const ue_buffer_manager::pdu_builder& pdu_builder_);
void set_cfg(const ue_cfg_t& ue_cfg);
const ue_carrier_params_t& cfg() const { return bwp_cfg; }
@ -94,6 +97,8 @@ public:
harq_entity harq_ent;
ue_buffer_manager::pdu_builder pdu_builder;
// metrics
mac_ue_metrics_t metrics = {};
@ -117,7 +122,7 @@ public:
const ue_cfg_t& cfg() const { return ue_cfg; }
void mac_buffer_state(uint32_t ce_lcid, uint32_t nof_cmds = 1);
void rlc_buffer_state(uint32_t lcid, uint32_t newtx, uint32_t retx) { buffers.dl_buffer_state(lcid, newtx, retx); }
void rlc_buffer_state(uint32_t lcid, uint32_t newtx, uint32_t retx);
/// UE state feedback
void ul_bsr(uint32_t lcg, uint32_t bsr_val) { buffers.ul_bsr(lcg, bsr_val); }
@ -151,11 +156,7 @@ class slot_ue
{
public:
slot_ue() = default;
explicit slot_ue(ue_carrier& ue,
slot_point slot_tx_,
uint32_t dl_pending_bytes,
uint32_t ul_pending_bytes,
ue_buffer_manager::slot_itf buffers_);
explicit slot_ue(ue_carrier& ue, slot_point slot_tx_, uint32_t dl_pending_bytes, uint32_t ul_pending_bytes);
slot_ue(slot_ue&&) noexcept = default;
slot_ue& operator=(slot_ue&&) noexcept = default;
bool empty() const { return ue == nullptr; }
@ -169,19 +170,23 @@ public:
dl_harq_proc* find_empty_dl_harq() { return ue->harq_ent.find_empty_dl_harq(); }
ul_harq_proc* find_empty_ul_harq() { return ue->harq_ent.find_empty_ul_harq(); }
void build_pdu(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu)
{
ue->pdu_builder.alloc_subpdus(rem_bytes, pdu);
}
// UE parameters common to all sectors
uint32_t dl_bytes = 0, ul_bytes = 0;
// UE parameters that are sector specific
bool dl_active;
bool ul_active;
slot_point pdcch_slot;
slot_point pdsch_slot;
slot_point pusch_slot;
slot_point uci_slot;
dl_harq_proc* h_dl = nullptr;
ul_harq_proc* h_ul = nullptr;
ue_buffer_manager::slot_itf buffers;
bool dl_active;
bool ul_active;
slot_point pdcch_slot;
slot_point pdsch_slot;
slot_point pusch_slot;
slot_point uci_slot;
dl_harq_proc* h_dl = nullptr;
ul_harq_proc* h_ul = nullptr;
private:
ue_carrier* ue = nullptr;

@ -330,7 +330,6 @@ void mac_nr::rach_detected(const rach_info_t& rach_info)
// Add new user to the scheduler so that it can RX/TX SRB0
sched_nr_ue_cfg_t uecfg = {};
uecfg.is_temp_crnti = true;
uecfg.carriers.resize(1);
uecfg.carriers[0].active = true;
uecfg.carriers[0].cc = enb_cc_idx;

@ -339,7 +339,7 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr
// Select scheduled LCIDs and update UE buffer state
bwp_pdsch_slot.dl.data.emplace_back();
ue.buffers.alloc_subpdus(ue.h_dl->tbs(), bwp_pdsch_slot.dl.data.back());
ue.build_pdu(ue.h_dl->tbs(), bwp_pdsch_slot.dl.data.back());
return alloc_result::success;
}

@ -27,7 +27,7 @@ int ue_buffer_manager::get_dl_tx_total() const
return total_bytes;
}
void ue_buffer_manager::slot_itf::alloc_subpdus(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu)
void ue_buffer_manager::pdu_builder::alloc_subpdus(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu)
{
for (ce_t ce : parent->pending_ces) {
if (ce.cc == cc) {
@ -53,12 +53,8 @@ void ue_buffer_manager::slot_itf::alloc_subpdus(uint32_t rem_bytes, sched_nr_int
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
slot_ue::slot_ue(ue_carrier& ue_,
slot_point slot_tx_,
uint32_t dl_pending_bytes,
uint32_t ul_pending_bytes,
ue_buffer_manager::slot_itf buffers_) :
ue(&ue_), pdcch_slot(slot_tx_), buffers(buffers_)
slot_ue::slot_ue(ue_carrier& ue_, slot_point slot_tx_, uint32_t dl_pending_bytes, uint32_t ul_pending_bytes) :
ue(&ue_), pdcch_slot(slot_tx_)
{
const uint32_t k0 = 0;
pdsch_slot = pdcch_slot + k0;
@ -89,12 +85,16 @@ slot_ue::slot_ue(ue_carrier& ue_,
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ue_carrier::ue_carrier(uint16_t rnti_, const ue_cfg_t& uecfg_, const cell_params_t& cell_params_) :
ue_carrier::ue_carrier(uint16_t rnti_,
const ue_cfg_t& uecfg_,
const cell_params_t& cell_params_,
const ue_buffer_manager::pdu_builder& pdu_builder_) :
rnti(rnti_),
cc(cell_params_.cc),
logger(srslog::fetch_basic_logger(cell_params_.sched_args.logger_name)),
bwp_cfg(rnti_, cell_params_.bwps[0], uecfg_),
cell_params(cell_params_),
pdu_builder(pdu_builder_),
harq_ent(rnti_, cell_params_.nof_prb(), SCHED_NR_MAX_HARQ, cell_params_.bwps[0].logger)
{}
@ -138,13 +138,12 @@ ue::ue(uint16_t rnti_, const ue_cfg_t& cfg, const sched_params_t& sched_cfg_) :
void ue::set_cfg(const ue_cfg_t& cfg)
{
bool conres_needed = not cfg.is_temp_crnti and ue_cfg.is_temp_crnti;
ue_cfg = cfg;
for (auto& ue_cc_cfg : cfg.carriers) {
if (ue_cc_cfg.active) {
if (carriers[ue_cc_cfg.cc] == nullptr) {
carriers[ue_cc_cfg.cc].reset(new ue_carrier(rnti, ue_cfg, sched_cfg.cells[ue_cc_cfg.cc]));
carriers[ue_cc_cfg.cc].reset(new ue_carrier(
rnti, ue_cfg, sched_cfg.cells[ue_cc_cfg.cc], ue_buffer_manager::pdu_builder{ue_cc_cfg.cc, buffers}));
} else {
carriers[ue_cc_cfg.cc]->set_cfg(ue_cfg);
}
@ -152,10 +151,6 @@ void ue::set_cfg(const ue_cfg_t& cfg)
}
buffers.config_lcids(cfg.ue_bearers);
if (conres_needed) {
mac_buffer_state(62, 1);
}
}
void ue::mac_buffer_state(uint32_t ce_lcid, uint32_t nof_cmds)
@ -166,6 +161,16 @@ void ue::mac_buffer_state(uint32_t ce_lcid, uint32_t nof_cmds)
}
}
void ue::rlc_buffer_state(uint32_t lcid, uint32_t newtx, uint32_t retx)
{
if (lcid == 0) {
// In case of DL-CCCH, schedule ConRes CE
// Note: use push_front because ConRes CE has priority
buffers.pending_ces.push_front({srsran::mac_sch_subpdu_nr::CON_RES_ID, cfg().carriers[0].cc});
}
buffers.dl_buffer_state(lcid, newtx, retx);
}
void ue::new_slot(slot_point pdcch_slot)
{
last_pdcch_slot = pdcch_slot;
@ -208,11 +213,7 @@ void ue::new_slot(slot_point pdcch_slot)
slot_ue ue::make_slot_ue(slot_point pdcch_slot, uint32_t cc)
{
srsran_assert(carriers[cc] != nullptr, "make_slot_ue() called for inexistent rnti=0x%x,cc=%d", rnti, cc);
return slot_ue(*carriers[cc],
pdcch_slot,
dl_pending_bytes,
ul_pending_bytes,
ue_buffer_manager::slot_itf{cfg().carriers[cc].cc, buffers});
return slot_ue(*carriers[cc], pdcch_slot, dl_pending_bytes, ul_pending_bytes);
}
} // namespace sched_nr_impl

@ -67,7 +67,6 @@ inline sched_nr_interface::ue_cfg_t get_rach_ue_cfg(uint32_t
srsran::phy_cfg_nr_default_t::reference_cfg_t{}})
{
sched_nr_interface::ue_cfg_t uecfg{};
uecfg.is_temp_crnti = true;
// set PCell
uecfg.carriers.resize(1);

@ -380,12 +380,13 @@ int sched_nr_base_tester::apply_slot_events(sim_nr_ue_ctxt_t& ue_ctxt, const ue_
"UL ACK rnti=0x%x, slot_ul_tx=%u, cc=%d pid=%d", ue_ctxt.rnti, h.last_slot_tx.to_uint(), enb_cc_idx, h.pid);
}
// update scheduler
sched_ptr->ul_crc_info(ue_ctxt.rnti, enb_cc_idx, ack.pid, ack.ack);
if (h.is_msg3) {
logger.info("STATUS: rnti=0x%x received Msg3", ue_ctxt.rnti);
sched_ptr->dl_buffer_state(ue_ctxt.rnti, 0, 150, 0); // Schedule RRC setup
}
// update scheduler
sched_ptr->ul_crc_info(ue_ctxt.rnti, enb_cc_idx, ack.pid, ack.ack);
}
}

@ -1216,7 +1216,6 @@ int rrc_nr::ue::update_rlc_bearers(const asn1::rrc_nr::cell_group_cfg_s& cell_gr
int rrc_nr::ue::update_mac(const cell_group_cfg_s& cell_group_diff, bool is_config_complete)
{
if (not is_config_complete) {
uecfg.is_temp_crnti = false;
// Release bearers
for (uint8_t lcid : cell_group_diff.rlc_bearer_to_release_list) {
uecfg.ue_bearers[lcid].direction = mac_lc_ch_cfg_t::IDLE;

Loading…
Cancel
Save