Commit dd980302 authored by Robert Schmidt's avatar Robert Schmidt

Refactor to call post-processor in place

Remove sched_ctrl->sched_ulsch, and call the post-processing function
post_process_ulsch() in the places where sched_ctrl->sched_ulsch has
been assigned. This will have two effects:

- it is not necessary to have the final loop over all UEs, which might
  be costly especially towards many UEs.
- till now, there is only a single sched_ulsch; however, a later commit
  will allow to schedule multiple PUSCH transmissions from a single (DL)
  slot. This would require to make sched_ctrl->sched_ulsch, and
  also iterate through all sched_ulsch. In this new scheme, we can
  simply call post_process_ulsch() multiple times, which is simpler (and
  therefore, implicitly handleded as of this commit).
parent d71cec79
......@@ -66,7 +66,7 @@ bool read_mac_sm(void* data)
}
if (is_ul_slot(rd->slot, &RC.nrmac[mod_id]->frame_structure)) {
rd->ul_curr_tbs = UE->mac_stats.ul.current_bytes;
rd->ul_sched_rb = sched_ctrl->sched_pusch.rbSize;
rd->ul_sched_rb = UE->mac_stats.ul.current_rbs;
}
rd->rnti = UE->rnti;
......
......@@ -208,9 +208,11 @@ uint32_t target_ul_mcs = 9;
uint32_t target_ul_bw = 50;
uint32_t target_ul_Nl = 1;
uint64_t ulsch_slot_bitmap = (1 << 8);
bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot)
void nr_ul_preprocessor_phytest(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch)
{
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
int frame = pp_pusch->frame;
int slot = pp_pusch->slot;
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
......@@ -219,7 +221,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slo
AssertFatal(nr_mac->UE_info.connected_ue_list[1] == NULL,
"cannot handle more than one UE\n");
if (UE == NULL)
return false;
return;
const int CC_id = 0;
......@@ -229,7 +231,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slo
/* return if all UL HARQ processes wait for feedback */
if (sched_ctrl->retrans_ul_harq.head == -1 && sched_ctrl->available_ul_harq.head == -1) {
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] UE has no free UL HARQ process, skipping\n", UE->rnti, frame, slot);
return false;
return;
}
const int bw = ul_bwp->BWPSize;
......@@ -243,7 +245,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slo
TYPE_C_RNTI_);
const int temp_tda = get_ul_tda(nr_mac, frame, slot);
if (temp_tda < 0)
return false;
return;
AssertFatal(temp_tda < tdaList->list.count, "time domain assignment %d >= %d\n", temp_tda, tdaList->list.count);
const int mu = ul_bwp->scs;
int K2 = get_K2(tdaList, temp_tda, mu, scc);
......@@ -252,17 +254,18 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slo
const int sched_slot = (slot + K2) % slots_frame;
const int tda = get_ul_tda(nr_mac, sched_frame, sched_slot);
if (tda < 0)
return false;
return;
AssertFatal(tda < tdaList->list.count,
"time domain assignment %d >= %d\n",
tda,
tdaList->list.count);
/* check if slot is UL, and that slot is 8 (assuming K2=6 because of UE
* limitations). Note that if K2 or the TDD configuration is changed, below
* conditions might exclude each other and never be true */
int slot_period = sched_slot % nr_mac->frame_structure.numb_slots_period;
if (!is_xlsch_in_slot(ulsch_slot_bitmap, slot_period))
return false;
return;
NR_tda_info_t tda_info = get_ul_tda_info(ul_bwp,
sched_ctrl->coreset->controlResourceSetId,
......@@ -270,7 +273,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slo
TYPE_C_RNTI_,
tda);
if (!tda_info.valid_tda)
return false;
return;
// TODO implement beam procedures for phy-test mode
int beam = 0;
......@@ -280,7 +283,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slo
for (int i = rbStart; i < rbStart + rbSize; ++i) {
if ((vrb_map_UL[i+BWPStart] & SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols)) != 0) {
LOG_E(MAC, "%4d.%2d RB %d is already reserved, cannot schedule UE\n", frame, slot, i);
return false;
return;
}
}
......@@ -295,7 +298,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slo
0);
if (CCEIndex < 0) {
LOG_E(MAC, "%s(): CCE list not empty, couldn't schedule PUSCH\n", __func__);
return false;
return;
}
sched_ctrl->cce_index = CCEIndex;
......@@ -337,7 +340,8 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slo
sched.nrOfLayers /* NrOfLayers */)
>> 3;
sched_ctrl->sched_pusch = sched;
/* save allocation to FAPI structures */
post_process_ulsch(nr_mac, pp_pusch, UE, &sched);
/* mark the corresponding RBs as used */
fill_pdcch_vrb_map(nr_mac,
......@@ -349,5 +353,4 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slo
for (int rb = rbStart; rb < rbStart + rbSize; rb++)
vrb_map_UL[rb+BWPStart] |= SL_to_bitmap(tda_info.startSymbolIndex, tda_info.nrOfSymbols);
return true;
}
......@@ -2692,7 +2692,6 @@ NR_UE_info_t *get_new_nr_ue_inst(uid_allocator_t *uia, rnti_t rnti, NR_CellGroup
/* set illegal time domain allocation to force recomputation of all fields */
sched_ctrl->sched_pdsch.time_domain_allocation = -1;
sched_ctrl->sched_pusch.time_domain_allocation = -1;
/* Set default BWPs */
AssertFatal(UE->sc_info.n_ul_bwp <= NR_MAX_NUM_BWP, "uplinkBWP_ToAddModList has %d BWP!\n", UE->sc_info.n_ul_bwp);
......
......@@ -1700,17 +1700,18 @@ static void nr_ue_max_mcs_min_rb(int mu,
}
static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
frame_t frame,
slot_t slot,
uint16_t *rballoc_mask,
int *n_rb_sched,
int dci_beam_idx,
NR_UE_info_t* UE,
int harq_pid,
const NR_ServingCellConfigCommon_t *scc,
const int tda)
post_process_pusch_t *pp_pusch,
uint16_t *rballoc_mask,
int *n_rb_sched,
int dci_beam_idx,
NR_UE_info_t *UE,
int harq_pid,
const NR_ServingCellConfigCommon_t *scc,
const int tda)
{
const int CC_id = 0;
int frame = pp_pusch->frame;
int slot = pp_pusch->slot;
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
/* Get previous PUSCH field info */
const NR_sched_pusch_t *retInfo = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch;
......@@ -1820,7 +1821,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
fill_pdcch_vrb_map(nrmac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, dci_beam_idx);
// signal new allocation
sched_ctrl->sched_pusch = new_sched;
post_process_ulsch(nrmac, pp_pusch, UE, &new_sched);
LOG_D(NR_MAC,
"%4d.%2d Allocate UL retransmission RNTI %04x sched %4d.%2d (%d RBs)\n",
frame,
......@@ -1848,9 +1849,8 @@ static int comparator(const void *p, const void *q) {
return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef;
}
static void pf_ul(module_id_t module_id,
frame_t frame,
int slot,
static void pf_ul(gNB_MAC_INST *nrmac,
post_process_pusch_t *pp_pusch,
frame_t sched_frame,
int sched_slot,
NR_UE_info_t *UE_list[],
......@@ -1859,7 +1859,8 @@ static void pf_ul(module_id_t module_id,
int n_rb_sched[num_beams])
{
const int CC_id = 0;
gNB_MAC_INST *nrmac = RC.nrmac[module_id];
int frame = pp_pusch->frame;
int slot = pp_pusch->slot;
NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
int slots_per_frame = nrmac->frame_structure.numb_slots_frame;
const int min_rb = nrmac->min_grant_prb;
......@@ -1880,13 +1881,16 @@ static void pf_ul(module_id_t module_id,
LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %04x\n",UE->rnti);
NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP;
const NR_mac_dir_stats_t *stats = &UE->mac_stats.ul;
NR_mac_dir_stats_t *stats = &UE->mac_stats.ul;
/* Calculate throughput */
const float a = 0.01f;
const uint32_t b = stats->current_bytes;
UE->ul_thr_ue = (1 - a) * UE->ul_thr_ue + a * b;
stats->current_bytes = 0;
stats->current_rbs = 0;
int total_rem_ues = 0;
for (int i = 0; i < num_beams; i++)
total_rem_ues += remainUEs[i];
......@@ -1915,8 +1919,7 @@ static void pf_ul(module_id_t module_id,
/* Allocate retransmission*/
const int tda = get_ul_tda(nrmac, sched_frame, sched_slot);
bool r = allocate_ul_retransmission(nrmac,
frame,
slot,
pp_pusch,
rballoc_mask,
&n_rb_sched[beam.idx],
dci_beam.idx,
......@@ -2063,7 +2066,8 @@ static void pf_ul(module_id_t module_id,
sched.dmrs_info.N_PRB_DMRS * sched.dmrs_info.num_dmrs_symb,
deltaMCS,
false);
sched_ctrl->sched_pusch = sched;
/* save allocation to FAPI structures */
post_process_ulsch(nrmac, pp_pusch, UE, &sched);
LOG_D(NR_MAC,
"pf_ul %d.%d UE %x Scheduling PUSCH (no data) nrb %d mcs %d tbs %d bits phr_txpower %d\n",
frame,
......@@ -2263,7 +2267,9 @@ static void pf_ul(module_id_t module_id,
sched_ctrl->cce_index = CCEIndex;
fill_pdcch_vrb_map(nrmac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, dci_beam.idx);
sched_ctrl->sched_pusch = sched;
/* save allocation to FAPI structures */
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;
......@@ -2374,7 +2380,7 @@ nfapi_nr_pusch_pdu_t *prepare_pusch_pdu(nfapi_nr_ul_tti_request_t *future_ul_tti
return pusch_pdu;
}
static void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE_info_t *UE, NR_sched_pusch_t *sched_pusch)
void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE_info_t *UE, NR_sched_pusch_t *sched_pusch)
{
frame_t frame = pusch->frame;
slot_t slot = pusch->slot;
......@@ -2585,12 +2591,14 @@ static void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch
nr_mac->cset0_bwp_size);
}
static bool nr_ulsch_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
static void nr_ulsch_preprocessor(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch)
{
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
int frame = pp_pusch->frame;
int slot = pp_pusch->slot;
// no UEs
if (nr_mac->UE_info.connected_ue_list[0] == NULL)
return false;
return;
NR_COMMON_channels_t *cc = nr_mac->common_channels;
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
......@@ -2603,7 +2611,7 @@ static bool nr_ulsch_preprocessor(module_id_t module_id, frame_t frame, slot_t s
const int sched_frame = (frame + (slot + K2) / slots_frame) % MAX_FRAME_NUMBER;
const int sched_slot = (slot + K2) % slots_frame;
if (!is_ul_slot(sched_slot, &nr_mac->frame_structure))
return false;
return;
int num_beams = nr_mac->beam_info.beam_allocation ? nr_mac->beam_info.beams_per_period : 1;
int bw = scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
......@@ -2618,8 +2626,7 @@ static bool nr_ulsch_preprocessor(module_id_t module_id, frame_t frame, slot_t s
max_sched_ues = min(max_sched_ues, MAX_DCI_CORESET);
/* proportional fair scheduling algorithm */
pf_ul(module_id, frame, slot, sched_frame, sched_slot, nr_mac->UE_info.connected_ue_list, max_sched_ues, num_beams, len);
return true;
pf_ul(nr_mac, pp_pusch, sched_frame, sched_slot, nr_mac->UE_info.connected_ue_list, max_sched_ues, num_beams, len);
}
nr_pp_impl_ul nr_init_ulsch_preprocessor(int CC_id)
......@@ -2659,38 +2666,15 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, slot_t slot, nfapi_
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
NR_SCHED_ENSURE_LOCKED(&nr_mac->sched_lock);
ul_dci_req->SFN = frame;
ul_dci_req->Slot = slot;
post_process_pusch_t pusch = { .frame = frame, .slot = slot, .ul_dci_req = ul_dci_req, .pdcch_pdu_coreset = {NULL}, };
/* Uplink data ONLY can be scheduled when the current slot is downlink slot,
* because we have to schedule the DCI0 first before schedule uplink data */
if (!is_dl_slot(slot, &nr_mac->frame_structure)) {
LOG_D(NR_MAC, "Current slot %d is NOT DL slot, cannot schedule DCI0 for UL data\n", slot);
return;
}
bool do_sched = nr_mac->pre_processor_ul(module_id, frame, slot);
if (!do_sched)
return;
ul_dci_req->SFN = frame;
ul_dci_req->Slot = slot;
post_process_pusch_t pusch = { frame, slot, ul_dci_req };
NR_UEs_t *UE_info = &nr_mac->UE_info;
UE_iterator(UE_info->connected_ue_list, UE) {
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
if (sched_ctrl->ul_failure && !get_softmodem_params()->phy_test)
continue;
UE->mac_stats.ul.current_bytes = 0;
UE->mac_stats.ul.current_rbs = 0;
/* dynamic PUSCH values (RB alloc, MCS, hence R, Qm, TBS) that change in
* every TTI are pre-populated by the preprocessor and used below */
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
LOG_D(NR_MAC,"UE %04x : sched_pusch->rbSize %d\n",UE->rnti,sched_pusch->rbSize);
if (sched_pusch->rbSize <= 0)
continue;
post_process_ulsch(nr_mac, &pusch, UE, sched_pusch);
memset(sched_pusch, 0, sizeof(*sched_pusch));
}
nr_mac->pre_processor_ul(nr_mac, &pusch);
}
......@@ -149,7 +149,7 @@ uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs);
void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot);
/* \brief UL preprocessor for phytest: schedules UE_id 0 with fixed MCS on a
* fixed set of resources */
bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot);
void nr_ul_preprocessor_phytest(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch);
void handle_nr_uci_pucch_0_1(module_id_t mod_id,
frame_t frame,
......@@ -498,4 +498,6 @@ void prepare_du_configuration_update(gNB_MAC_INST *mac,
const NR_BCCH_DL_SCH_Message_t *sib1);
void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group);
void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE_info_t *UE, NR_sched_pusch_t *sched_pusch);
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
......@@ -598,9 +598,6 @@ typedef struct {
NR_sched_pucch_t *sched_pucch;
int sched_pucch_size;
/// Sched PUSCH: scheduling decisions, copied into HARQ and cleared every TTI
NR_sched_pusch_t sched_pusch;
/// Sched SRS: scheduling decisions
NR_sched_srs_t sched_srs;
......@@ -807,8 +804,12 @@ typedef struct {
nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_coreset[MAX_NUM_CORESET];
} post_process_pusch_t;
/* forward declaration to use in nr_pp_impl_dl */
struct gNB_MAC_INST_s;
typedef struct gNB_MAC_INST_s gNB_MAC_INST;
typedef void (*nr_pp_impl_dl)(module_id_t mod_id, frame_t frame, slot_t slot);
typedef bool (*nr_pp_impl_ul)(module_id_t mod_id, frame_t frame, slot_t slot);
typedef void (*nr_pp_impl_ul)(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch);
typedef struct f1_config_t {
f1ap_setup_req_t *setup_req;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment