enb: set maximum allowed TTI difference between PHY and Stack TTI clocks for ZMQ

this fixes the issue where PHY and MAC threads, and the processing
of events therein, are drifting apart too much.

This patch effectivly enforces a strong wait on the PHY if the
stack thread is too slow in processing its tasks.

For RF hardware the default is still 8192 TTIs, for ZMQ 1 TTI is used.
This commit is contained in:
Andre Puschmann 2020-06-04 21:32:40 +02:00
parent a1d64c1efe
commit 06d31f46ba
5 changed files with 30 additions and 15 deletions

View File

@ -147,7 +147,7 @@ private:
srslte::logger_stdout logger_stdout;
srslte::logger_file logger_file;
srslte::logger* logger = nullptr;
srslte::log_filter log; // Own logger for eNB
srslte::log_ref log; // Own logger for eNB
srslte::log_filter pool_log;

View File

@ -68,6 +68,7 @@ typedef struct {
typedef struct {
std::string type;
uint32_t sync_queue_size; // Max allowed difference between PHY and Stack clocks (in TTI)
mac_args_t mac;
s1ap_args_t s1ap;
pcap_args_t mac_pcap;

View File

@ -45,14 +45,15 @@ int enb::init(const all_args_t& args_, srslte::logger* logger_)
int ret = SRSLTE_SUCCESS;
logger = logger_;
// Init UE log
log.init("ENB ", logger);
log.set_level(srslte::LOG_LEVEL_INFO);
log.info("%s", get_build_string().c_str());
// Init eNB log
srslte::logmap::set_default_logger(logger);
log = srslte::logmap::get("ENB");
log->set_level(srslte::LOG_LEVEL_INFO);
log->info("%s", get_build_string().c_str());
// Validate arguments
if (parse_args(args_)) {
log.console("Error processing arguments.\n");
log->console("Error processing arguments.\n");
return SRSLTE_ERROR;
}
@ -63,32 +64,32 @@ int enb::init(const all_args_t& args_, srslte::logger* logger_)
// Create layers
std::unique_ptr<enb_stack_lte> lte_stack(new enb_stack_lte(logger));
if (!lte_stack) {
log.console("Error creating eNB stack.\n");
log->console("Error creating eNB stack.\n");
return SRSLTE_ERROR;
}
std::unique_ptr<srslte::radio> lte_radio = std::unique_ptr<srslte::radio>(new srslte::radio(logger));
if (!lte_radio) {
log.console("Error creating radio multi instance.\n");
log->console("Error creating radio multi instance.\n");
return SRSLTE_ERROR;
}
std::unique_ptr<srsenb::phy> lte_phy = std::unique_ptr<srsenb::phy>(new srsenb::phy(logger));
if (!lte_phy) {
log.console("Error creating LTE PHY instance.\n");
log->console("Error creating LTE PHY instance.\n");
return SRSLTE_ERROR;
}
// Init Radio
if (lte_radio->init(args.rf, lte_phy.get())) {
log.console("Error initializing radio.\n");
log->console("Error initializing radio.\n");
ret = SRSLTE_ERROR;
}
// Only Init PHY if radio couldn't be initialized
if (ret == SRSLTE_SUCCESS) {
if (lte_phy->init(args.phy, phy_cfg, lte_radio.get(), lte_stack.get())) {
log.console("Error initializing PHY.\n");
log->console("Error initializing PHY.\n");
ret = SRSLTE_ERROR;
}
}
@ -96,7 +97,7 @@ int enb::init(const all_args_t& args_, srslte::logger* logger_)
// Only init Stack if both radio and PHY could be initialized
if (ret == SRSLTE_SUCCESS) {
if (lte_stack->init(args.stack, rrc_cfg, lte_phy.get())) {
log.console("Error initializing stack.\n");
log->console("Error initializing stack.\n");
ret = SRSLTE_ERROR;
}
}
@ -108,8 +109,8 @@ int enb::init(const all_args_t& args_, srslte::logger* logger_)
started = true; // set to true in any case to allow stopping the eNB if an error happened
if (ret == SRSLTE_SUCCESS) {
log.console("\n==== eNodeB started ===\n");
log.console("Type <t> to view trace\n");
log->console("\n==== eNodeB started ===\n");
log->console("Type <t> to view trace\n");
} else {
// if any of the layers failed to start, make sure the rest is stopped in a controlled manner
stop();

View File

@ -23,6 +23,7 @@
#include "srsenb/hdr/cfg_parser.h"
#include "srsenb/hdr/enb.h"
#include "srslte/asn1/rrc_asn1_utils.h"
#include "srslte/common/multiqueue.h"
#include "srslte/phy/common/phy_common.h"
#include "srslte/srslte.h"
#include <boost/algorithm/string.hpp>
@ -1064,6 +1065,15 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_
// RRC needs eNB id for SIB1 packing
rrc_cfg_->enb_id = args_->stack.s1ap.enb_id;
// Set sync queue capacity to 1 for ZMQ
if (args_->rf.device_name == "zmq") {
srslte::logmap::get("ENB")->info("Using sync queue size of one for ZMQ based radio.");
args_->stack.sync_queue_size = 1;
} else {
// use default size
args_->stack.sync_queue_size = MULTIQUEUE_DEFAULT_CAPACITY;
}
return SRSLTE_SUCCESS;
}

View File

@ -33,11 +33,11 @@ enb_stack_lte::enb_stack_lte(srslte::logger* logger_) :
timers(128), logger(logger_), pdcp(this, "PDCP"), thread("STACK")
{
enb_queue_id = pending_tasks.add_queue();
sync_queue_id = pending_tasks.add_queue();
mme_queue_id = pending_tasks.add_queue();
gtpu_queue_id = pending_tasks.add_queue();
mac_queue_id = pending_tasks.add_queue();
stack_queue_id = pending_tasks.add_queue();
// sync_queue is added in init()
pool = byte_buffer_pool::get_instance();
}
@ -100,6 +100,9 @@ int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_)
// Init Rx socket handler
rx_sockets.reset(new srslte::rx_multisocket_handler("ENBSOCKETS", stack_log));
// add sync queue
sync_queue_id = pending_tasks.add_queue(args.sync_queue_size);
// Init all layers
mac.init(args.mac, rrc_cfg.cell_list, phy, &rlc, &rrc, this, mac_log);
rlc.init(&pdcp, &rrc, &mac, &timers, rlc_log);