Skip to content

Commit

Permalink
du-high: fix race condition in test mode
Browse files Browse the repository at this point in the history
  • Loading branch information
frankist authored and codebot committed Dec 19, 2024
1 parent 0b400a0 commit 6c2f055
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 133 deletions.
3 changes: 2 additions & 1 deletion lib/du/du_high/test_mode/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
add_library(srsran_du_high_adapters
mac_test_mode_adapter.cpp
f1ap_test_mode_adapter.cpp
mac_test_mode_helpers.cpp)
mac_test_mode_helpers.cpp
mac_test_mode_ue_repository.cpp)
target_link_libraries(srsran_du_high_adapters srslog srsran_support srsran_du_manager srsran_mac srsran_f1ap_du)
74 changes: 20 additions & 54 deletions lib/du/du_high/test_mode/mac_test_mode_adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,43 +65,6 @@ size_t get_ring_size(const mac_cell_creation_request& cell_cfg)

} // namespace

test_ue_info_manager::test_ue_info_manager(rnti_t rnti_start_, uint16_t nof_ues_, uint16_t nof_cells_) :
rnti_start(rnti_start_), nof_ues(nof_ues_), nof_cells(nof_cells_), pending_tasks(128)
{
}

void test_ue_info_manager::add_ue(rnti_t rnti, du_ue_index_t ue_idx, const sched_ue_config_request& sched_ue_cfg_req)
{
// Dispatch creation of UE to du_cell thread.
while (not pending_tasks.try_push([this, rnti, ue_idx, sched_ue_cfg_req]() {
rnti_to_ue_info_lookup[rnti] =
test_ue_info{.ue_idx = ue_idx, .sched_ue_cfg_req = sched_ue_cfg_req, .msg4_rx_flag = false};
})) {
srslog::fetch_basic_logger("MAC").warning("Failed to add test mode UE. Retrying...");
}
}

void test_ue_info_manager::remove_ue(rnti_t rnti)
{
while (not pending_tasks.try_push([this, rnti]() {
if (rnti_to_ue_info_lookup.count(rnti) > 0) {
rnti_to_ue_info_lookup.erase(rnti);
}
})) {
srslog::fetch_basic_logger("MAC").warning("Failed to remove test mode UE. Retrying...");
}
}

void test_ue_info_manager::process_pending_tasks()
{
unique_task task;
while (pending_tasks.try_pop(task)) {
task();
}
}

// ----

