Skip to content

Commit 5a7a943

Browse files
committed
units: added the CU-UP application unit. Updated gNB and CU applications to use it
1 parent 3b0bafb commit 5a7a943

22 files changed

+269
-507
lines changed

apps/cu/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ add_executable(srscu
1111
cu_appconfig_cli11_schema.cpp
1212
cu_appconfig_validator.cpp
1313
cu_appconfig_yaml_writer.cpp
14-
cu_worker_manager.cpp
1514
)
1615

1716
install(TARGETS srscu

apps/cu/cu.cpp

Lines changed: 50 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -30,37 +30,32 @@
3030
#include "srsran/support/versioning/version.h"
3131

3232
#include "apps/cu/cu_appconfig_cli11_schema.h"
33-
#include "apps/cu/cu_worker_manager.h"
3433
#include "apps/units/cu_cp/cu_cp_application_unit.h"
3534
#include "apps/units/cu_cp/cu_cp_config_translators.h"
3635
#include "apps/units/cu_cp/cu_cp_unit_config.h"
3736
#include "apps/units/cu_cp/pcap_factory.h"
38-
#include "apps/units/cu_up/cu_up_builder.h"
39-
#include "apps/units/cu_up/cu_up_logger_registrator.h"
37+
#include "apps/units/cu_up/cu_up_application_unit.h"
4038
#include "apps/units/cu_up/cu_up_unit_config.h"
41-
#include "apps/units/cu_up/cu_up_unit_config_cli11_schema.h"
42-
#include "apps/units/cu_up/cu_up_unit_config_translators.h"
43-
#include "apps/units/cu_up/cu_up_unit_config_validator.h"
44-
#include "apps/units/cu_up/cu_up_unit_config_yaml_writer.h"
45-
#include "apps/units/cu_up/cu_up_wrapper.h"
4639
#include "apps/units/cu_up/pcap_factory.h"
4740
#include "srsran/cu_up/cu_up.h"
48-
#include "srsran/cu_up/cu_up_factory.h"
4941

5042
// TODO remove apps/gnb/*.h
5143
#include "apps/gnb/adapters/e2_gateway_remote_connector.h"
5244
#include "apps/gnb/gnb_appconfig_translators.h"
53-
#include "srsran/e1ap/gateways/e1_local_connector_factory.h"
54-
#include "srsran/ngap/gateways/n2_connection_client_factory.h"
5545

5646
#include "apps/services/application_message_banners.h"
5747
#include "apps/services/application_tracer.h"
5848
#include "apps/services/buffer_pool/buffer_pool_manager.h"
5949
#include "apps/services/stdin_command_dispatcher.h"
50+
#include "apps/services/worker_manager.h"
51+
#include "apps/services/worker_manager_config.h"
6052
#include "cu_appconfig.h"
6153
#include "cu_appconfig_validator.h"
6254
#include "cu_appconfig_yaml_writer.h"
6355

56+
#include "srsran/e1ap/gateways/e1_local_connector_factory.h"
57+
#include "srsran/ngap/gateways/n2_connection_client_factory.h"
58+
6459
#include <atomic>
6560
#include <thread>
6661

@@ -118,9 +113,9 @@ static void initialize_log(const std::string& filename)
118113
srslog::init();
119114
}
120115

