From d005336cb89ee5237a295cc5fd9897a0bf8d2ff6 Mon Sep 17 00:00:00 2001 From: Laurent THOMAS Date: Thu, 14 Aug 2025 15:41:12 +0200 Subject: [PATCH] Simplify PRACH beam handling, remove race Simplify by removing a small malloc and memcpy() the beams. This should also remove the data race between ru and gNB/CU-DU --- executables/nr-ru.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_prach.c | 24 ++++++++++++------------ openair1/PHY/defs_common.h | 3 +-- openair1/SCHED_NR/fapi_nr_l1.c | 2 +- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 1c2e1acaf1..f28f2919c4 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -1222,7 +1222,7 @@ void *ru_thread(void *param) for (int prach_oc = 0; prach_oc < p->lower.num_prach_ocas; prach_oc++) { int prachStartSymbol = p->lower.prachStartSymbol + prach_oc * N_dur; - int beam_id = p->lower.beam ? p->lower.beam[prach_oc] : 0; + int beam_id = p->beams[prach_oc]; //comment FK: the standard 38.211 section 5.3.2 has one extra term +14*N_RA_slot. This is because there prachStartSymbol is given wrt to start of the 15kHz slot or 60kHz slot. Here we work slot based, so this function is anyway only called in slots where there is PRACH. Its up to the MAC to schedule another PRACH PDU in the case there are there N_RA_slot \in {0,1}. rx_nr_prach_ru(ru, p->lower.fmt, // could also use format diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 371160437a..3c2eb73e77 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -46,8 +46,6 @@ void init_prach_list(prach_list_t *l, prach_type_t t) void free_nr_prach_entry(prach_list_t *l, prach_item_t *p) { pthread_mutex_lock(&l->prach_list_mutex); - if (p->type == prach_upper) - free_and_zero(p->upper.beam_nb); *p = (prach_item_t){.frame = -1, .slot = -1, .num_slots = -1}; pthread_mutex_unlock(&l->prach_list_mutex); } @@ -91,25 +89,27 @@ prach_item_t *nr_fill_prach(PHY_VARS_gNB *gNB, int SFN, int Slot, nfapi_nr_prach prach->num_slots = (format < 4) ? get_long_prach_dur(format, gNB->frame_parms.numerology_index) : 1; if (gNB->common_vars.beam_id) { int n_symb = get_nr_prach_duration(prach_pdu->prach_format); - prach->upper.beam_nb = calloc(prach_pdu->beamforming.dig_bf_interface, sizeof(*prach->upper.beam_nb)); + AssertFatal(prach_pdu->beamforming.dig_bf_interface < NFAPI_MAX_NUM_BG_IF, + "impossible beams size %d\n", + prach_pdu->beamforming.dig_bf_interface); for (int i = 0; i < prach_pdu->beamforming.dig_bf_interface; i++) { int fapi_beam_idx = prach_pdu->beamforming.prgs_list[0].dig_bf_interface_list[i].beam_idx; int start_symb = prach_pdu->prach_start_symbol + i * n_symb; int bitmap = SL_to_bitmap(start_symb, n_symb); - prach->upper.beam_nb[i] = beam_index_allocation(gNB->enable_analog_das, - fapi_beam_idx, - &gNB->gNB_config.analog_beamforming_ve, - &gNB->common_vars, - Slot, - NR_NUMBER_OF_SYMBOLS_PER_SLOT, - bitmap); + prach->beams[i] = beam_index_allocation(gNB->enable_analog_das, + fapi_beam_idx, + &gNB->gNB_config.analog_beamforming_ve, + &gNB->common_vars, + Slot, + NR_NUMBER_OF_SYMBOLS_PER_SLOT, + bitmap); } } prach->pdu = *prach_pdu; return prach; } -void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beam_id) +void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_pdu, int *beams) { prach_item_t *prach = find_nr_prach(&ru->prach_list, SFN, Slot, SEARCH_EXIST_OR_FREE); if (!prach) { @@ -123,9 +123,9 @@ void nr_fill_prach_ru(RU_t *ru, int SFN, int Slot, nfapi_nr_prach_pdu_t *prach_p .num_slots = (fmt < 4) ? get_long_prach_dur(fmt, ru->nr_frame_parms->numerology_index) : 1, .lower = {.fmt = fmt, .numRA = prach_pdu->num_ra, - .beam = beam_id, .prachStartSymbol = prach_pdu->prach_start_symbol, .num_prach_ocas = prach_pdu->num_prach_ocas}}; + memcpy(prach->beams, beams, sizeof(prach->beams)); } void rx_nr_prach_ru(RU_t *ru, diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 79f1763842..b9923a1b8b 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -1006,11 +1006,11 @@ typedef struct { int frame; int slot; int num_slots; // prach duration in slots + int beams[NFAPI_MAX_NUM_BG_IF]; prach_type_t type; union { struct { // identifier for concurrent beams - int *beam_nb; nfapi_nr_prach_pdu_t pdu; } upper; struct { @@ -1018,7 +1018,6 @@ typedef struct { int numRA; int prachStartSymbol; int num_prach_ocas; - int *beam; } lower; }; nfapi_nr_prach_pdu_t pdu; diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index fa5167adff..09419d4e84 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -156,7 +156,7 @@ void nr_schedule_ul_tti_req(PHY_VARS_gNB *gNB, nfapi_nr_ul_tti_request_t *UL_tti nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; prach_item_t *prach = nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); if (prach && (gNB->RU_list[0]->if_south == LOCAL_RF || gNB->RU_list[0]->if_south == REMOTE_IF5)) - nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu, prach->upper.beam_nb); + nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu, prach->beams); break; case NFAPI_NR_UL_CONFIG_SRS_PDU_TYPE: LOG_D(NR_PHY,