diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index fc563b56b9..d123d53063 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -859,14 +859,11 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, .dmrs_info = dmrs_info, }; + const int bwpStart = sched_pusch.bwp_info.bwpStart; + const int bwpSize = sched_pusch.bwp_info.bwpSize; int rbStart = 0; - for (int i = 0; (i < ra->msg3_nb_rb) && (rbStart <= (sched_pusch.bwp_info.bwpSize - ra->msg3_nb_rb)); i++) { - if (vrb_map_UL[rbStart + sched_pusch.bwp_info.bwpStart + i] & SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) { - rbStart += i; - i = 0; - } - } - if (rbStart > (sched_pusch.bwp_info.bwpSize - ra->msg3_nb_rb)) { + int rbSize = 0; + if (!get_rb_alloc(ra->msg3_nb_rb, ra->msg3_nb_rb, bwpStart, bwpSize, vrb_map_UL, msg3_mask, &rbStart, &rbSize)) { // cannot find free vrb_map for msg3 retransmission in this slot reset_beam_status(&nr_mac->beam_info, sched_frame, sched_slot, UE->UE_beam_index, slots_frame, beam_ul.new_beam); reset_beam_status(&nr_mac->beam_info, frame, slot, UE->UE_beam_index, slots_frame, beam_dci.new_beam); @@ -980,7 +977,7 @@ static void nr_generate_Msg3_retransmission(module_id_t module_idP, beam_dci.idx); for (int rb = 0; rb < ra->msg3_nb_rb; rb++) { - vrb_map_UL[rbStart + sched_pusch.bwp_info.bwpStart + rb] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); + vrb_map_UL[rbStart + sched_pusch.bwp_info.bwpStart + rb] |= msg3_mask; } // Restart RA contention resolution timer in Msg3 retransmission slot (current slot + K2) @@ -1064,6 +1061,7 @@ static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, fra int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; SLIV2SL(startSymbolAndLength, &ra->msg3_startsymb, &ra->msg3_nbSymb); + const uint16_t msg3_mask = SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb); const int buffer_index = ul_buffer_index(ra->Msg3_frame, ra->Msg3_slot, @@ -1083,18 +1081,9 @@ static bool nr_get_Msg3alloc(gNB_MAC_INST *mac, int CC_id, int current_slot, fra /* search msg3_nb_rb free RBs */ int rbSize = 0; int rbStart = 0; - while (rbSize < msg3_nb_rb) { - rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ - rbSize = 0; - while (rbStart < bwpSize && (vrb_map_UL[rbStart + bwpStart] & SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb))) - rbStart++; - if (rbStart + msg3_nb_rb > bwpSize) { - LOG_D(NR_MAC, "No space to allocate Msg 3\n"); - return false; - } - while (rbStart + rbSize < bwpSize - && !(vrb_map_UL[rbStart + bwpStart + rbSize] & SL_to_bitmap(ra->msg3_startsymb, ra->msg3_nbSymb)) && rbSize < msg3_nb_rb) - rbSize++; + if (!get_rb_alloc(msg3_nb_rb, msg3_nb_rb, bwpStart, bwpSize, vrb_map_UL, msg3_mask, &rbStart, &rbSize)) { + LOG_D(NR_MAC, "No space to allocate Msg 3\n"); + return false; } ra->msg3_nb_rb = msg3_nb_rb; ra->msg3_first_rb = rbStart; @@ -1476,10 +1465,6 @@ static void nr_generate_Msg2(module_id_t module_idP, return; } - int mcsIndex = -1; // initialization value - int rbStart = 0; - int rbSize = 8; - bwp_info_t bwp_info = get_pdsch_bwp_start_size(nr_mac, UE); NR_ControlResourceSet_t *coreset = sched_ctrl->coreset; AssertFatal(coreset, "Coreset cannot be null for RA-Msg2\n"); const int coresetid = coreset->controlResourceSetId; @@ -1499,15 +1484,13 @@ static void nr_generate_Msg2(module_id_t module_idP, if (!tda_info.valid_tda) return; + int rbStart = 0; + int rbSize = 0; + uint16_t msg2_nb_rb = max(8, nr_mac->min_grant_prb); // RAR TBS is 9 bytes + const uint16_t msg2_mask = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); + bwp_info_t bwp_info = get_pdsch_bwp_start_size(nr_mac, UE); uint16_t *vrb_map = cc[CC_id].vrb_map[beam.idx]; - for (int i = 0; (i < rbSize) && (rbStart <= (bwp_info.bwpSize - rbSize)); i++) { - if (vrb_map[bwp_info.bwpStart + rbStart + i] & SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) { - rbStart += i; - i = 0; - } - } - - if (rbStart > (bwp_info.bwpSize - rbSize)) { + if (!get_rb_alloc(msg2_nb_rb, msg2_nb_rb, bwp_info.bwpStart, bwp_info.bwpSize, vrb_map, msg2_mask, &rbStart, &rbSize)) { LOG_W(NR_MAC, "Cannot find free vrb_map for RA RNTI %04x!\n", ra->RA_rnti); reset_beam_status(&nr_mac->beam_info, ra->Msg3_frame, ra->Msg3_slot, UE->UE_beam_index, n_slots_frame, ra->Msg3_beam.new_beam); reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam); @@ -1568,6 +1551,7 @@ static void nr_generate_Msg2(module_id_t module_idP, NR_pdsch_dmrs_t dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, &tda_info, 1); + int mcsIndex = -1; // initialization value uint8_t tb_scaling = 0; int R, Qm; uint32_t TBS = 0; @@ -1665,7 +1649,7 @@ static void nr_generate_Msg2(module_id_t module_idP, // Mark the corresponding symbols RBs as used fill_pdcch_vrb_map(nr_mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, aggregation_level, beam.idx); for (int rb = 0; rb < rbSize; rb++) { - vrb_map[bwp_info.bwpStart + rb + rbStart] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); + vrb_map[bwp_info.bwpStart + rb + rbStart] |= msg2_mask; } // In CFRA: in Msg3 handling, will unconditionally mark succeeded @@ -1764,14 +1748,6 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP, return; } - NR_pdsch_dmrs_t dmrs_info = get_dl_dmrs_params(scc, dl_bwp, &msg4_tda, 1); - bwp_info_t bwp_info = get_pdsch_bwp_start_size(nr_mac, UE); - uint8_t mcsTableIdx = dl_bwp->mcsTableIdx; - uint8_t mcsIndex = 0; - int rbStart = 0; - int rbSize = 0; - uint8_t tb_scaling = 0; - uint32_t tb_size = 0; uint16_t pdu_length; if(current_harq_pid >= 0) { // in case of retransmission NR_UE_harq_t *harq = &sched_ctrl->harq_processes[current_harq_pid]; @@ -1783,16 +1759,23 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP, // BI MAC subheader (1 Oct) + SuccessRAR MAC subheader (1 Oct) + SuccessRAR (11 Oct) } + NR_pdsch_dmrs_t dmrs_info = get_dl_dmrs_params(scc, dl_bwp, &msg4_tda, 1); + bwp_info_t bwp_info = get_pdsch_bwp_start_size(nr_mac, UE); + uint8_t mcsTableIdx = dl_bwp->mcsTableIdx; + uint8_t mcsIndex = 0; + uint8_t tb_scaling = 0; + uint32_t tb_size = 0; + int msg4_nr_rb = 0; // increase PRBs until we get to BWPSize or TBS is bigger than MAC PDU size do { - if(rbSize < bwp_info.bwpSize) - rbSize++; + if(msg4_nr_rb < bwp_info.bwpSize) + msg4_nr_rb++; else mcsIndex++; LOG_D(NR_MAC,"Calling nr_compute_tbs with N_PRB_DMRS %d, N_DMRS_SLOT %d\n",dmrs_info.N_PRB_DMRS,dmrs_info.N_DMRS_SLOT); tb_size = nr_compute_tbs(nr_get_Qm_dl(mcsIndex, mcsTableIdx), nr_get_code_rate_dl(mcsIndex, mcsTableIdx), - rbSize, + msg4_nr_rb, msg4_tda.nrOfSymbols, dmrs_info.N_PRB_DMRS * dmrs_info.N_DMRS_SLOT, 0, @@ -1801,18 +1784,11 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP, AssertFatal(tb_size >= pdu_length, "Cannot allocate %s\n", ra_type_str); - int i = 0; + int rbStart = 0; + int rbSize = 0; + const uint16_t msg4_mask = SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols); uint16_t *vrb_map = cc[CC_id].vrb_map[beam.idx]; - while ((i < rbSize) && (rbStart + rbSize <= bwp_info.bwpSize)) { - if (vrb_map[bwp_info.bwpStart + rbStart + i]&SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols)) { - rbStart += i+1; - i = 0; - } else { - i++; - } - } - - if (rbStart > (bwp_info.bwpSize - rbSize)) { + if (!get_rb_alloc(msg4_nr_rb, msg4_nr_rb, bwp_info.bwpStart, bwp_info.bwpSize, vrb_map, msg4_mask, &rbStart, &rbSize)) { LOG_E(NR_MAC, "Cannot find free vrb_map for RNTI %04x!\n", UE->rnti); reset_beam_status(&nr_mac->beam_info, frameP, slotP, UE->UE_beam_index, n_slots_frame, beam.new_beam); return; @@ -1953,7 +1929,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP, aggregation_level, beam.idx); for (int rb = 0; rb < rbSize; rb++) { - vrb_map[bwp_info.bwpStart + rb + rbStart] |= SL_to_bitmap(msg4_tda.startSymbolIndex, msg4_tda.nrOfSymbols); + vrb_map[bwp_info.bwpStart + rb + rbStart] |= msg4_mask; } ra->ra_state = nrRA_WAIT_Msg4_MsgB_ACK; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index c6d130cdaf..87584b5709 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -257,37 +257,31 @@ static bool update_rb_mcs_tbs(NR_sched_pdsch_t *pdsch, uint32_t num_total_bytes, const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); int bwpSize = pdsch->bwp_info.bwpSize; int bwpStart = pdsch->bwp_info.bwpStart; - int rbStop = bwpSize - 1; - while (pdsch->rbStart < rbStop) { - if (vrb_map[pdsch->rbStart + bwpStart] & slbitmap) - pdsch->rbStart++; - else { - int max_rbSize = 0; - while (pdsch->rbStart + max_rbSize <= rbStop && !(vrb_map[pdsch->rbStart + max_rbSize + bwpStart] & slbitmap)) - max_rbSize++; - bool res = false; - while (res == false && pdsch->mcs < 10) { - pdsch->Qm = nr_get_Qm_dl(pdsch->mcs, mcsTableIdx); - pdsch->R = nr_get_code_rate_dl(pdsch->mcs, mcsTableIdx); - res = nr_find_nb_rb(pdsch->Qm, - pdsch->R, - 1, // no transform precoding for DL - 1, // single layer - tda_info->nrOfSymbols, - pdsch->dmrs_parms.N_PRB_DMRS * pdsch->dmrs_parms.N_DMRS_SLOT, - num_total_bytes, - 1, // min_rbSize - max_rbSize, - &pdsch->tb_size, - &pdsch->rbSize); - if (!res) - pdsch->mcs++; - } + for (pdsch->mcs = 0; pdsch->mcs < 10; pdsch->mcs++) { + pdsch->Qm = nr_get_Qm_dl(pdsch->mcs, mcsTableIdx); + pdsch->R = nr_get_code_rate_dl(pdsch->mcs, mcsTableIdx); + if (!nr_find_nb_rb(pdsch->Qm, + pdsch->R, + 1, // no transform precoding for DL + 1, // single layer + tda_info->nrOfSymbols, + pdsch->dmrs_parms.N_PRB_DMRS * pdsch->dmrs_parms.N_DMRS_SLOT, + num_total_bytes, + 1, // min_rbSize + bwpSize, // max_rbSize, + &pdsch->tb_size, + &pdsch->rbSize)) + continue; + int rbStart, rbSize; + if (get_rb_alloc(pdsch->rbSize, pdsch->rbSize, bwpStart, bwpSize, vrb_map, slbitmap, &rbStart, &rbSize)) { + pdsch->rbStart = rbStart; + pdsch->rbSize = rbSize; break; } } - if (pdsch->tb_size < num_total_bytes) { + + if (pdsch->mcs >= 10 || pdsch->tb_size < num_total_bytes) { LOG_D(NR_MAC, "Couldn't allocate enough resources for %d bytes in SIB PDSCH (rbStart %d, rbSize %d, bwpSize %d)\n", num_total_bytes, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index dbf285e931..af3eccfeae 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -478,47 +478,24 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac, uint16_t *rballoc_mask = nr_mac->common_channels[CC_id].vrb_map[beam_idx]; bwp_info_t bwp_info = get_pdsch_bwp_start_size(nr_mac, UE); - int rbStart = bwp_info.bwpStart; - int rbStop = bwp_info.bwpStart + bwp_info.bwpSize - 1; + const int bwp_start = bwp_info.bwpStart; + const int bwp_size = bwp_info.bwpSize; + // WRT the BWP start, the RBs are indexed from 0 to bwpSize-1 + int rbStart = 0; int rbSize = 0; if (reuse_old_tda && layers == new_sched.nrOfLayers) { /* Check that there are enough resources for retransmission */ - while (rbSize < new_sched.rbSize) { - rbStart += rbSize; /* last iteration rbSize was not enough, skip it */ - rbSize = 0; - - const uint16_t slbitmap = SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols); - while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap)) - rbStart++; - - if (rbStart >= rbStop) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot); - return false; - } - - while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap) && rbSize < new_sched.rbSize) - rbSize++; - DevAssert(rbSize > 0); + const uint16_t slbitmap = SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols); + if (!get_rb_alloc(new_sched.rbSize, new_sched.rbSize, bwp_start, bwp_size, rballoc_mask, slbitmap, &rbStart, &rbSize)) { + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot); + return false; } } else { /* the retransmission will use a different time domain allocation, check * that we have enough resources */ NR_pdsch_dmrs_t temp_dmrs = get_dl_dmrs_params(scc, dl_bwp, &temp_tda, layers); - const uint16_t slbitmap = SL_to_bitmap(temp_tda.startSymbolIndex, temp_tda.nrOfSymbols); - while (rbStart < rbStop && (rballoc_mask[rbStart] & slbitmap)) - rbStart++; - - if (rbStart >= rbStop) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot); - return false; - } - - while (rbStart + rbSize <= rbStop && !(rballoc_mask[rbStart + rbSize] & slbitmap)) - rbSize++; - DevAssert(rbSize > 0); - uint32_t new_tbs; uint16_t new_rbSize; bool success = nr_find_nb_rb(new_sched.Qm, @@ -529,7 +506,7 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac, temp_dmrs.N_PRB_DMRS * temp_dmrs.N_DMRS_SLOT, new_sched.tb_size, 1, /* minimum of 1RB: need to find exact TBS, don't preclude any number */ - rbSize, + bwp_size, &new_tbs, &new_rbSize); @@ -543,6 +520,12 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac, return false; /* the maximum TBsize we might have is smaller than what we need */ } + const uint16_t slbitmap = SL_to_bitmap(temp_tda.startSymbolIndex, temp_tda.nrOfSymbols); + if (!get_rb_alloc(new_rbSize, new_rbSize, bwp_start, bwp_size, rballoc_mask, slbitmap, &rbStart, &rbSize)) { + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate DL retransmission: no resources\n", UE->rnti, frame, slot); + return false; + } + /* we can allocate it. Overwrite the time_domain_allocation, the number * of RBs, and the new TB size. The rest is done below */ new_sched.tb_size = new_tbs; @@ -587,7 +570,7 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac, sched_ctrl->cce_index = CCEIndex; fill_pdcch_vrb_map(nr_mac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, beam_idx); - new_sched.rbStart = rbStart - bwp_info.bwpStart; + new_sched.rbStart = rbStart; new_sched.pucch_allocation = alloc; new_sched.bwp_info = bwp_info; @@ -596,7 +579,7 @@ static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac, /* retransmissions: directly allocate */ *n_rb_sched -= new_sched.rbSize; - for (int rb = rbStart; rb < new_sched.rbSize; rb++) + for (int rb = new_sched.bwp_info.bwpStart + new_sched.rbStart; rb < new_sched.bwp_info.bwpStart + new_sched.rbStart + new_sched.rbSize; rb++) rballoc_mask[rb] |= SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols); return true; @@ -824,26 +807,18 @@ static void pf_dl(gNB_MAC_INST *mac, uint16_t *rballoc_mask = mac->common_channels[CC_id].vrb_map[beam.idx]; bwp_info_t bwp_info = get_pdsch_bwp_start_size(mac, iterator->UE); int rbStart = 0; // WRT BWP start - int rbStop = bwp_info.bwpSize - 1; int bwp_start = bwp_info.bwpStart; + int bwp_size = bwp_info.bwpSize; // Freq-demain allocation - while (rbStart < rbStop && (rballoc_mask[rbStart + bwp_start] & slbitmap)) - rbStart++; - - uint16_t max_rbSize = 1; - - while (rbStart + max_rbSize <= rbStop && !(rballoc_mask[rbStart + max_rbSize + bwp_start] & slbitmap)) - max_rbSize++; - - if (max_rbSize < min_rbSize) { + int max_rbSize = 0; + if (!get_rb_alloc(min_rbSize, bwp_size, bwp_start, bwp_size, rballoc_mask, slbitmap, &rbStart, &max_rbSize)) { LOG_D(NR_MAC, - "(%d.%d) Cannot schedule RNTI %04x, rbStart %d, rbSize %d, rbStop %d\n", + "(%d.%d) Cannot schedule RNTI %04x, rbStart %d, rbSize %d\n", frame, slot, rnti, rbStart, - max_rbSize, - rbStop); + max_rbSize); reset_beam_status(&mac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam); iterator++; continue; @@ -932,8 +907,8 @@ static void pf_dl(gNB_MAC_INST *mac, /* transmissions: directly allocate */ n_rb_sched[beam.idx] -= sched_pdsch.rbSize; - for (int rb = bwp_start; rb < sched_pdsch.rbSize; rb++) - rballoc_mask[rb + sched_pdsch.rbStart] |= slbitmap; + for (int rb = bwp_start + sched_pdsch.rbStart; rb < bwp_start + sched_pdsch.rbStart + sched_pdsch.rbSize; rb++) + rballoc_mask[rb] |= slbitmap; remainUEs[beam.idx]--; iterator++; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index ef8e001909..d74a52cafe 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -127,26 +127,10 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch) if (target_dl_bw>bwpSize) target_dl_bw = bwpSize; uint16_t *vrb_map = mac->common_channels[CC_id].vrb_map[beam.idx]; - /* loop ensures that we allocate exactly target_dl_bw, or return */ - while (true) { - /* advance to first free RB */ - while (rbStart < bwpSize && - (vrb_map[rbStart + BWPStart]&SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols))) - rbStart++; - rbSize = 1; - /* iterate until we are at target_dl_bw or no available RBs */ - while (rbStart + rbSize < bwpSize && - !(vrb_map[rbStart + rbSize + BWPStart]&SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) && - rbSize < target_dl_bw) - rbSize++; - /* found target_dl_bw? */ - if (rbSize == target_dl_bw) - break; - /* at end and below target_dl_bw? */ - if (rbStart + rbSize >= bwpSize) - return; - rbStart += rbSize; - } + const uint16_t slbitmap = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); + /* ensure that we allocate exactly target_dl_bw, or return */ + if (!get_rb_alloc(target_dl_bw, target_dl_bw, BWPStart, bwpSize, vrb_map, slbitmap, &rbStart, &rbSize)) + return; sched_ctrl->num_total_bytes = 0; DevAssert(seq_arr_size(&sched_ctrl->lc_config) == 1); @@ -218,7 +202,7 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch) /* mark the corresponding RBs as used */ for (int rb = 0; rb < sched_pdsch.rbSize; rb++) - vrb_map[rb + sched_pdsch.rbStart + BWPStart] = SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols); + vrb_map[rb + sched_pdsch.rbStart + BWPStart] = slbitmap; } uint32_t target_ul_mcs = 9; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 7b9a32f547..d103e38731 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -719,6 +719,45 @@ bool nr_find_nb_rb(uint16_t Qm, return *tbs >= bytes && *nb_rb <= nb_rb_max; } +bool get_rb_alloc(int rbSize_min, + int rbSize_max, + int bwpStart, + int bwpSize, + const uint16_t *vrb_map, + uint16_t sym_mask, + int *rbStart_ptr, + int *rbSize_ptr) +{ + const uint16_t *bwp_map = &vrb_map[bwpStart]; + int rbStart = 0; + while (rbStart + rbSize_min <= bwpSize) { + // 1. Find the first free RB + if ((bwp_map[rbStart] & sym_mask) != 0) { + rbStart++; + continue; + } + + // 2. Measure contiguous block + int current_limit = min(rbStart + rbSize_max, bwpSize); + int rbEnd = rbStart + 1; + while (rbEnd < current_limit && (bwp_map[rbEnd] & sym_mask) == 0) { + rbEnd++; + } + int rbSize = rbEnd - rbStart; + + // 3. Validate + if (rbSize >= rbSize_min) { + *rbStart_ptr = rbStart; + *rbSize_ptr = rbSize; + return true; + } + + // Skip the block we just checked + the occupied one that stopped us + rbStart = rbEnd + 1; + } + return false; +} + const NR_DMRS_UplinkConfig_t *get_DMRS_UplinkConfig(const NR_PUSCH_Config_t *pusch_Config, const NR_tda_info_t *tda_info) { if (pusch_Config == NULL) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 0998eb463b..1890c7413c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -1715,9 +1715,9 @@ static void nr_ue_max_mcs_min_rb(int mu, int ph_limit, NR_sched_pusch_t *sched_pusch, NR_UE_UL_BWP_t *ul_bwp, - uint16_t minRb, - uint32_t tbs, - uint16_t *Rb, + int minRb, + int tbs, + int *Rb, uint8_t *mcs) { AssertFatal(*Rb >= minRb, "illegal Rb %d < minRb %d\n", *Rb, minRb); @@ -1810,6 +1810,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; int rbStart = 0; // wrt BWP start + int rbSize = 0; bwp_info_t bwp_info = get_pusch_bwp_start_size(UE); const uint32_t bwpSize = bwp_info.bwpSize; const uint32_t bwpStart = bwp_info.bwpStart; @@ -1827,10 +1828,9 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, if (reuse_old_tda && nrOfLayers == retInfo->nrOfLayers) { /* Check the resource is enough for retransmission */ const uint16_t slbitmap = SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols); - while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap)) - rbStart++; - if (rbStart + retInfo->rbSize > bwpSize) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d) \n", + if (!get_rb_alloc(retInfo->rbSize, retInfo->rbSize, bwpStart, bwpSize, rballoc_mask, slbitmap, &rbStart, &rbSize)) { + LOG_D(NR_MAC, + "[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources (rbStart %d, retInfo->rbSize %d, bwpSize %d) \n", UE->rnti, frame, slot, @@ -1845,16 +1845,6 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, NR_pusch_dmrs_t dmrs_info = get_ul_dmrs_params(scc, ul_bwp, tda_info, nrOfLayers); /* the retransmission will use a different time domain allocation, check * that we have enough resources */ - const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); - while (rbStart < bwpSize && (rballoc_mask[rbStart + bwpStart] & slbitmap)) - rbStart++; - if (rbStart >= bwpSize) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources\n", UE->rnti, frame, slot); - return false; - } - int rbSize = 0; - while (rbStart + rbSize < bwpSize && !(rballoc_mask[rbStart + bwpStart + rbSize] & slbitmap)) - rbSize++; uint32_t new_tbs; uint16_t new_rbSize; bool success = nr_find_nb_rb(retInfo->Qm, @@ -1865,11 +1855,12 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, dmrs_info.N_PRB_DMRS * dmrs_info.num_dmrs_symb, retInfo->tb_size, 1, /* minimum of 1RB: need to find exact TBS, don't preclude any number */ - rbSize, + bwpSize, &new_tbs, &new_rbSize); if (!success || new_tbs != retInfo->tb_size) { - LOG_D(NR_MAC, "[UE %04x][%4d.%2d] allocation of UL retransmission failed: new TBsize %d of new TDA does not match old TBS %d \n", + LOG_D(NR_MAC, + "[UE %04x][%4d.%2d] allocation of UL retransmission failed: new TBsize %d of new TDA does not match old TBS %d \n", UE->rnti, frame, slot, @@ -1877,7 +1868,19 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, retInfo->tb_size); return false; /* the maximum TBsize we might have is smaller than what we need */ } - LOG_D(NR_MAC, "Retransmission with TDA %d->%d and TBS %d -> %d\n", retInfo->time_domain_allocation, tda, retInfo->tb_size, new_tbs); + + const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); + if (!get_rb_alloc(new_rbSize, new_rbSize, bwpStart, bwpSize, rballoc_mask, slbitmap, &rbStart, &rbSize)) { + LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL retransmission: no resources\n", UE->rnti, frame, slot); + return false; + } + + LOG_D(NR_MAC, + "Retransmission with TDA %d->%d and TBS %d -> %d\n", + retInfo->time_domain_allocation, + tda, + retInfo->tb_size, + new_tbs); /* we can allocate it. Overwrite the time_domain_allocation, the number * of RBs, and the new TB size. The rest is done below */ new_sched.rbSize = new_rbSize; @@ -1922,8 +1925,8 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, /* Mark the corresponding RBs as used */ n_rb_sched -= new_sched.rbSize; - for (int rb = bwpStart; rb < new_sched.rbSize; rb++) - rballoc_mask[rb + new_sched.rbStart] |= SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols); + for (int rb = bwpStart + new_sched.rbStart; rb < bwpStart + new_sched.rbStart + new_sched.rbSize; rb++) + rballoc_mask[rb] |= SL_to_bitmap(new_sched.tda_info.startSymbolIndex, new_sched.tda_info.nrOfSymbols); return true; } @@ -2178,18 +2181,13 @@ static int pf_ul(gNB_MAC_INST *nrmac, /* find maximum amount of RBs that we can schedule starting from first free RB */ int rbStart = 0; + int available_rb = 0; const uint16_t slbitmap = SL_to_bitmap(tda_info->startSymbolIndex, tda_info->nrOfSymbols); bwp_info_t bi = get_pusch_bwp_start_size(iterator->UE); - while (rbStart < bi.bwpSize && (rballoc_mask[rbStart + bi.bwpStart] & slbitmap)) - rbStart++; /* if it's for inactivity, min_grant_prb is enough, otherwise check what * would be the maximum */ uint16_t max_rbSize = iterator->sched_inactive ? min_rb : bi.bwpSize; - uint16_t available_rb = 1; - while (rbStart + available_rb < bi.bwpSize && !(rballoc_mask[rbStart + bi.bwpStart + available_rb] & slbitmap) && available_rb < max_rbSize) - available_rb++; - - if (rbStart + min_rb > bi.bwpSize || available_rb < min_rb) { + if (!get_rb_alloc(min_rb, max_rbSize, bi.bwpStart, bi.bwpSize, rballoc_mask, slbitmap, &rbStart, &available_rb)) { reset_beam_status(&nrmac->beam_info, frame, slot, iterator->UE->UE_beam_index, slots_per_frame, dci_beam.new_beam); reset_beam_status(&nrmac->beam_info, sched_frame, sched_slot, iterator->UE->UE_beam_index, slots_per_frame, beam.new_beam); LOG_D(NR_MAC, "[UE %04x][%4d.%2d] could not allocate UL data: no resources (rbStart %d, min_rb %d, bwpSize %d)\n", @@ -2300,8 +2298,8 @@ static int pf_ul(gNB_MAC_INST *nrmac, post_process_ulsch(nrmac, pp_pusch, iterator->UE, &sched); n_rb_sched[beam.idx] -= sched.rbSize; - for (int rb = bi.bwpStart; rb < sched.rbSize; rb++) - rballoc_mask[rb + sched.rbStart] |= slbitmap; + for (int rb = bi.bwpStart + sched.rbStart; rb < bi.bwpStart + sched.rbStart + sched.rbSize; rb++) + rballoc_mask[rb] |= slbitmap; /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ remainUEs[beam.idx]--; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 5a59ed67af..27bab01d65 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -439,6 +439,27 @@ bool nr_find_nb_rb(uint16_t Qm, uint32_t *tbs, uint16_t *nb_rb); +/** + * \brief Function to return a free block of RBs of a required size within an BWP + * \param rbSize_min Minimum size of the free block of RBs + * \param rbSize_max Maximum size of the free block of RBs + * \param bwpStart Start RB of the BWP + * \param bwpSize Size of the BWP in RBs + * \param vrb_map Pointer to the RB allocation map + * \param sym_mask Mask indicating the symbols to be used in the block of RBs + * \param rbStart_ptr Pointer returning the start RB of the found free block + * \param rbSize_ptr Pointer returning the size of the found free block of RBs + * \return Indicates if a free block of RBs of the required size could be found and *rbStart_ptr and *rbSize_ptr are set accordingly + */ +bool get_rb_alloc(int rbSize_min, + int rbSize_max, + int bwpStart, + int bwpSize, + const uint16_t *vrb_map, + uint16_t sym_mask, + int *rbStart_ptr, + int *rbSize_ptr); + int get_mcs_from_bler(const NR_bler_options_t *bler_options, const NR_mac_dir_stats_t *stats, NR_bler_stats_t *bler_stats,