Refactor to call post-processor in place
Call the post-processor when the allocation is "fixed" (i.e., nothing
changes anymore), instead of having a final loop across all UEs that
might potentially be costly.
In order to calculate the PF metric, note that the statistics "reset" is
moved into pf_dl() instead of the post-processing loop, as it has to be
done on each slot.
See also: dd98030202 ("Refactor to call post-processor in place")
This commit is contained in:
@@ -182,13 +182,13 @@ extern void fix_scd(NR_ServingCellConfig_t *scd);// forward declaration
|
||||
/* specific dlsim DL preprocessor: uses rbStart/rbSize/mcs/nrOfLayers from command line of dlsim */
|
||||
int g_mcsIndex = -1, g_mcsTableIdx = 0, g_rbStart = -1, g_rbSize = -1, g_nrOfLayers = 1, g_pmi = 0;
|
||||
|
||||
void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
void nr_dlsim_preprocessor(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pp_pdsch)
|
||||
{
|
||||
NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.connected_ue_list[0];
|
||||
AssertFatal(RC.nrmac[module_id]->UE_info.connected_ue_list[1] == NULL, "Only single UE allowed in dlsim\n");
|
||||
NR_UE_info_t *UE_info = nr_mac->UE_info.connected_ue_list[0];
|
||||
AssertFatal(nr_mac->UE_info.connected_ue_list[1] == NULL, "Only single UE allowed in dlsim\n");
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl;
|
||||
NR_UE_DL_BWP_t *current_BWP = &UE_info->current_DL_BWP;
|
||||
NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon;
|
||||
NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels[0].ServingCellConfigCommon;
|
||||
|
||||
uint8_t nr_of_candidates = 0;
|
||||
if (g_mcsIndex < 4) {
|
||||
@@ -201,8 +201,8 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
&nr_of_candidates,
|
||||
sched_ctrl->search_space,4);
|
||||
}
|
||||
uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE_info->rnti);
|
||||
int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id],
|
||||
uint32_t Y = get_Y(sched_ctrl->search_space, pp_pdsch->slot, UE_info->rnti);
|
||||
int CCEIndex = find_pdcch_candidate(nr_mac,
|
||||
/* CC_id = */ 0,
|
||||
sched_ctrl->aggregation_level,
|
||||
nr_of_candidates,
|
||||
@@ -210,13 +210,18 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
&sched_ctrl->sched_pdcch,
|
||||
sched_ctrl->coreset,
|
||||
Y);
|
||||
AssertFatal(CCEIndex>=0, "%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n", frame, slot, 0, UE_info->rnti);
|
||||
AssertFatal(CCEIndex >= 0,
|
||||
"%4d.%2d could not find CCE for DL DCI UE %d/RNTI %04x\n",
|
||||
pp_pdsch->frame,
|
||||
pp_pdsch->slot,
|
||||
0,
|
||||
UE_info->rnti);
|
||||
sched_ctrl->cce_index = CCEIndex;
|
||||
|
||||
NR_sched_pdsch_t sched_pdsch = {
|
||||
.rbStart = g_rbStart,
|
||||
.rbSize = g_rbSize,
|
||||
.bwp_info = get_pdsch_bwp_start_size(RC.nrmac[module_id], UE_info),
|
||||
.bwp_info = get_pdsch_bwp_start_size(nr_mac, UE_info),
|
||||
.mcs = g_mcsIndex,
|
||||
.nrOfLayers = g_nrOfLayers,
|
||||
.pm_index = g_pmi,
|
||||
@@ -224,7 +229,7 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
/* the following might override the table that is mandated by RRC
|
||||
* configuration */
|
||||
current_BWP->mcsTableIdx = g_mcsTableIdx;
|
||||
sched_pdsch.time_domain_allocation = get_dl_tda(RC.nrmac[module_id], slot);
|
||||
sched_pdsch.time_domain_allocation = get_dl_tda(nr_mac, pp_pdsch->slot);
|
||||
AssertFatal(sched_pdsch.time_domain_allocation >= 0,"Unable to find PDSCH time domain allocation in list\n");
|
||||
|
||||
sched_pdsch.tda_info = get_dl_tda_info(current_BWP,
|
||||
@@ -253,7 +258,7 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
sched_pdsch.nrOfLayers) >> 3;
|
||||
|
||||
/* the simulator assumes the HARQ PID is equal to the slot number */
|
||||
sched_pdsch.dl_harq_pid = slot;
|
||||
sched_pdsch.dl_harq_pid = pp_pdsch->slot;
|
||||
|
||||
/* The scheduler uses lists to track whether a HARQ process is
|
||||
* free/busy/awaiting retransmission, and updates the HARQ process states.
|
||||
@@ -262,17 +267,17 @@ void nr_dlsim_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
* Therefore, below lines just "repair" everything so that the scheduler
|
||||
* won't remark that there is no HARQ feedback */
|
||||
sched_ctrl->feedback_dl_harq.head = -1; // always overwrite feedback HARQ process
|
||||
if (sched_ctrl->harq_processes[slot].round == 0) // depending on round set in simulation ...
|
||||
add_front_nr_list(&sched_ctrl->available_dl_harq, slot); // ... make PID available
|
||||
if (sched_ctrl->harq_processes[pp_pdsch->slot].round == 0) // depending on round set in simulation ...
|
||||
add_front_nr_list(&sched_ctrl->available_dl_harq, pp_pdsch->slot); // ... make PID available
|
||||
else
|
||||
add_front_nr_list(&sched_ctrl->retrans_dl_harq, slot); // ... make PID retransmission
|
||||
sched_ctrl->harq_processes[slot].is_waiting = false;
|
||||
add_front_nr_list(&sched_ctrl->retrans_dl_harq, pp_pdsch->slot); // ... make PID retransmission
|
||||
sched_ctrl->harq_processes[pp_pdsch->slot].is_waiting = false;
|
||||
AssertFatal(sched_pdsch.rbStart >= 0, "invalid rbStart %d\n", sched_pdsch.rbStart);
|
||||
AssertFatal(sched_pdsch.rbSize > 0, "invalid rbSize %d\n", sched_pdsch.rbSize);
|
||||
AssertFatal(sched_pdsch.mcs >= 0, "invalid mcs %d\n", sched_pdsch.mcs);
|
||||
AssertFatal(current_BWP->mcsTableIdx >= 0 && current_BWP->mcsTableIdx <= 2, "invalid mcsTableIdx %d\n", current_BWP->mcsTableIdx);
|
||||
|
||||
sched_ctrl->sched_pdsch = sched_pdsch;
|
||||
post_process_dlsch(nr_mac, pp_pdsch, UE_info, &sched_pdsch);
|
||||
}
|
||||
|
||||
nrUE_params_t nrUE_params;
|
||||
|
||||
@@ -422,17 +422,17 @@ bwp_info_t get_pdsch_bwp_start_size(gNB_MAC_INST *nr_mac, NR_UE_info_t *UE)
|
||||
return bwp_info;
|
||||
}
|
||||
|
||||
static bool allocate_dl_retransmission(module_id_t module_id,
|
||||
frame_t frame,
|
||||
slot_t slot,
|
||||
static bool allocate_dl_retransmission(gNB_MAC_INST *nr_mac,
|
||||
post_process_pdsch_t *pp_pdsch,
|
||||
int *n_rb_sched,
|
||||
NR_UE_info_t *UE,
|
||||
int beam_idx,
|
||||
int current_harq_pid)
|
||||
{
|
||||
|
||||
frame_t frame = pp_pdsch->frame;
|
||||
slot_t slot = pp_pdsch->slot;
|
||||
int CC_id = 0;
|
||||
gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
|
||||
|
||||
const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels->ServingCellConfigCommon;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP;
|
||||
@@ -578,7 +578,8 @@ static bool allocate_dl_retransmission(module_id_t module_id,
|
||||
new_sched.rbStart = rbStart - bwp_info.bwpStart;
|
||||
new_sched.pucch_allocation = alloc;
|
||||
new_sched.bwp_info = bwp_info;
|
||||
sched_ctrl->sched_pdsch = new_sched;
|
||||
|
||||
post_process_dlsch(nr_mac, pp_pdsch, UE, &new_sched);
|
||||
|
||||
/* retransmissions: directly allocate */
|
||||
*n_rb_sched -= new_sched.rbSize;
|
||||
@@ -606,15 +607,16 @@ static int comparator(const void *p, const void *q)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pf_dl(module_id_t module_id,
|
||||
frame_t frame,
|
||||
slot_t slot,
|
||||
static void pf_dl(gNB_MAC_INST *mac,
|
||||
post_process_pdsch_t *pp_pdsch,
|
||||
NR_UE_info_t **UE_list,
|
||||
int max_num_ue,
|
||||
int num_beams,
|
||||
int n_rb_sched[num_beams])
|
||||
{
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_id];
|
||||
frame_t frame = pp_pdsch->frame;
|
||||
slot_t slot = pp_pdsch->slot;
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc=mac->common_channels[0].ServingCellConfigCommon;
|
||||
// UEs that could be scheduled
|
||||
UEsched_t UE_sched[MAX_MOBILES_PER_GNB + 1] = {0};
|
||||
@@ -633,15 +635,18 @@ static void pf_dl(module_id_t module_id,
|
||||
if (!nr_mac_ue_is_active(UE))
|
||||
continue;
|
||||
|
||||
const NR_mac_dir_stats_t *stats = &UE->mac_stats.dl;
|
||||
NR_mac_dir_stats_t *stats = &UE->mac_stats.dl;
|
||||
/* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
|
||||
int harq_pid = sched_ctrl->retrans_dl_harq.head;
|
||||
|
||||
/* Calculate Throughput */
|
||||
const float a = 0.01f;
|
||||
const uint32_t b = UE->mac_stats.dl.current_bytes;
|
||||
const uint32_t b = stats->current_bytes;
|
||||
UE->dl_thr_ue = (1 - a) * UE->dl_thr_ue + a * b;
|
||||
|
||||
stats->current_bytes = 0;
|
||||
stats->current_rbs = 0;
|
||||
|
||||
/* Check if this UE should get TA (every 100 frames). If we add the CE,
|
||||
* ta_apply will be reset */
|
||||
if (frame == ((sched_ctrl->ta_frame + 100) % 1024))
|
||||
@@ -659,7 +664,7 @@ static void pf_dl(module_id_t module_id,
|
||||
bool sch_ret = beam.idx >= 0;
|
||||
/* Allocate retransmission */
|
||||
if (sch_ret)
|
||||
sch_ret = allocate_dl_retransmission(module_id, frame, slot, &n_rb_sched[beam.idx], UE, beam.idx, harq_pid);
|
||||
sch_ret = allocate_dl_retransmission(mac, pp_pdsch, &n_rb_sched[beam.idx], UE, beam.idx, harq_pid);
|
||||
if (!sch_ret) {
|
||||
LOG_D(NR_MAC, "[UE %04x][%4d.%2d] DL retransmission could not be allocated\n", UE->rnti, frame, slot);
|
||||
reset_beam_status(&mac->beam_info, frame, slot, UE->UE_beam_index, slots_per_frame, beam.new_beam);
|
||||
@@ -876,7 +881,7 @@ static void pf_dl(module_id_t module_id,
|
||||
&sched_pdsch.tb_size,
|
||||
&sched_pdsch.rbSize);
|
||||
|
||||
sched_ctrl->sched_pdsch = sched_pdsch;
|
||||
post_process_dlsch(mac, pp_pdsch, iterator->UE, &sched_pdsch);
|
||||
|
||||
/* transmissions: directly allocate */
|
||||
n_rb_sched[beam.idx] -= sched_pdsch.rbSize;
|
||||
@@ -889,9 +894,9 @@ static void pf_dl(module_id_t module_id,
|
||||
}
|
||||
}
|
||||
|
||||
static void nr_dlsch_preprocessor(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
static void nr_dlsch_preprocessor(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
|
||||
{
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_id];
|
||||
module_id_t module_id = 0;
|
||||
NR_UEs_t *UE_info = &mac->UE_info;
|
||||
|
||||
if (UE_info->connected_ue_list[0] == NULL)
|
||||
@@ -905,7 +910,7 @@ static void nr_dlsch_preprocessor(module_id_t module_id, frame_t frame, slot_t s
|
||||
n_rb_sched[i] = bw;
|
||||
|
||||
/* Retrieve amount of data to send for this UE */
|
||||
nr_store_dlsch_buffer(module_id, frame, slot);
|
||||
nr_store_dlsch_buffer(module_id, pp_pdsch->frame, pp_pdsch->slot);
|
||||
|
||||
int average_agg_level = 4; // TODO find a better estimation
|
||||
int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE);
|
||||
@@ -914,7 +919,7 @@ static void nr_dlsch_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_dl(module_id, frame, slot, UE_info->connected_ue_list, max_sched_ues, num_beams, n_rb_sched);
|
||||
pf_dl(mac, pp_pdsch, UE_info->connected_ue_list, max_sched_ues, num_beams, n_rb_sched);
|
||||
}
|
||||
|
||||
nr_pp_impl_dl nr_init_dlsch_preprocessor(int CC_id)
|
||||
@@ -1003,7 +1008,7 @@ nfapi_nr_dl_tti_pdsch_pdu_rel15_t *prepare_pdsch_pdu(nfapi_nr_dl_tti_request_pdu
|
||||
void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE_info_t *UE, NR_sched_pdsch_t *sched_pdsch)
|
||||
{
|
||||
int CC_id = 0;
|
||||
int module_id = 0;
|
||||
int module_id = nr_mac->Mod_id;
|
||||
frame_t frame = pdsch->frame;
|
||||
slot_t slot = pdsch->slot;
|
||||
|
||||
@@ -1371,6 +1376,8 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
nfapi_nr_tx_data_request_t *TX_req)
|
||||
{
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_id];
|
||||
int CC_id = 0;
|
||||
|
||||
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
|
||||
AssertFatal(pthread_mutex_trylock(&gNB_mac->sched_lock) == EBUSY,
|
||||
"this function should be called with the scheduler mutex locked\n");
|
||||
@@ -1378,34 +1385,14 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
if (!is_dl_slot(slot, &gNB_mac->frame_structure))
|
||||
return;
|
||||
|
||||
/* PREPROCESSOR */
|
||||
gNB_mac->pre_processor_dl(module_id, frame, slot);
|
||||
const int CC_id = 0;
|
||||
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
NR_UEs_t *UE_info = &gNB_mac->UE_info;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
|
||||
post_process_pdsch_t pdsch = { frame, slot, dl_req, TX_req };
|
||||
|
||||
const NR_BWP_t *initialDL = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters;
|
||||
gNB_mac->mac_stats.total_prb_aggregate += NRRIV2BW(initialDL->locationAndBandwidth, MAX_BWP_SIZE);
|
||||
|
||||
UE_iterator(UE_info->connected_ue_list, UE) {
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &DL_req->dl_tti_request_body;
|
||||
post_process_pdsch_t pdsch = { frame, slot, dl_req, TX_req };
|
||||
|
||||
if (!nr_mac_ue_is_active(UE) && !get_softmodem_params()->phy_test)
|
||||
continue;
|
||||
/* PREPROCESSOR */
|
||||
gNB_mac->pre_processor_dl(gNB_mac, &pdsch);
|
||||
|
||||
NR_sched_pdsch_t *sched_pdsch = &sched_ctrl->sched_pdsch;
|
||||
UE->mac_stats.dl.current_bytes = 0;
|
||||
UE->mac_stats.dl.current_rbs = 0;
|
||||
|
||||
if (sched_pdsch->rbSize <= 0)
|
||||
continue;
|
||||
|
||||
post_process_dlsch(gNB_mac, &pdsch, UE, sched_pdsch);
|
||||
|
||||
/* mark UE as scheduled */
|
||||
sched_pdsch->rbSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,9 +55,11 @@ uint32_t target_dl_bw = 50;
|
||||
uint64_t dlsch_slot_bitmap = (1<<1);
|
||||
|
||||
/* schedules whole bandwidth for first user, all the time */
|
||||
void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
|
||||
{
|
||||
gNB_MAC_INST *mac = RC.nrmac[module_id];
|
||||
frame_t frame = pp_pdsch->frame;
|
||||
slot_t slot = pp_pdsch->slot;
|
||||
|
||||
/* already mutex protected: held in gNB_dlsch_ulsch_scheduler() */
|
||||
int slot_period = slot % mac->frame_structure.numb_slots_period;
|
||||
if (!is_xlsch_in_slot(dlsch_slot_bitmap, slot_period))
|
||||
@@ -188,7 +190,7 @@ void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot)
|
||||
target_dl_Nl)
|
||||
>> 3;
|
||||
|
||||
sched_ctrl->sched_pdsch = sched_pdsch;
|
||||
post_process_dlsch(mac, pp_pdsch, UE, &sched_pdsch);
|
||||
|
||||
/* mark the corresponding RBs as used */
|
||||
for (int rb = 0; rb < sched_pdsch.rbSize; rb++)
|
||||
|
||||
@@ -2974,9 +2974,6 @@ NR_UE_info_t *get_new_nr_ue_inst(uid_allocator_t *uia, rnti_t rnti, NR_CellGroup
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
|
||||
sched_ctrl->ta_update = 31;
|
||||
|
||||
/* set illegal time domain allocation to force recomputation of all fields */
|
||||
sched_ctrl->sched_pdsch.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);
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs);
|
||||
|
||||
/* \brief preprocessor for phytest: schedules UE_id 0 with fixed MCS on all
|
||||
* freq resources */
|
||||
void nr_preprocessor_phytest(module_id_t module_id, frame_t frame, slot_t slot);
|
||||
void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch);
|
||||
/* \brief UL preprocessor for phytest: schedules UE_id 0 with fixed MCS on a
|
||||
* fixed set of resources */
|
||||
void nr_ul_preprocessor_phytest(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch);
|
||||
@@ -504,5 +504,6 @@ void prepare_du_configuration_update(gNB_MAC_INST *mac,
|
||||
|
||||
void nr_mac_clean_cellgroup(NR_CellGroupConfig_t *cell_group);
|
||||
|
||||
void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE_info_t *UE, NR_sched_pdsch_t *sched_pdsch);
|
||||
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__*/
|
||||
|
||||
@@ -633,8 +633,6 @@ typedef struct {
|
||||
/// PHR info: nominal UE transmit power levels (dBm)
|
||||
int pcmax;
|
||||
|
||||
/// Sched PDSCH: scheduling decisions, copied into HARQ and cleared every TTI
|
||||
NR_sched_pdsch_t sched_pdsch;
|
||||
/// UE-estimated maximum MCS (from CSI-RS)
|
||||
uint8_t dl_max_mcs;
|
||||
|
||||
@@ -847,7 +845,7 @@ typedef struct {
|
||||
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 void (*nr_pp_impl_dl)(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pp_pdsch);
|
||||
typedef void (*nr_pp_impl_ul)(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch);
|
||||
|
||||
typedef struct f1_config_t {
|
||||
|
||||
Reference in New Issue
Block a user