limit minimum UL grant size to accommodate both BSR and RLC headers

master
Francisco 4 years ago committed by Francisco Paisana
parent cde61a5796
commit d3c51fdad4

@ -81,10 +81,12 @@ public:
uint32_t get_required_prb_ul(uint32_t enb_cc_idx, uint32_t req_bytes); uint32_t get_required_prb_ul(uint32_t enb_cc_idx, uint32_t req_bytes);
rbg_interval get_required_dl_rbgs(uint32_t enb_cc_idx); /// Get total pending bytes to be transmitted in DL.
srsran::interval<uint32_t> get_requested_dl_bytes(uint32_t enb_cc_idx); /// The amount of CEs to transmit depends on whether enb_cc_idx is UE's PCell
uint32_t get_pending_dl_rlc_data() const; uint32_t get_pending_dl_bytes(uint32_t enb_cc_idx);
uint32_t get_expected_dl_bitrate(uint32_t enb_cc_idx, int nof_rbgs = -1) const; rbg_interval get_required_dl_rbgs(uint32_t enb_cc_idx);
uint32_t get_pending_dl_rlc_data() const;
uint32_t get_expected_dl_bitrate(uint32_t enb_cc_idx, int nof_rbgs = -1) const;
uint32_t get_pending_ul_data_total(tti_point tti_tx_ul, int this_enb_cc_idx); uint32_t get_pending_ul_data_total(tti_point tti_tx_ul, int this_enb_cc_idx);
uint32_t get_pending_ul_new_data(tti_point tti_tx_ul, int this_enb_cc_idx); uint32_t get_pending_ul_new_data(tti_point tti_tx_ul, int this_enb_cc_idx);
@ -138,6 +140,8 @@ public:
bool pusch_enabled(tti_point tti_rx, uint32_t enb_cc_idx, bool needs_pdcch) const; bool pusch_enabled(tti_point tti_rx, uint32_t enb_cc_idx, bool needs_pdcch) const;
private: private:
srsran::interval<uint32_t> get_requested_dl_bytes(uint32_t enb_cc_idx);
bool is_sr_triggered(); bool is_sr_triggered();
tbs_info allocate_new_dl_mac_pdu(sched_interface::dl_sched_data_t* data, tbs_info allocate_new_dl_mac_pdu(sched_interface::dl_sched_data_t* data,

@ -662,7 +662,7 @@ void sf_sched::set_dl_data_sched_result(const sf_cch_allocator::alloc_result_t&
continue; continue;
} }
sched_ue* user = ue_it->second.get(); sched_ue* user = ue_it->second.get();
uint32_t data_before = user->get_requested_dl_bytes(cc_cfg->enb_cc_idx).stop(); uint32_t data_before = user->get_pending_dl_bytes(cc_cfg->enb_cc_idx);
const dl_harq_proc& dl_harq = user->get_dl_harq(data_alloc.pid, cc_cfg->enb_cc_idx); const dl_harq_proc& dl_harq = user->get_dl_harq(data_alloc.pid, cc_cfg->enb_cc_idx);
bool is_newtx = dl_harq.is_empty(); bool is_newtx = dl_harq.is_empty();
@ -678,7 +678,7 @@ void sf_sched::set_dl_data_sched_result(const sf_cch_allocator::alloc_result_t&
data_alloc.pid, data_alloc.pid,
data_alloc.user_mask, data_alloc.user_mask,
tbs, tbs,
user->get_requested_dl_bytes(cc_cfg->enb_cc_idx).stop()); user->get_pending_dl_bytes(cc_cfg->enb_cc_idx));
logger.warning("%s", srsran::to_c_str(str_buffer)); logger.warning("%s", srsran::to_c_str(str_buffer));
continue; continue;
} }
@ -698,7 +698,7 @@ void sf_sched::set_dl_data_sched_result(const sf_cch_allocator::alloc_result_t&
dl_harq.nof_retx(0) + dl_harq.nof_retx(1), dl_harq.nof_retx(0) + dl_harq.nof_retx(1),
tbs, tbs,
data_before, data_before,
user->get_requested_dl_bytes(cc_cfg->enb_cc_idx).stop(), user->get_pending_dl_bytes(cc_cfg->enb_cc_idx),
get_tti_tx_dl()); get_tti_tx_dl());
logger.info("%s", srsran::to_c_str(str_buffer)); logger.info("%s", srsran::to_c_str(str_buffer));
} }