121-
static void register_app_logs(const logger_appconfig& log_cfg,
122-
cu_cp_application_unit& cu_cp_app_unit,
123-
const cu_up_unit_logger_config& cu_up_loggers)
116+
static void register_app_logs(const logger_appconfig& log_cfg,
117+
cu_cp_application_unit& cu_cp_app_unit,
118+
cu_up_application_unit& cu_up_app_unit)
124119
{
125120
// Set log-level of app and all non-layer specific components to app level.
126121
for (const auto& id : {"ALL", "SCTP-GW", "IO-EPOLL", "UDP-GW", "PCAP"}) {
@@ -145,19 +140,23 @@ static void register_app_logs(const logger_appconfig& log_cfg,
145140

146141
// Register units logs.
147142
cu_cp_app_unit.on_loggers_registration();
148-
register_cu_up_loggers(cu_up_loggers);
143+
cu_up_app_unit.on_loggers_registration();
149144
}
150145

151-
// Temporary helper to create CU-UP.
152-
// TODO remove
153-
std::unique_ptr<srs_cu_up::cu_up_interface> app_build_cu_up(const cu_up_unit_config& unit_cfg,
154-
cu_worker_manager& workers,
155-
const std::string& f1u_bind_addr,
156-
srs_cu_up::e1_connection_client& e1_conn_client,
157-
f1u_cu_up_gateway& f1u_gateway,
158-
dlt_pcap& gtpu_pcap,
159-
timer_manager& timers,
160-
io_broker& io_brk);
146+
static void fill_cu_worker_manager_config(worker_manager_config& config, const cu_appconfig& unit_cfg)
147+
{
148+
config.nof_low_prio_threads = unit_cfg.expert_execution_cfg.threads.non_rt_threads.nof_non_rt_threads;
149+
config.low_prio_sched_config = unit_cfg.expert_execution_cfg.affinities.low_priority_cpu_cfg;
150+
}
151+
152+
static void autoderive_cu_up_parameters_after_parsing(cu_up_unit_config& cu_up_cfg, const cu_cp_unit_config& cu_cp_cfg)
153+
{
154+
// If no UPF is configured, we set the UPF configuration from the CU-CP AMF configuration.
155+
if (cu_up_cfg.upf_cfg.bind_addr == "auto") {
156+
cu_up_cfg.upf_cfg.bind_addr = cu_cp_cfg.amf_config.amf.bind_addr;
157+
}
158+
cu_up_cfg.upf_cfg.no_core = cu_cp_cfg.amf_config.no_core;
159+
}
161160

162161
int main(int argc, char** argv)
163162
{
@@ -189,17 +188,16 @@ int main(int argc, char** argv)
189188
cu_cp_app_unit->get_cu_cp_unit_config().pcap_cfg.set_default_filename("/tmp/cu");
190189
cu_cp_app_unit->on_parsing_configuration_registration(app);
191190

192-
cu_up_unit_config cu_up_config;
193-
cu_up_config.pcap_cfg.set_default_filename("/tmp/cu");
194-
configure_cli11_with_cu_up_unit_config_schema(app, cu_up_config);
191+
auto cu_up_app_unit = create_cu_up_application_unit();
192+
cu_up_app_unit->get_cu_up_unit_config().pcap_cfg.set_default_filename("/tmp/cu");
193+
cu_up_app_unit->on_parsing_configuration_registration(app);
195194

196195
// Set the callback for the app calling all the autoderivation functions.
197-
app.callback([&app, &cu_cp_app_unit, &cu_up_config]() {
196+
app.callback([&app, &cu_cp_app_unit, &cu_up_app_unit]() {
198197
cu_cp_app_unit->on_configuration_parameters_autoderivation(app);
199198

200-
autoderive_cu_up_parameters_after_parsing(cu_cp_app_unit->get_cu_cp_unit_config().amf_config.amf.bind_addr,
201-
cu_cp_app_unit->get_cu_cp_unit_config().amf_config.no_core,
202-
cu_up_config);
199+
autoderive_cu_up_parameters_after_parsing(cu_up_app_unit->get_cu_up_unit_config(),
200+
cu_cp_app_unit->get_cu_cp_unit_config());
203201
});
204202

205203
// Parse arguments.
@@ -208,21 +206,21 @@ int main(int argc, char** argv)
208206
// Check the modified configuration.
209207
if (!validate_cu_appconfig(cu_cfg) ||
210208
!cu_cp_app_unit->on_configuration_validation(os_sched_affinity_bitmask::available_cpus()) ||
211-
!validate_cu_up_unit_config(cu_up_config)) {
209+
!cu_up_app_unit->on_configuration_validation(os_sched_affinity_bitmask::available_cpus())) {
212210
report_error("Invalid configuration detected.\n");
213211
}
214212

215213
// Set up logging.
216214
initialize_log(cu_cfg.log_cfg.filename);
217-
register_app_logs(cu_cfg.log_cfg, *cu_cp_app_unit, cu_up_config.loggers);
215+
register_app_logs(cu_cfg.log_cfg, *cu_cp_app_unit, *cu_up_app_unit);
218216

219217
// Log input configuration.
220218
srslog::basic_logger& config_logger = srslog::fetch_basic_logger("CONFIG");
221219
if (config_logger.debug.enabled()) {
222220
YAML::Node node;
223221
fill_cu_appconfig_in_yaml_schema(node, cu_cfg);
224-
fill_cu_up_config_in_yaml_schema(node, cu_up_config);
225222
cu_cp_app_unit->dump_config(node);
223+
cu_up_app_unit->dump_config(node);
226224
config_logger.debug("Input configuration (all values): \n{}", YAML::Dump(node));
227225
} else {
228226
config_logger.info("Input configuration (only non-default values): \n{}", app.config_to_str(false, false));
@@ -259,13 +257,17 @@ int main(int argc, char** argv)
259257
check_drm_kms_polling(cu_logger);
260258

261259
// Create worker manager.
262-
cu_worker_manager workers{
263-
cu_cfg, cu_cp_app_unit->get_cu_cp_unit_config().pcap_cfg, cu_up_config.pcap_cfg, cu_up_config.gtpu_queue_size};
260+
worker_manager_config worker_manager_cfg;
261+
fill_cu_worker_manager_config(worker_manager_cfg, cu_cfg);
262+
cu_cp_app_unit->fill_worker_manager_config(worker_manager_cfg);
263+
cu_up_app_unit->fill_worker_manager_config(worker_manager_cfg);
264+
worker_manager workers{worker_manager_cfg};
264265

265266
// Create layer specific PCAPs.
266267
cu_cp_dlt_pcaps cu_cp_dlt_pcaps =
267268
create_cu_cp_dlt_pcap(cu_cp_app_unit->get_cu_cp_unit_config().pcap_cfg, *workers.get_executor_getter());
268-
cu_up_dlt_pcaps cu_up_dlt_pcaps = create_cu_up_dlt_pcaps(cu_up_config.pcap_cfg, *workers.get_executor_getter());
269+
cu_up_dlt_pcaps cu_up_dlt_pcaps =
270+
create_cu_up_dlt_pcaps(cu_up_app_unit->get_cu_up_unit_config().pcap_cfg, *workers.get_executor_getter());
269271

270272
// Create IO broker.
271273
const auto& low_prio_cpu_mask = cu_cfg.expert_execution_cfg.affinities.low_priority_cpu_cfg.mask;
@@ -294,7 +296,7 @@ int main(int argc, char** argv)
294296
std::unique_ptr<srs_cu_up::ngu_gateway> cu_f1u_gw =
295297
srs_cu_up::create_udp_ngu_gateway(cu_f1u_gw_config, *epoll_broker, *workers.cu_up_io_ul_exec);
296298
std::unique_ptr<f1u_cu_up_udp_gateway> cu_f1u_conn =
297-
srs_cu_up::create_split_f1u_gw({cu_f1u_gw.get(), cu_f1u_gtpu_demux.get(), *cu_up_dlt_pcaps.f1u, GTPU_PORT});
299+
srs_cu_up::create_split_f1u_gw({*cu_f1u_gw, *cu_f1u_gtpu_demux, *cu_up_dlt_pcaps.f1u, GTPU_PORT});
298300

299301
// Create E1AP local connector
300302
std::unique_ptr<e1_local_connector> e1_gw =
@@ -350,14 +352,15 @@ int main(int argc, char** argv)
350352
cu_f1c_gw->attach_cu_cp(cu_cp_obj.get_f1c_handler());
351353

352354
// Create and start CU-UP
353-
std::unique_ptr<srs_cu_up::cu_up_interface> cu_up_obj = app_build_cu_up(cu_up_config,
354-
workers,
355-
cu_cfg.nru_cfg.bind_addr,
356-
*e1_gw,
357-
*cu_f1u_conn,
358-
*cu_up_dlt_pcaps.n3,
359-
*cu_timers,
360-
*epoll_broker);
355+
cu_up_unit_dependencies cu_up_unit_deps;
356+
cu_up_unit_deps.workers = &workers;
357+
cu_up_unit_deps.e1ap_conn_client = e1_gw.get();
358+
cu_up_unit_deps.f1u_gateway = cu_f1u_conn.get();
359+
cu_up_unit_deps.gtpu_pcap = cu_up_dlt_pcaps.n3.get();
360+
cu_up_unit_deps.timers = cu_timers;
361+
cu_up_unit_deps.io_brk = epoll_broker.get();
362+
363+
std::unique_ptr<srs_cu_up::cu_up_interface> cu_up_obj = cu_up_app_unit->create_cu_up_unit(cu_up_unit_deps);
361364
cu_up_obj->start();
362365

363366
{
@@ -389,45 +392,3 @@ int main(int argc, char** argv)
389392

390393
return 0;
391394
}
392-
393-
// Temporary helper to create CU-UP.
394-
// TODO remove
395-
std::unique_ptr<srs_cu_up::cu_up_interface> app_build_cu_up(const cu_up_unit_config& unit_cfg,
396-
cu_worker_manager& workers,
397-
const std::string& f1u_bind_address,
398-
srs_cu_up::e1_connection_client& e1_conn_client,
399-
f1u_cu_up_gateway& f1u_gateway,
400-
dlt_pcap& gtpu_pcap,
401-
timer_manager& timers,
402-
io_broker& io_brk)
403-
{
404-
srs_cu_up::cu_up_configuration config = generate_cu_up_config(unit_cfg);
405-
config.ctrl_executor = workers.cu_up_ctrl_exec;
406-
config.cu_up_e2_exec = workers.cu_up_e2_exec;
407-
config.ue_exec_pool = workers.cu_up_exec_mapper.get();
408-
config.io_ul_executor = workers.cu_up_io_ul_exec; // Optionally select separate exec for UL IO
409-
config.e1ap.e1_conn_client = &e1_conn_client;
410-
config.f1u_gateway = &f1u_gateway;
411-
config.gtpu_pcap = &gtpu_pcap;
412-
config.timers = &timers;
413-
config.qos = generate_cu_up_qos_config(unit_cfg);
414-
415-
config.net_cfg.f1u_bind_addr = f1u_bind_address; // TODO remove this parameter and make sure that the CU-UP gets the
416-
// bind address directly from the gateway.
417-
418-
// Create NG-U gateway.
419-
std::unique_ptr<srs_cu_up::ngu_gateway> ngu_gw;
420-
if (not unit_cfg.upf_cfg.no_core) {
421-
udp_network_gateway_config ngu_gw_config = {};
422-
ngu_gw_config.bind_address = config.net_cfg.n3_bind_addr;
423-
ngu_gw_config.bind_port = config.net_cfg.n3_bind_port;
424-
ngu_gw_config.bind_interface = config.net_cfg.n3_bind_interface;
425-
ngu_gw_config.rx_max_mmsg = config.net_cfg.n3_rx_max_mmsg;
426-
ngu_gw = srs_cu_up::create_udp_ngu_gateway(ngu_gw_config, io_brk, *workers.cu_up_io_ul_exec);
427-
} else {
428-
ngu_gw = srs_cu_up::create_no_core_ngu_gateway();
429-
}
430-
config.ngu_gw = ngu_gw.get();
431-
432-
return std::make_unique<cu_up_wrapper>(std::move(ngu_gw), create_cu_up(config));
433-
}

0 commit comments

Comments
 (0)