From e4b012555fe425709f6b639ac9723518bcd20043 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Fri, 28 Feb 2025 12:33:33 +0100 Subject: [PATCH 1/3] Fix possible deadlock in NR UE Remove pthread_mutex_init call from nr_ue_init_mac. The function is reentrant causing mutex overwrite and possible hanging of the NR UE. --- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 9147249c1e..35167b6173 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -70,7 +70,6 @@ void nr_ue_init_mac(NR_UE_MAC_INST_t *mac) mac->p_Max_alt = INT_MIN; mac->n_ta_offset = -1; mac->ntn_ta.ntn_params_changed = false; - pthread_mutex_init(&mac->if_mutex, NULL); reset_mac_inst(mac); // need to inizialize because might not been setup (optional timer) @@ -137,6 +136,8 @@ NR_UE_MAC_INST_t *nr_l2_init_ue(int nb_inst) NR_UE_MAC_INST_t *mac = &nr_ue_mac_inst[j]; mac->ue_id = j; nr_ue_init_mac(mac); + int ret = pthread_mutex_init(&mac->if_mutex, NULL); + AssertFatal(ret == 0, "Mutex init failed\n"); nr_ue_mac_default_configs(mac); if (IS_SA_MODE(get_softmodem_params())) ue_init_config_request(mac, get_slots_per_frame_from_scs(get_softmodem_params()->numerology)); From 953e4a448b4f9cc83fd266002a745e631b55349f Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Fri, 28 Feb 2025 12:38:31 +0100 Subject: [PATCH 2/3] Command line option for rfsim server hanging workaround Enable/disable workaround based on a new option "hanging-workaround". This addresses an issue where the workaround will trigger even if there is no risk of a permanent lockup of the system. --- radio/rfsimulator/README.md | 21 +++++++++++---------- radio/rfsimulator/simulator.c | 6 +++++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/radio/rfsimulator/README.md b/radio/rfsimulator/README.md index dac8b155ad..ae46034cec 100644 --- a/radio/rfsimulator/README.md +++ b/radio/rfsimulator/README.md @@ -69,16 +69,17 @@ the corresponding section in the configuration file. The RF simulator is using the configuration module, and its parameters are defined in a specific section called "rfsimulator". Add the following options to the command line in order to enable different RFSim features: -| CL option | usage | default | -|:--------------------- |:-------------------------------------------------------------------------------|----: | -|`--rfsimulator.serveraddr `| IPv4v6 address or DNS name to connect to, or `server` to behave as a IPv4v6 TCP server | 127.0.0.1 | -|`--rfsimulator.serverport `| port number to connect to or to listen on (eNB, which behaves as a tcp server) | 4043 | -|`--rfsimulator.options` | list of comma separated run-time options, two are supported: `chanmod`, `saviq`| all options disabled | -|`--rfsimulator.options saviq` | store IQs to a file for future replay | disabled | -|`--rfsimulator.options chanmod` | enable the channel model | disabled | -|`--rfsimulator.IQfile ` | path to a file to store the IQ samples to (only with `saviq`) | `/tmp/rfsimulator.iqs` | -|`--rfsimulator.prop_delay` | simulated receive-path (gNB: UL, UE: DL) propagation delay in ms | 0 | -|`--rfsimulator.wait_timeout` | wait timeout when no UE is connected | 1 | +| CL option | usage | default | +|:--------------------- |:-------------------------------------------------------------------------------|----: | +|`--rfsimulator.serveraddr ` | IPv4v6 address or DNS name to connect to, or `server` to behave as a IPv4v6 TCP server | 127.0.0.1 | +|`--rfsimulator.serverport ` | port number to connect to or to listen on (eNB, which behaves as a tcp server) | 4043 | +|`--rfsimulator.options` | list of comma separated run-time options, two are supported: `chanmod`, `saviq`| all options disabled | +|`--rfsimulator.options saviq` | store IQs to a file for future replay | disabled | +|`--rfsimulator.options chanmod` | enable the channel model | disabled | +|`--rfsimulator.IQfile ` | path to a file to store the IQ samples to (only with `saviq`) | `/tmp/rfsimulator.iqs` | +|`--rfsimulator.prop_delay` | simulated receive-path (gNB: UL, UE: DL) propagation delay in ms | 0 | +|`--rfsimulator.wait_timeout` | wait timeout when no UE is connected | 1 | +|`--rfismulator.hanging-workaround`| Enable workaround to de-block potentially hanging server on new client connection. | 0 | Please refer to this document [`SIMULATION/TOOLS/DOC/channel_simulation.md`](../../openair1/SIMULATION/TOOLS/DOC/channel_simulation.md) for information about using the RFSimulator options to run the simulator with a channel model. diff --git a/radio/rfsimulator/simulator.c b/radio/rfsimulator/simulator.c index c733f4c8a2..8cf4324dd7 100644 --- a/radio/rfsimulator/simulator.c +++ b/radio/rfsimulator/simulator.c @@ -101,6 +101,8 @@ typedef enum { SIMU_ROLE_SERVER = 1, SIMU_ROLE_CLIENT } simuRole; #define RFSIM_CONFIG_HELP_OPTIONS " list of comma separated options to enable rf simulator functionalities. Available options: \n"\ " chanmod: enable channel modelisation\n"\ " saviq: enable saving written iqs to a file\n" +#define CONFIG_HELP_HANG_WORKAROUND "Enable workaroud for server mode hanging on new client connection.\n" + /*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* configuration parameters for the rfsimulator device */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ @@ -117,6 +119,7 @@ typedef enum { SIMU_ROLE_SERVER = 1, SIMU_ROLE_CLIENT } simuRole; {"offset", "\n", simOpt, .u64ptr=&(rfsimulator->chan_offset), .defint64val=0, TYPE_UINT64, 0 },\ {"prop_delay", "\n", simOpt, .dblptr=&(rfsimulator->prop_delay_ms), .defdblval=0.0, TYPE_DOUBLE, 0 },\ {"wait_timeout", "\n", simOpt, .iptr=&(rfsimulator->wait_timeout), .defintval=1, TYPE_INT, 0 },\ + {"hanging-workaround", CONFIG_HELP_HANG_WORKAROUND, simOpt, .iptr=&rfsimulator->hanging_workaround, .defintval=0, TYPE_INT, 0 },\ }; static void getset_currentchannels_type(char *buf, int debug, webdatadef_t *tdata, telnet_printfunc_t prnt); @@ -181,6 +184,7 @@ typedef struct { poll_telnetcmdq_func_t poll_telnetcmdq; int wait_timeout; double prop_delay_ms; + int hanging_workaround; } rfsimulator_state_t; @@ -994,7 +998,7 @@ static int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimest t->nextRxTstamp + nsamps); flushInput(t, 3, nsamps); } - if (loops++ > 10 && t->role == SIMU_ROLE_SERVER) { + if (t->hanging_workaround && loops++ > 10 && t->role == SIMU_ROLE_SERVER) { // Just start producing samples. The clients will catch up. have_to_wait = false; LOG_W(HW, From 86725135178d4501ed34cfef581383bc6062e25a Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Wed, 26 Feb 2025 17:56:25 +0100 Subject: [PATCH 3/3] Allow >1 channel models on rfsim server Use `rfsimu_channel_ue1`, `rfsimu_channel_ue2`, etc. if you want to use different channel models for each client. The client connection order determines its channel model name. --- openair1/SIMULATION/TOOLS/DOC/channel_simulation.md | 6 +++++- radio/rfsimulator/simulator.c | 12 +++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md b/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md index 30cc68e662..e3e3bd3189 100644 --- a/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md +++ b/openair1/SIMULATION/TOOLS/DOC/channel_simulation.md @@ -90,7 +90,11 @@ channelmod = { }; ``` -where `rfsimu_channel_ue0` will be activated on server side (i.e. eNB/gNB) for uplink and `rfsimu_channel_enB0` will be activated on client side (i.e. UE) for downlink. +where `rfsimu_channel_ue0` will be activated on server side for uplink and `rfsimu_channel_enB0` will be activated on client side for downlink. + +Use `rfsimu_channel_ue1`, `rfsimu_channel_ue2`, etc. if you want to use different channel models for each client. The client connection order determines its channel model. + +The server could be either the UE or the gNB, the channel name suffix does not depend on the application but on the rfsimulators role (server/client). ## Edit the configuration file diff --git a/radio/rfsimulator/simulator.c b/radio/rfsimulator/simulator.c index 8cf4324dd7..b11f4034ca 100644 --- a/radio/rfsimulator/simulator.c +++ b/radio/rfsimulator/simulator.c @@ -260,11 +260,17 @@ static int allocCirBuf(rfsimulator_state_t *bridge, int sock) tableNor(rand); init_done=true; } - char *modelname = (bridge->role == SIMU_ROLE_SERVER) ? "rfsimu_channel_ue0" : "rfsimu_channel_enB0"; + char modelname[30]; + snprintf(modelname, sizeofArray(modelname), "rfsimu_channel_%s%d", (bridge->role == SIMU_ROLE_SERVER) ? "ue" : "enB", nb_ue); ptr->channel_model = find_channel_desc_fromname(modelname); // path_loss in dB if (!ptr->channel_model) { - LOG_E(HW, "Channel model %s not found, check config file\n", modelname); - return -1; + // Use legacy method to find channel model - this will use the same channel model for all clients + char *legacy_model_name = (bridge->role == SIMU_ROLE_SERVER) ? "rfsimu_channel_ue0" : "rfsimu_channel_enB0"; + ptr->channel_model = find_channel_desc_fromname(legacy_model_name); + if (!ptr->channel_model) { + LOG_E(HW, "Channel model %s/%s not found, check config file\n", modelname, legacy_model_name); + return -1; + } } set_channeldesc_owner(ptr->channel_model, RFSIMU_MODULEID);