@ -767,6 +767,11 @@ rbg_interval sched_ue::get_required_dl_rbgs(uint32_t enb_cc_idx)
return {min_pending_rbg, max_pending_rbg}; return {min_pending_rbg, max_pending_rbg};
} }
uint32_t sched_ue::get_pending_dl_bytes(uint32_t enb_cc_idx)
{
return get_requested_dl_bytes(enb_cc_idx).stop();
}
/** /**
* Returns the range (min,max) of possible MAC PDU sizes. * Returns the range (min,max) of possible MAC PDU sizes.
* - the lower boundary value is set based on the following conditions: * - the lower boundary value is set based on the following conditions:

@ -298,6 +298,7 @@ int get_required_prb_dl(const sched_ue_cell& cell,
uint32_t get_required_prb_ul(const sched_ue_cell& cell, uint32_t req_bytes) uint32_t get_required_prb_ul(const sched_ue_cell& cell, uint32_t req_bytes)
{ {
const static int MIN_ALLOC_BYTES = 10; /// There should be enough space for RLC header + BSR + some payload
if (req_bytes == 0) { if (req_bytes == 0) {
return 0; return 0;
} }
@ -308,11 +309,18 @@ uint32_t get_required_prb_ul(const sched_ue_cell& cell, uint32_t req_bytes)
}; };
// find nof prbs that lead to a tbs just above req_bytes // find nof prbs that lead to a tbs just above req_bytes
int target_tbs = static_cast<int>(req_bytes) + 4; int target_tbs = std::max(static_cast<int>(req_bytes) + 4, MIN_ALLOC_BYTES);
uint32_t max_prbs = std::min(cell.tpc_fsm.max_ul_prbs(), cell.cell_cfg->nof_prb()); uint32_t max_prbs = std::min(cell.tpc_fsm.max_ul_prbs(), cell.cell_cfg->nof_prb());
std::tuple<uint32_t, int, uint32_t, int> ret = std::tuple<uint32_t, int, uint32_t, int> ret =
false_position_method(1U, max_prbs, target_tbs, compute_tbs_approx, [](int y) { return y == SRSRAN_ERROR; }); false_position_method(1U, max_prbs, target_tbs, compute_tbs_approx, [](int y) { return y == SRSRAN_ERROR; });
uint32_t req_prbs = std::get<2>(ret); uint32_t req_prbs = std::get<2>(ret);
uint32_t final_tbs = std::get<3>(ret);
while (final_tbs < MIN_ALLOC_BYTES and req_prbs < cell.cell_cfg->nof_prb()) {
// Note: If PHR<0 is limiting the max nof PRBs per UL grant, the UL grant may become too small to fit any
// data other than headers + BSR. In this edge-case, force an increase the nof required PRBs.
req_prbs++;
final_tbs = compute_tbs_approx(req_prbs);
}
while (!srsran_dft_precoding_valid_prb(req_prbs) && req_prbs < cell.cell_cfg->nof_prb()) { while (!srsran_dft_precoding_valid_prb(req_prbs) && req_prbs < cell.cell_cfg->nof_prb()) {
req_prbs++; req_prbs++;
} }

@ -59,6 +59,10 @@ add_executable(sched_dci_test sched_dci_test.cc)
target_link_libraries(sched_dci_test srsran_common srsenb_mac srsran_mac sched_test_common) target_link_libraries(sched_dci_test srsran_common srsenb_mac srsran_mac sched_test_common)
add_test(sched_dci_test sched_dci_test) add_test(sched_dci_test sched_dci_test)
add_executable(sched_ue_cell_test sched_ue_cell_test.cc)
target_link_libraries(sched_ue_cell_test srsran_common srsenb_mac srsran_mac sched_test_common)
add_test(sched_ue_cell_test sched_ue_cell_test)
add_executable(sched_benchmark_test sched_benchmark.cc) add_executable(sched_benchmark_test sched_benchmark.cc)
target_link_libraries(sched_benchmark_test srsran_common srsenb_mac srsran_mac sched_test_common) target_link_libraries(sched_benchmark_test srsran_common srsenb_mac srsran_mac sched_test_common)
add_test(sched_benchmark_test sched_benchmark_test) add_test(sched_benchmark_test sched_benchmark_test)

@ -0,0 +1,75 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#include "sched_test_common.h"
#include "sched_test_utils.h"
#include "srsenb/hdr/stack/mac/sched_ue.h"
#include "srsran/common/test_common.h"
using namespace srsenb;
const uint32_t seed = std::chrono::system_clock::now().time_since_epoch().count();
/**
* Test scenario where PHR < 0, and the UL grant size is limited.
* - The UL grant size should be the smallest possible that guarantees fitting both a BSR, RLC header, and some RLC
* payload.
*/
void test_neg_phr_scenario()
{
sched_interface::cell_cfg_t cell_cfg = generate_default_cell_cfg(50);
cell_cfg.target_pucch_ul_sinr = 20;
cell_cfg.target_pusch_ul_sinr = 20;
cell_cfg.enable_phr_handling = true;
sched_interface::sched_args_t sched_cfg = {};
sched_cell_params_t cell_params;
cell_params.set_cfg(0, cell_cfg, sched_cfg);
sched_interface::ue_cfg_t ue_cfg = generate_default_ue_cfg();
sched_ue_cell ue_cc(0x46, cell_params, tti_point(0));
ue_cc.set_ue_cfg(ue_cfg);
float snr = 0;
ue_cc.tpc_fsm.set_snr(snr, 0);
ue_cc.tpc_fsm.set_snr(snr, 1);
ue_cc.ul_cqi = srsran_cqi_from_snr(snr);
ue_cc.tpc_fsm.set_phr(-5);
ue_cc.new_tti(tti_point(0));
uint32_t req_bytes = 10000;
uint32_t pending_prbs = get_required_prb_ul(ue_cc, req_bytes);
TESTASSERT(pending_prbs < 10); // The PHR<0 is limiting the number of allocated PRBs
uint32_t N_srs = 0;
uint32_t prb_grant_size = pending_prbs;
uint32_t nof_symb = 2 * (SRSRAN_CP_NSYMB(cell_cfg.cell.cp) - 1) - N_srs;
uint32_t nof_re = nof_symb * prb_grant_size * SRSRAN_NRE;
tbs_info tbinfo = cqi_to_tbs_ul(ue_cc, prb_grant_size, nof_re, req_bytes);
TESTASSERT(tbinfo.tbs_bytes >= 10);
}
int main()
{
srsenb::set_randseed(seed);
srsran::console("This is the chosen seed: %u\n", seed);
auto& test_log = srslog::fetch_basic_logger("TEST", false);
test_log.set_level(srslog::basic_levels::info);
// Start the log backend.
srslog::init();
test_neg_phr_scenario();
srslog::flush();
srsran::console("Success\n");
}
Loading…
Cancel
Save