mac_test_mode_cell_adapter::mac_test_mode_cell_adapter(
const srs_du::du_test_mode_config::test_mode_ue_config& test_ue_cfg_,
const mac_cell_creation_request& cell_cfg,
Expand All @@ -110,7 +73,8 @@ mac_test_mode_cell_adapter::mac_test_mode_cell_adapter(
mac_cell_slot_handler& slot_handler_,
mac_cell_result_notifier& result_notifier_,
std::function<void(rnti_t)> dl_bs_notifier_,
test_ue_info_manager& ue_info_mgr_) :
mac_test_mode_ue_repository& ue_info_mgr_) :
cell_index(cell_cfg.cell_index),
test_ue_cfg(test_ue_cfg_),
adapted(adapted_),
pdu_handler(pdu_handler_),
Expand Down Expand Up @@ -216,7 +180,7 @@ void mac_test_mode_cell_adapter::handle_crc(const mac_crc_indication_message& ms
if (entry.slot == msg.sl_rx) {
// Forward CRC to MAC, but remove the UCI for the test mode UE.
for (mac_crc_pdu& crc : msg_copy.crcs) {
if (ue_info_mgr.is_test_ue(crc.rnti)) {
if (ue_info_mgr.is_cell_test_ue(cell_index, crc.rnti)) {
// test mode UE case.

// Find respective PUSCH PDU that was previously scheduled.
Expand Down Expand Up @@ -244,10 +208,11 @@ void mac_test_mode_cell_adapter::handle_crc(const mac_crc_indication_message& ms
}
} else {
// In case of auto-ACK mode, test mode UEs are removed from CRC.
msg_copy.crcs.erase(std::remove_if(msg_copy.crcs.begin(),
msg_copy.crcs.end(),
[this](const auto& crc) { return ue_info_mgr.is_test_ue(crc.rnti); }),
msg_copy.crcs.end());
msg_copy.crcs.erase(
std::remove_if(msg_copy.crcs.begin(),
msg_copy.crcs.end(),
[this](const auto& crc) { return ue_info_mgr.is_cell_test_ue(cell_index, crc.rnti); }),
msg_copy.crcs.end());
}

// Forward resulting CRC indication to real MAC.
Expand Down Expand Up @@ -278,7 +243,7 @@ void mac_test_mode_cell_adapter::forward_crc_ind_to_mac(const mac_crc_indication
}

for (const mac_crc_pdu& pdu : crc_msg.crcs) {
if (not ue_info_mgr.is_test_ue(pdu.rnti)) {
if (not ue_info_mgr.is_cell_test_ue(cell_index, pdu.rnti)) {
continue;
}

Expand All @@ -302,7 +267,7 @@ void mac_test_mode_cell_adapter::handle_uci(const mac_uci_indication_message& ms
if (entry.slot == msg_copy.sl_rx) {
// Forward UCI to MAC, but alter the UCI for the test mode UE.
for (mac_uci_pdu& test_uci : msg_copy.ucis) {
if (ue_info_mgr.is_test_ue(test_uci.rnti)) {
if (ue_info_mgr.is_cell_test_ue(cell_index, test_uci.rnti)) {
bool entry_found = false;
if (std::holds_alternative<mac_uci_pdu::pusch_type>(test_uci.pdu)) {
for (const ul_sched_info& pusch : entry.puschs) {
Expand Down Expand Up @@ -339,10 +304,11 @@ void mac_test_mode_cell_adapter::handle_uci(const mac_uci_indication_message& ms
}
} else {
// In case of auto-ACK mode, test mode UEs are removed from UCI.
msg_copy.ucis.erase(std::remove_if(msg_copy.ucis.begin(),
msg_copy.ucis.end(),
[this](const auto& u) { return ue_info_mgr.is_test_ue(u.rnti); }),
msg_copy.ucis.end());
msg_copy.ucis.erase(
std::remove_if(msg_copy.ucis.begin(),
msg_copy.ucis.end(),
[this](const auto& u) { return ue_info_mgr.is_cell_test_ue(cell_index, u.rnti); }),
msg_copy.ucis.end());
}

// Forward UCI indication to real MAC.
Expand All @@ -359,7 +325,7 @@ void mac_test_mode_cell_adapter::on_new_downlink_scheduler_results(const mac_dl_
{
if (last_slot_ind != dl_res.slot) {
// Process any pending tasks for the test mode UE manager asynchronously.
ue_info_mgr.process_pending_tasks();
ue_info_mgr.process_pending_tasks(cell_index);
last_slot_ind = dl_res.slot;
}

Expand All @@ -372,7 +338,7 @@ void mac_test_mode_cell_adapter::on_new_uplink_scheduler_results(const mac_ul_sc
{
if (last_slot_ind != ul_res.slot) {
// Process any pending tasks for the test mode UE manager asynchronously.
ue_info_mgr.process_pending_tasks();
ue_info_mgr.process_pending_tasks(cell_index);
last_slot_ind = ul_res.slot;
}

Expand All @@ -387,20 +353,20 @@ void mac_test_mode_cell_adapter::on_new_uplink_scheduler_results(const mac_ul_sc

// Fill the ring element with the scheduler decisions.
for (const pucch_info& pucch : ul_res.ul_res->pucchs) {
if (ue_info_mgr.is_test_ue(pucch.crnti)) {
if (ue_info_mgr.is_cell_test_ue(cell_index, pucch.crnti)) {
entry.pucchs.push_back(pucch);
}
}
for (const ul_sched_info& pusch : ul_res.ul_res->puschs) {
if (ue_info_mgr.is_test_ue(pusch.pusch_cfg.rnti)) {
if (ue_info_mgr.is_cell_test_ue(cell_index, pusch.pusch_cfg.rnti)) {
entry.puschs.push_back(pusch);
}
}
}

if (ul_res.ul_res != nullptr and not ul_res.ul_res->pucchs.empty()) {
for (const pucch_info& pucch : ul_res.ul_res->pucchs) {
if (not ue_info_mgr.is_test_ue(pucch.crnti) or ue_info_mgr.is_msg4_rxed(pucch.crnti)) {
if (not ue_info_mgr.is_cell_test_ue(cell_index, pucch.crnti) or ue_info_mgr.is_msg4_rxed(pucch.crnti)) {
// UE is not test mode or it has already received Msg4.
continue;
}
Expand Down
83 changes: 5 additions & 78 deletions lib/du/du_high/test_mode/mac_test_mode_adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,92 +10,18 @@

#pragma once

#include "srsran/adt/mpmc_queue.h"
#include "srsran/adt/unique_function.h"
#include "mac_test_mode_ue_repository.h"
#include "srsran/du/du_high/du_test_mode_config.h"
#include "srsran/mac/mac.h"
#include "srsran/mac/mac_cell_result.h"
#include "srsran/scheduler/result/pucch_info.h"
#include "srsran/scheduler/result/pusch_info.h"
#include "srsran/srslog/srslog.h"
#include <mutex>
#include <unordered_map>

namespace srsran {
namespace srs_du {

/// \brief Handles information related to the test UE(s).
class test_ue_info_manager
{
public:
test_ue_info_manager(rnti_t rnti_start_, uint16_t nof_ues_, uint16_t nof_cells_);

du_ue_index_t rnti_to_du_ue_idx(rnti_t rnti) const
{
if (rnti_to_ue_info_lookup.count(rnti) == 0) {
return INVALID_DU_UE_INDEX;
}
return rnti_to_ue_info_lookup.at(rnti).ue_idx;
}

bool is_test_ue(du_ue_index_t ue_idx) const { return ue_idx < nof_ues; }

bool is_test_ue(rnti_t rnti) const
{
return (rnti >= rnti_start) and (rnti < to_rnti(to_value(rnti_start) + nof_ues * nof_cells));
}

void add_ue(rnti_t rnti, du_ue_index_t ue_idx_, const sched_ue_config_request& sched_ue_cfg_req_);

void remove_ue(rnti_t rnti);

const sched_ue_config_request& get_sched_ue_cfg_request(rnti_t rnti) const
{
return rnti_to_ue_info_lookup.at(rnti).sched_ue_cfg_req;
}

const sched_ue_config_request* find_sched_ue_cfg_request(rnti_t rnti) const
{
auto it = rnti_to_ue_info_lookup.find(rnti);
return it != rnti_to_ue_info_lookup.end() ? &it->second.sched_ue_cfg_req : nullptr;
}

bool is_msg4_rxed(rnti_t rnti) const
{
if (rnti_to_ue_info_lookup.count(rnti) > 0) {
return rnti_to_ue_info_lookup.at(rnti).msg4_rx_flag;
}
return false;
}

void msg4_rxed(rnti_t rnti, bool msg4_rx_flag_)
{
if (rnti_to_ue_info_lookup.count(rnti) > 0) {
rnti_to_ue_info_lookup.at(rnti).msg4_rx_flag = msg4_rx_flag_;
}
}

void process_pending_tasks();

private:
struct test_ue_info {
du_ue_index_t ue_idx;
sched_ue_config_request sched_ue_cfg_req;
bool msg4_rx_flag;
};

// Parameters received from configuration.
rnti_t rnti_start;
uint16_t nof_ues;
uint16_t nof_cells;

// Mapping between UE RNTI and test UE information.
std::unordered_map<rnti_t, test_ue_info> rnti_to_ue_info_lookup;

concurrent_queue<unique_task, concurrent_queue_policy::lockfree_mpmc, concurrent_queue_wait_policy::non_blocking>
pending_tasks;
};

class phy_test_mode_adapter : public mac_result_notifier
{
public:
Expand Down Expand Up @@ -137,7 +63,7 @@ class mac_test_mode_cell_adapter : public mac_cell_control_information_handler,
mac_cell_slot_handler& slot_handler_,
mac_cell_result_notifier& result_notifier_,
std::function<void(rnti_t)> dl_bs_notifier_,
test_ue_info_manager& ue_info_mgr_);
mac_test_mode_ue_repository& ue_info_mgr_);

void on_new_downlink_scheduler_results(const mac_dl_sched_result& dl_res) override;

Expand Down Expand Up @@ -176,6 +102,7 @@ class mac_test_mode_cell_adapter : public mac_cell_control_information_handler,

size_t get_ring_idx(slot_point sl) const { return sl.to_uint() % sched_decision_history.size(); }

const du_cell_index_t cell_index;
const srs_du::du_test_mode_config::test_mode_ue_config& test_ue_cfg;
mac_cell_control_information_handler& adapted;
mac_pdu_handler& pdu_handler;
Expand All @@ -186,7 +113,7 @@ class mac_test_mode_cell_adapter : public mac_cell_control_information_handler,

std::vector<slot_decision_history> sched_decision_history;

test_ue_info_manager& ue_info_mgr;
mac_test_mode_ue_repository& ue_info_mgr;

slot_point last_slot_ind;
};
Expand Down Expand Up @@ -253,7 +180,7 @@ class mac_test_mode_adapter final : public mac_interface,
srs_du::du_test_mode_config::test_mode_ue_config test_ue;
std::unique_ptr<mac_interface> mac_adapted;

test_ue_info_manager ue_info_mgr;
mac_test_mode_ue_repository ue_info_mgr;

std::unique_ptr<phy_test_mode_adapter> phy_notifier;

Expand Down
Loading

0 comments on commit 6c2f055

Please sign in to comment.