sched-nr: fix scheduler to pass nr tests

Signed-off-by: Carlo Galiotto <carlo@srs.io>
master
Carlo Galiotto 3 years ago committed by carlo-gal
parent 2b3158536a
commit c935484102

@ -61,7 +61,7 @@ public:
struct pdu_builder { struct pdu_builder {
pdu_builder() = default; pdu_builder() = default;
explicit pdu_builder(uint32_t cc_, ue_buffer_manager& parent_) : cc(cc_), parent(&parent_) {} explicit pdu_builder(uint32_t cc_, ue_buffer_manager& parent_) : cc(cc_), parent(&parent_) {}
bool alloc_subpdus(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu); bool alloc_subpdus(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu, bool reset_buf_states = false);
private: private:
uint32_t cc = SRSRAN_MAX_CARRIERS; uint32_t cc = SRSRAN_MAX_CARRIERS;
@ -180,9 +180,9 @@ public:
ul_harq_proc* find_empty_ul_harq() { return ue->harq_ent.find_empty_ul_harq(); } ul_harq_proc* find_empty_ul_harq() { return ue->harq_ent.find_empty_ul_harq(); }
/// Build PDU with MAC CEs and MAC SDUs /// Build PDU with MAC CEs and MAC SDUs
bool build_pdu(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu) bool build_pdu(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu, bool reset_buf_states = false)
{ {
return ue->pdu_builder.alloc_subpdus(rem_bytes, pdu); return ue->pdu_builder.alloc_subpdus(rem_bytes, pdu, reset_buf_states);
} }
/// Channel Information Getters /// Channel Information Getters

@ -385,15 +385,22 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, uint32_t ss_id, const
// Select scheduled LCIDs and update UE buffer state // Select scheduled LCIDs and update UE buffer state
bwp_pdsch_slot.dl.data.emplace_back(); bwp_pdsch_slot.dl.data.emplace_back();
// NOTE: ue.h_dl->tbs() has to be converted from bits to bytes // NOTES: 1) ue.h_dl->tbs() has to be converted from bits to bytes
bool segmented_ccch_pdu = not ue.build_pdu(ue.h_dl->tbs() / 8, bwp_pdsch_slot.dl.data.back()); // 2) In case of CCCH segmentation, we'll need to repeat the scheduling with a higher MCS. Hence, the
if (segmented_ccch_pdu) { // function ue.build_pdu() will reset the LCIDs and UE buffer states as before its execution if the flag
// "mcs<min_MCS_ccch" is true
bool segmented_ccch_pdu = not ue.build_pdu(ue.h_dl->tbs() / 8, bwp_pdsch_slot.dl.data.back(), mcs < min_MCS_ccch);
if (segmented_ccch_pdu and mcs < min_MCS_ccch) {
// In case of segmented PDU for CCCH, set minimum MCS to 4 and re-run the outer while loop // In case of segmented PDU for CCCH, set minimum MCS to 4 and re-run the outer while loop
bwp_pdsch_slot.dl.data.pop_back(); bwp_pdsch_slot.dl.data.pop_back();
mcs = min_MCS_ccch; mcs = min_MCS_ccch;
pdcch.dci.mcs = mcs; pdcch.dci.mcs = mcs;
logger.warning( logger.info("SCHED: MCS increased to min value %d to allocate SRB0/CCCH for rnti=0x%x", min_MCS_ccch, ue->rnti);
"SCHED: MCS increased to min value %d to allocate SRB0/CCCH for rnti=0x%x", min_MCS_ccch, ue->rnti); } else if (segmented_ccch_pdu /* and mcs >= min_MCS_ccch */) {
// With MCS >= then min_MCS_ccch, it is not possible to allocate SRB0/CCCH without PDU segmentation
logger.error("SCHED: Insufficient resources to allocate SRB0/CCCH without PDU segmentation for rnti=0x%x",
ue->rnti);
break;
} else { } else {
break; break;
} }

@ -27,8 +27,18 @@ int ue_buffer_manager::get_dl_tx_total() const
return total_bytes; return total_bytes;
} }
// Return true if there is no SRB0/CCCH MAC PDU segmentation, false otherwise /**
bool ue_buffer_manager::pdu_builder::alloc_subpdus(uint32_t rem_bytes, sched_nr_interface::dl_pdu_t& pdu) * @brief Allocates LCIDs and update US buffer states depending on available resources and checks if there is SRB0/CCCH
MAC PDU segmentation
* @param rem_bytes TBS to be filled with MAC CEs and MAC SDUs [in bytes]
* @param reset_buf_states If true, when there is SRB0/CCCH MAC PDU segmentation, restore the UE buffers and scheduled
LCIDs as before running this function
* @return true if there is no SRB0/CCCH MAC PDU segmentation, false otherwise
*/
bool ue_buffer_manager::pdu_builder::alloc_subpdus(uint32_t rem_bytes,
sched_nr_interface::dl_pdu_t& pdu,
bool reset_buf_states)
{ {
// In case of SRB0/CCCH PDUs, we need to check whether there is PDU segmentation; if LCID = 0 has emtpy buffer, no // In case of SRB0/CCCH PDUs, we need to check whether there is PDU segmentation; if LCID = 0 has emtpy buffer, no
// need to perform this check // need to perform this check
@ -47,10 +57,10 @@ bool ue_buffer_manager::pdu_builder::alloc_subpdus(uint32_t rem_bytes, sched_nr_
rem_bytes -= size_ce; rem_bytes -= size_ce;
pdu.subpdus.push_back(ce.lcid); pdu.subpdus.push_back(ce.lcid);
// If there is possibility of CCCH segmentation, we need to save the MAC CEs in a tmp queue to be later restored // If there is possibility of CCCH segmentation, we need to save the MAC CEs in a tmp queue to be later restored
if (check_ccch_pdu_segmentation) { if (check_ccch_pdu_segmentation and reset_buf_states) {
restore_ces.push_back(parent->pending_ces.front()); restore_ces.push_back(parent->pending_ces.front());
parent->pending_ces.pop_front();
} }
parent->pending_ces.pop_front();
} }
} }
@ -60,12 +70,16 @@ bool ue_buffer_manager::pdu_builder::alloc_subpdus(uint32_t rem_bytes, sched_nr_
// Verify if the TBS is big enough to store the entire CCCH buffer // Verify if the TBS is big enough to store the entire CCCH buffer
// Note: (pending_lcid_bytes > rem_bytes) implies (check_ccch_pdu_segmentation == true) // Note: (pending_lcid_bytes > rem_bytes) implies (check_ccch_pdu_segmentation == true)
if (lcid == srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CCCH and pending_lcid_bytes > rem_bytes) { if (lcid == srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CCCH and pending_lcid_bytes > rem_bytes) {
if (reset_buf_states) {
// restore the MAC CEs as they were at the beginning of the function // restore the MAC CEs as they were at the beginning of the function
for (ce_t ce : restore_ces) { for (ce_t ce : restore_ces) {
parent->pending_ces.push_back(ce); parent->pending_ces.push_back(ce);
} }
// double check if this line is required // double check if this line is required
pdu.subpdus.clear(); pdu.subpdus.clear();
} else {
pdu.subpdus.push_back(lcid);
}
return false; return false;
} }
if (pending_lcid_bytes > 0) { if (pending_lcid_bytes > 0) {

Loading…
Cancel
Save