From fc26b8c053a991f3a429916d15ee55775c1592dc Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 10 Dec 2024 10:53:01 +0100 Subject: [PATCH] Fix process_slot_tx_barriers for high rx-to-tx values Set the number of barriers to 512 and implement proper slot and frame based selection. Now the dynamic barriers should not be overwritten in case the rx-to-tx offset is high. The maximum offset supported is 512. --- executables/nr-ue.c | 17 +++++++++-------- openair1/PHY/defs_nr_UE.h | 11 ++++++++++- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 15 +++++++++------ 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 27f9654aa4..d892bff9e5 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -553,8 +553,8 @@ void processSlotTX(void *arg) int slots_per_frame = (UE->sl_mode == 2) ? UE->SL_UE_PHY_PARAMS.sl_frame_params.slots_per_frame : UE->frame_parms.slots_per_frame; - int next_slot = (proc->nr_slot_tx + 1 + proc->nr_slot_tx_offset) % slots_per_frame; - dynamic_barrier_join(&UE->process_slot_tx_barriers[next_slot]); + int next_slot_and_frame = proc->nr_slot_tx + 1 + proc->nr_slot_tx_offset + proc->frame_tx * slots_per_frame; + dynamic_barrier_join(&UE->process_slot_tx_barriers[next_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]); RU_write(rxtxD, sl_tx_action); free(rxtxD); TracyCZoneEnd(ctx); @@ -810,8 +810,7 @@ void *UE_thread(void *arg) int absolute_slot = 0, decoded_frame_rx = MAX_FRAME_NUMBER - 1, trashed_frames = 0; int tx_wait_for_dlsch[NR_MAX_SLOTS_PER_FRAME]; - int num_ind_fifo = nb_slot_frame; - for(int i = 0; i < num_ind_fifo; i++) { + for(int i = 0; i < NUM_PROCESS_SLOT_TX_BARRIERS; i++) { dynamic_barrier_init(&UE->process_slot_tx_barriers[i]); } int shiftForNextFrame = 0; @@ -822,7 +821,7 @@ void *UE_thread(void *arg) if (get_softmodem_params()->sync_ref && UE->sl_mode == 2) { UE->is_synchronized = 1; } else { - //warm up the RF board + //warm up the RF board int64_t tmp; for (int i = 0; i < 50; i++) readFrame(UE, &tmp, true); @@ -934,7 +933,7 @@ void *UE_thread(void *arg) } // We have resynchronized, maybe after RF loss so we need to purge any existing context memset(tx_wait_for_dlsch, 0, sizeof(tx_wait_for_dlsch)); - for (int i = 0; i < num_ind_fifo; i++) { + for (int i = 0; i < NUM_PROCESS_SLOT_TX_BARRIERS; i++) { dynamic_barrier_reset(&UE->process_slot_tx_barriers[i]); } continue; @@ -957,7 +956,7 @@ void *UE_thread(void *arg) if (UE->ntn_config_message->update) { UE->ntn_config_message->update = false; update_ntn_system_information = true; - nr_slot_tx_offset = UE->ntn_config_message->ntn_config_params.cell_specific_k_offset % nb_slot_frame; + nr_slot_tx_offset = UE->ntn_config_message->ntn_config_params.cell_specific_k_offset; } int slot_nr = absolute_slot % nb_slot_frame; @@ -1054,7 +1053,9 @@ void *UE_thread(void *arg) int sync_to_previous_thread = stream_status == STREAM_STATUS_SYNCED ? 1 : 0; int slot = curMsgTx->proc.nr_slot_tx; - dynamic_barrier_update(&UE->process_slot_tx_barriers[slot], + int slot_and_frame = slot + curMsgTx->proc.frame_tx * UE->frame_parms.slots_per_frame; + + dynamic_barrier_update(&UE->process_slot_tx_barriers[slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS], tx_wait_for_dlsch[slot] + sync_to_previous_thread, start_process_slot_tx, curMsgTx); diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 2db8530a99..729acc84ca 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -85,6 +85,15 @@ #define UNUSED(x) (void)x; #define NUM_DL_ACTORS 4 +// Set the number of barriers for processSlotTX to 512. This value has to be at least 483 for NTN where +// DL-to-UL offset is up to 483. The selected value is also half of the frame range so that +// (slot + frame * slots_per_frame) % NUM_PROCESS_SLOT_TX_BARRIERS is contiguous between the last slot of +// frame 1023 and first slot of frame 0 +// e.g. in numerology 1: +// (19 + 1023 * 20) % 512 = 511 +// (0 + 0 * 20) % 512 = 0 +#define NUM_PROCESS_SLOT_TX_BARRIERS 512 + #include "impl_defs_top.h" #include "impl_defs_nr.h" #include "time_meas.h" @@ -527,7 +536,7 @@ typedef struct PHY_VARS_NR_UE_s { void *phy_sim_pdsch_dl_ch_estimates_ext; uint8_t *phy_sim_dlsch_b; - dynamic_barrier_t process_slot_tx_barriers[NR_MAX_SLOTS_PER_FRAME]; + dynamic_barrier_t process_slot_tx_barriers[NUM_PROCESS_SLOT_TX_BARRIERS]; // Gain change required for automation RX gain change int adjust_rxgain; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 664a293a96..ab92b17711 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -729,8 +729,9 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, if (is_cw0_active != ACTIVE && is_cw1_active != ACTIVE) { // don't wait anymore LOG_E(NR_PHY, "Internal error nr_ue_dlsch_procedure() called but no active cw on slot %d, harq %d\n", nr_slot_rx, harq_pid); - const int ack_nack_slot = (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) % ue->frame_parms.slots_per_frame; - dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot]); + const int ack_nack_slot_and_frame = + (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) + proc->frame_rx * ue->frame_parms.slots_per_frame; + dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]); return false; } @@ -865,8 +866,9 @@ static bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, // DLSCH decoding finished! don't wait anymore in Tx process, we know if we should answer ACK/NACK PUCCH if (dlsch[0].rnti_type == TYPE_C_RNTI_) { - const int ack_nack_slot = (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) % ue->frame_parms.slots_per_frame; - dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot]); + const int ack_nack_slot_and_frame = + (proc->nr_slot_rx + dlsch[0].dlsch_config.k1_feedback) + proc->frame_rx * ue->frame_parms.slots_per_frame; + dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]); } if (ue->phy_sim_dlsch_b) @@ -1148,8 +1150,9 @@ void pdsch_processing(PHY_VARS_NR_UE *ue, const UE_nr_rxtx_proc_t *proc, nr_phy_ nr_ue_dlsch_procedures(ue, proc, dlsch, llr, G); else { LOG_E(NR_PHY, "Demodulation impossible, internal error\n"); - int ack_nack_slot = (proc->nr_slot_rx + dlsch_config->k1_feedback) % ue->frame_parms.slots_per_frame; - dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot]); + const int ack_nack_slot_and_frame = + proc->nr_slot_rx + dlsch_config->k1_feedback + proc->frame_rx * ue->frame_parms.slots_per_frame; + dynamic_barrier_join(&ue->process_slot_tx_barriers[ack_nack_slot_and_frame % NUM_PROCESS_SLOT_TX_BARRIERS]); LOG_W(NR_PHY, "nr_ue_pdsch_procedures failed in slot %d\n", proc->nr_slot_rx); }