Remove polling support for fronthaul interface

Signed-off-by: Teodora Vladić <teodora.vladic@openairinterface.org>
This commit is contained in:
Teodora Vladić
2026-04-15 14:47:46 +02:00
committed by Romain Beurdouche
parent 9a2a313515
commit 7af713a1d1
4 changed files with 5 additions and 124 deletions

View File

@@ -501,19 +501,6 @@ cmake .. -GNinja -DOAI_FHI72=ON -Dxran_DOWNLOAD=ON
ninja nr-softmodem oran_fhlib_5g params_libconfig
```
Note that in tags 2025.w06 and prior, the FHI72 driver used polling to wait for
the next slot. This is inefficient as it burns CPU time, and has been replaced
with a more efficient mechanism. Nevertheless, if you experience problems that
did not occur previously, it is possible to re-enable polling, either with
`build_oai` like this
./build_oai --gNB --ninja -t oran_fhlib_5g --cmake-opt -Dxran_LOCATION=$HOME/phy/fhi_lib/lib --cmake-opt -DOAI_FHI72_USE_POLLING=ON
or with `cmake` like so
cmake .. -GNinja -DOAI_FHI72=ON -Dxran_LOCATION=$HOME/phy/fhi_lib/lib -DOAI_FHI72_USE_POLLING=ON
ninja oran_fhlib_5g
## Configuration
RU and DU configurations have a circular dependency: you have to configure DU MAC address in the RU configuration and the RU MAC address, VLAN and Timing advance parameters in the DU configuration.

View File

@@ -85,8 +85,6 @@ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
target_link_libraries(oran_fhlib_5g PRIVATE armral)
endif()
add_boolean_option(OAI_FHI72_USE_POLLING OFF "Enable polling in FHI72 driver" ON)
message(STATUS "Building FHI72 CUS library")
set_target_properties(oran_fhlib_5g PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

View File

@@ -43,8 +43,8 @@ optionally compresses IQ data, then writes it into IQ buffers of xran.
For PUSCH/PRACH, `oran_fh_if4p5_south_in()` calls `xran_fh_rx_read_slot()`/
`xran_fh_rx_prach_read_slot()` that blocks and waits for the next slot.
This is done through either a message queue, or through polling, which in both
cases depends on xran calling the callbacks `oai_xran_fh_rx_callback()`/
`oai_xran_fh_rx_prach_callback()` as installed during xran initialization.
This is done through a message queue which depends on xran calling the callbacks
`oai_xran_fh_rx_callback()`/`oai_xran_fh_rx_prach_callback()` as installed during
xran initialization.
Once unblocked, it reads first PUSCH data, then PRACH data, before returning to
OAI.

View File

@@ -29,10 +29,6 @@
#define N_SC_PER_PRB 12
#if OAI_FHI72_USE_POLLING
#define USE_POLLING
#endif
// Declare variable useful for the send buffer function
volatile bool first_call_set = false;
@@ -43,7 +39,6 @@ int xran_is_prach_slot(uint8_t PortId, uint32_t subframe_id, uint32_t slot_id
);
#include "common/utils/LOG/log.h"
#ifndef USE_POLLING
extern notifiedFIFO_t oran_sync_fifo;
#define MAX_QUEUE_LENGTH_NO_JUMP 3
atomic_int xran_queue_length = 0;
@@ -51,13 +46,6 @@ atomic_int xran_queue_prach_length = 0;
#if defined K_RELEASE
extern notifiedFIFO_t oran_sync_fifo_prach;
#endif
#else
volatile oran_sync_info_t oran_sync_info = {0};
#if defined K_RELEASE
volatile oran_sync_info_t oran_sync_info_prach = {0};
volatile bool prach_rx_awaiting = false;
#endif
#endif
/* Prints TX_TOTAL, RX_TOTAL, RX_ON_TIME, RX_ERR_DROP counters every 128 frames. */
void print_fhi_counters(ru_info_t *ru, const int frame, const int slot)
@@ -116,8 +104,7 @@ void print_fhi_counters(ru_info_t *ru, const int frame, const int slot)
/** @details xran-specific callback, called when all packets for given CC and
* 1/4, 1/2, 3/4, all symbols of a slot arrived. Currently, only used to get
* timing information and unblock another thread in xran_fh_rx_read_slot()
* through either a message queue, or writing in global memory with polling, on
* a full slot boundary. */
* through a message queue on a full slot boundary. */
void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status
#if defined K_RELEASE
, uint8_t mu
@@ -191,7 +178,6 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status
rx_RU[i][slot2] = 0;
if (last_slot == -1 || slot2 != last_slot) {
#ifndef USE_POLLING
notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(oran_sync_info_t), 0, &oran_sync_fifo, NULL);
oran_sync_info_t *info = NotifiedFifoData(req);
info->tti = tti;
@@ -218,28 +204,6 @@ void oai_xran_fh_rx_callback(void *pCallbackTag, xran_status_t status
LOG_D(HW, "Push %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, info->sl, slot, ru_id, subframe, last_slot);
atomic_fetch_add(&xran_queue_length, 1);
pushNotifiedFIFO(&oran_sync_fifo, req);
#else
LOG_D(HW, "Writing %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot);
oran_sync_info.tti = tti;
oran_sync_info.sl = slot2;
oran_sync_info.f = frame;
#if defined K_RELEASE
oran_sync_info.mu = mu;
oran_buf_list_t *bufs = get_xran_buffers(ru_id);
struct xran_fh_config *fh_config = get_xran_fh_config(ru_id);
for (uint16_t cc_id = 0; cc_id < 1 /* fh_config->nCC */; cc_id++) { // OAI does not support multiple CC yet.
for(uint32_t ant_id = 0; ant_id < fh_config->neAxc; ant_id++) {
struct xran_prb_map *pRbMap = (struct xran_prb_map *)bufs->dstcp[ant_id][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
AssertFatal(pRbMap != NULL, "(%d:%d:%d)pRbMap == NULL. Aborting.\n", cc_id, tti % XRAN_N_FE_BUF_LEN, ant_id);
for (uint32_t sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
oran_sync_info.nRxPkt[cc_id][ant_id][sym_id] = pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt;
pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt = 0;
}
}
}
#endif
#endif
} else
LOG_E(HW, "Cannot Push %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot);
last_slot = slot2;
@@ -295,20 +259,12 @@ void oai_xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status
rx_RU[i][slot2] = 0;
if (last_slot == -1 || slot2 != last_slot) {
#ifndef USE_POLLING
notifiedFIFO_elt_t *req = newNotifiedFIFO_elt(sizeof(oran_sync_info_t), 0, &oran_sync_fifo_prach, NULL);
oran_sync_info_t *info = NotifiedFifoData(req);
info->tti = tti;
info->sl = slot2;
info->f = frame;
info->mu = mu;
#else
LOG_D(HW, "Writing PRACH slot %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot);
oran_sync_info_prach.tti = tti;
oran_sync_info_prach.sl = slot2;
oran_sync_info_prach.f = frame;
oran_sync_info_prach.mu = mu;
#endif
struct xran_cb_tag *callback_tag = (struct xran_cb_tag *)pCallbackTag;
uint32_t tti = callback_tag->slotiId;
uint32_t ru_id = callback_tag->oXuId;
@@ -321,23 +277,15 @@ void oai_xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status
AssertFatal(pRbMap != NULL, "(%d:%d:%d)pRbMapPrach == NULL. Aborting.\n", cc_id, tti % XRAN_N_FE_BUF_LEN, ant_id);
for (uint32_t sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
AssertFatal(pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt <= 1, "PRACH segmentation is not supported\n");
#ifndef USE_POLLING
info->nRxPkt[cc_id][ant_id][sym_id] = pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt;
#else
oran_sync_info_prach.nRxPkt[cc_id][ant_id][sym_id] = pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt;
#endif
pRbMap->sFrontHaulRxPacketCtrl[sym_id].nRxPkt = 0;
}
}
}
}
#ifndef USE_POLLING
LOG_D(HW, "Push PRACH slot %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, info->sl, slot, ru_id, subframe, last_slot);
atomic_fetch_add(&xran_queue_prach_length, 1);
pushNotifiedFIFO(&oran_sync_fifo_prach, req);
#else
prach_rx_awaiting = true;
#endif
} else
LOG_E(HW, "Cannot Push PRACH slot %d.%d.%d (slot %d, subframe %d,last_slot %d)\n", frame, slot2, ru_id, slot, subframe, last_slot);
last_slot = slot2;
@@ -372,7 +320,6 @@ int oai_physide_dl_tti_call_back(void *param
int xran_fh_rx_prach_read_slot(PHY_VARS_gNB *gNB, ru_info_t *ru, int *frame, int *slot)
{
#if defined K_RELEASE
#ifndef USE_POLLING
// pull next even from oran_sync_fifo_prach if any
notifiedFIFO_elt_t *res = pullNotifiedFIFO(&oran_sync_fifo_prach);
atomic_fetch_sub(&xran_queue_prach_length, 1);
@@ -399,29 +346,6 @@ int xran_fh_rx_prach_read_slot(PHY_VARS_gNB *gNB, ru_info_t *ru, int *frame, int
*frame = info->f;
uint8_t mu = info->mu;
delNotifiedFIFO_elt(res);
#else
#error "POLLING is not supported for K release unless you know how to fix the race condition on prach_rx_awaiting"
if (!prach_rx_awaiting) {
return (0);
} else {
prach_rx_awaiting = false;
}
*slot = oran_sync_info_prach.sl;
*frame = oran_sync_info_prach.f;
uint8_t mu = oran_sync_info_prach.mu;
uint32_t tti_in = oran_sync_info_prach.tti;
static int last_slot = -1;
LOG_D(HW, "oran slot %d, last_slot %d\n", *slot, last_slot);
int cnt = 0;
// while (*slot == last_slot) {
while (tti_in == oran_sync_info_prach.tti) {
//*slot = oran_sync_info.sl;
cnt++;
}
LOG_D(HW, "cnt %d, Reading %d.%d\n", cnt, *frame, *slot);
last_slot = *slot;
#endif
#endif
prach_item_t p;
@@ -494,11 +418,7 @@ int xran_fh_rx_prach_read_slot(PHY_VARS_gNB *gNB, ru_info_t *ru, int *frame, int
#if defined K_RELEASE
struct xran_prb_map * pPrbMap = (struct xran_prb_map *)bufs->prachdstdecomp[aa % nb_rx_per_ru][tti % XRAN_N_FE_BUF_LEN].pBuffers->pData;
struct xran_rx_packet_ctl *p_rx_packet_ctl = &pPrbMap->sFrontHaulRxPacketCtrl[sym_idx];
#ifndef USE_POLLING
int32_t nRxPkt = info->nRxPkt[cc_id][aa][sym_idx];
#else
int32_t nRxPkt = oran_sync_info.nRxPkt[cc_id][aa][sym_idx];
#endif
if (nRxPkt == 0) {
LOG_D(HW, "read_prach %d.%d.%d saa = %d: nRxPkt = 0!\n", *frame, *slot, sym_idx, aa);
memset(&dst[sym_idx], 0, N_ZC * 2 * sizeof(*dst));
@@ -640,7 +560,6 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
int idx = 0;
static int outcnt = 0;
#ifndef USE_POLLING
// pull next event from oran_sync_fifo
notifiedFIFO_elt_t *res = pullNotifiedFIFO(&oran_sync_fifo);
atomic_fetch_sub(&xran_queue_length, 1);
@@ -669,25 +588,6 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
uint8_t mu = info->mu;
#endif
delNotifiedFIFO_elt(res);
#else
*slot = oran_sync_info.sl;
*frame = oran_sync_info.f;
#if defined K_RELEASE
uint8_t mu = oran_sync_info.mu;
#endif
uint32_t tti_in = oran_sync_info.tti;
static int last_slot = -1;
LOG_D(HW, "oran slot %d, last_slot %d\n", *slot, last_slot);
int cnt = 0;
// while (*slot == last_slot) {
while (tti_in == oran_sync_info.tti) {
//*slot = oran_sync_info.sl;
cnt++;
}
LOG_D(HW, "cnt %d, Reading %d.%d\n", cnt, *frame, *slot);
last_slot = *slot;
#endif
// return(0);
struct xran_fh_config *fh_cfg = get_xran_fh_config(0);
@@ -743,11 +643,7 @@ int xran_fh_rx_read_slot(ru_info_t *ru, int *frame, int *slot)
struct xran_rx_packet_ctl *p_rx_packet_ctl = &pRbMap->sFrontHaulRxPacketCtrl[sym_idx];
uint32_t one_rb_size =
(((pRbElm->iqWidth == 0) || (pRbElm->iqWidth == 16)) ? (N_SC_PER_PRB * 2 * 2) : (3 * pRbElm->iqWidth + 1));
#ifndef USE_POLLING
int32_t nRxPkt = info->nRxPkt[cc_id][ant_id][sym_idx];
#else
int32_t nRxPkt = oran_sync_info.nRxPkt[cc_id][ant_id][sym_idx];
#endif
int32_t nRxPkt = info->nRxPkt[cc_id][ant_id][sym_idx];
LOG_D(HW, "nRxPkt %d\n", nRxPkt);
for (int pkt_idx = 0; pkt_idx < nRxPkt; pkt_idx++) {
uint8_t *pData;