stack,nr: isolate calls between LTE and NR stacks via the task multiqueue

This commit is contained in:
Francisco Paisana 2021-10-04 11:15:31 +01:00
parent 9160c783c9
commit 23bf542ae7
6 changed files with 31 additions and 29 deletions

View File

@ -90,17 +90,9 @@ public:
virtual void set_activity_user(uint16_t eutra_rnti) = 0;
};
class stack_nr_interface_stack_eutra
{
public:
/// Helper method to provide time signal to NR-RRC (PHY only sends TTI ticks to EUTRA stack)
virtual void tti_clock() = 0;
};
// combined interface used by X2 adapter
class x2_interface : public rrc_nr_interface_rrc,
public rrc_eutra_interface_rrc_nr,
public stack_nr_interface_stack_eutra,
public pdcp_interface_gtpu, // allow GTPU to access PDCP in DL direction
public gtpu_interface_pdcp // allow PDCP to access GTPU in UL direction
{};

View File

@ -46,8 +46,8 @@ public:
~enb_stack_lte() final;
// eNB stack base interface
int init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_, phy_interface_stack_lte* phy_, x2_interface* x2_);
void stop() final;
int init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_, phy_interface_stack_lte* phy_, x2_interface* x2_);
void stop() final;
std::string get_type() final;
bool get_metrics(stack_metrics_t* metrics) final;
@ -111,14 +111,21 @@ public:
// rrc_eutra_interface_rrc_nr
void sgnb_addition_ack(uint16_t eutra_rnti, sgnb_addition_ack_params_t params) final
{
rrc.sgnb_addition_ack(eutra_rnti, params);
x2_task_queue.push([this, eutra_rnti, params]() { rrc.sgnb_addition_ack(eutra_rnti, params); });
}
void sgnb_addition_reject(uint16_t eutra_rnti) final
{
x2_task_queue.push([this, eutra_rnti]() { rrc.sgnb_addition_reject(eutra_rnti); });
}
void sgnb_addition_reject(uint16_t eutra_rnti) final { rrc.sgnb_addition_reject(eutra_rnti); }
void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) final
{
rrc.sgnb_addition_complete(eutra_rnti, nr_rnti);
x2_task_queue.push([this, eutra_rnti, nr_rnti]() { rrc.sgnb_addition_complete(eutra_rnti, nr_rnti); });
}
void set_activity_user(uint16_t eutra_rnti) final
{
// Note: RRC processes activity asynchronously, so there is no need to use x2_task_queue
rrc.set_activity_user(eutra_rnti);
}
void set_activity_user(uint16_t eutra_rnti) final { rrc.set_activity_user(eutra_rnti); }
// gtpu_interface_pdcp
void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu);
@ -151,7 +158,7 @@ private:
// task handling
srsran::task_scheduler task_sched;
srsran::task_queue_handle enb_task_queue, sync_task_queue, metrics_task_queue;
srsran::task_queue_handle enb_task_queue, sync_task_queue, metrics_task_queue, x2_task_queue;
// bearer management
enb_bearer_manager bearers; // helper to manage mapping between EPS and radio bearers
@ -165,7 +172,7 @@ private:
srsenb::s1ap s1ap;
// RAT-specific interfaces
phy_interface_stack_lte* phy = nullptr;
phy_interface_stack_lte* phy = nullptr;
// state
std::atomic<bool> started{false};

View File

@ -87,10 +87,14 @@ public:
// X2 data interface
void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu, int pdcp_sn = -1) final
{
pdcp.write_sdu(rnti, lcid, std::move(sdu), pdcp_sn);
auto task = [this, rnti, lcid, pdcp_sn](srsran::unique_byte_buffer_t& sdu) {
pdcp.write_sdu(rnti, lcid, std::move(sdu), pdcp_sn);
};
gtpu_task_queue.push(std::bind(task, std::move(sdu)));
}
std::map<uint32_t, srsran::unique_byte_buffer_t> get_buffered_pdus(uint16_t rnti, uint32_t lcid) final
{
// TODO: make it thread-safe. For now, this function is unused
return pdcp.get_buffered_pdus(rnti, lcid);
}
@ -111,7 +115,7 @@ private:
// task scheduling
static const int STACK_MAIN_THREAD_PRIO = 4;
srsran::task_scheduler task_sched;
srsran::task_multiqueue::queue_handle sync_task_queue, ue_task_queue, gw_task_queue, mac_task_queue;
srsran::task_multiqueue::queue_handle sync_task_queue, ue_task_queue, gtpu_task_queue, mac_task_queue;
// derived
srsenb::mac_nr mac;

View File

@ -93,15 +93,6 @@ public:
eutra_stack->set_activity_user(eutra_rnti);
}
// stack_nr_interface_stack_eutra
void tti_clock()
{
if (nr_stack == nullptr) {
return;
}
nr_stack->tti_clock();
}
// pdcp_interface_gtpu
void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu, int pdcp_sn = -1)
{

View File

@ -164,6 +164,11 @@ int enb_stack_lte::init(const stack_args_t& args_,
// add sync queue
sync_task_queue = task_sched.make_task_queue(args.sync_queue_size);
// add x2 queue
if (x2_ != nullptr) {
x2_task_queue = task_sched.make_task_queue();
}
// setup bearer managers
gtpu_adapter.reset(new gtpu_pdcp_adapter(stack_logger, &pdcp, x2_, &gtpu, bearers));
@ -286,7 +291,10 @@ void enb_stack_lte::run_thread()
void enb_stack_lte::write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu)
{
// call GTPU adapter to map to EPS bearer
gtpu_adapter->write_pdu(rnti, lcid, std::move(pdu));
auto task = [this, rnti, lcid](srsran::unique_byte_buffer_t& pdu) {
gtpu_adapter->write_pdu(rnti, lcid, std::move(pdu));
};
x2_task_queue.push(std::bind(task, std::move(pdu)));
}
} // namespace srsenb

View File

@ -32,7 +32,7 @@ gnb_stack_nr::gnb_stack_nr(srslog::sink& log_sink) :
{
ue_task_queue = task_sched.make_task_queue();
sync_task_queue = task_sched.make_task_queue();
gw_task_queue = task_sched.make_task_queue();
gtpu_task_queue = task_sched.make_task_queue();
mac_task_queue = task_sched.make_task_queue();
}