diff --git a/srsenb/hdr/stack/mac/scheduler_grid.h b/srsenb/hdr/stack/mac/scheduler_grid.h index 4796612f8..90ba9e8b1 100644 --- a/srsenb/hdr/stack/mac/scheduler_grid.h +++ b/srsenb/hdr/stack/mac/scheduler_grid.h @@ -235,9 +235,9 @@ public: void new_tti(uint32_t tti_rx_, uint32_t start_cfi); // DL alloc - alloc_outcome_t alloc_bc(uint32_t aggr_lvl, uint32_t sib_idx, uint32_t sib_ntx); - alloc_outcome_t alloc_paging(uint32_t aggr_lvl, uint32_t paging_payload); - alloc_outcome_t alloc_rar(uint32_t aggr_lvl, const pending_rar_t& rar_grant); + alloc_outcome_t alloc_bc(uint32_t aggr_lvl, uint32_t sib_idx, uint32_t sib_ntx); + alloc_outcome_t alloc_paging(uint32_t aggr_lvl, uint32_t paging_payload); + std::pair alloc_rar(uint32_t aggr_lvl, const pending_rar_t& rar_grant); // UL alloc alloc_outcome_t alloc_msg3(const pending_msg3_t& msg3); diff --git a/srsenb/src/stack/mac/scheduler_carrier.cc b/srsenb/src/stack/mac/scheduler_carrier.cc index 03e9b4908..da2176886 100644 --- a/srsenb/src/stack/mac/scheduler_carrier.cc +++ b/srsenb/src/stack/mac/scheduler_carrier.cc @@ -173,15 +173,23 @@ void ra_sched::dl_sched(srsenb::sf_sched* tti_sched) } // Try to schedule DCI + RBGs for RAR Grant - alloc_outcome_t ret = tti_sched->alloc_rar(rar_aggr_level, rar); + std::pair ret = tti_sched->alloc_rar(rar_aggr_level, rar); - // If we can allocate, schedule Msg3 and remove from pending - if (not ret) { + if (ret.first == alloc_outcome_t::SUCCESS) { + // if all RAR grant allocations were successful + if (ret.second == rar.nof_grants) { + // Remove pending RAR + pending_rars.pop_front(); + } else if (ret.second > 0) { + // keep the RAR grants that were not scheduled, so we can schedule in next TTI + std::copy(&rar.msg3_grant[ret.second], &rar.msg3_grant[rar.nof_grants], &rar.msg3_grant[0]); + rar.nof_grants -= ret.second; + } + } else if (ret.first == alloc_outcome_t::RB_COLLISION) { + // there are not enough RBs for RAR or Msg3 allocation. We can skip this TTI return; } - - // Remove pending RAR - pending_rars.pop_front(); + // try to scheduler next RAR with different RA-RNTI } } diff --git a/srsenb/src/stack/mac/scheduler_grid.cc b/srsenb/src/stack/mac/scheduler_grid.cc index 82bf8108e..fe567c3b3 100644 --- a/srsenb/src/stack/mac/scheduler_grid.cc +++ b/srsenb/src/stack/mac/scheduler_grid.cc @@ -502,40 +502,57 @@ alloc_outcome_t sf_sched::alloc_paging(uint32_t aggr_lvl, uint32_t paging_payloa return ret.first; } -alloc_outcome_t sf_sched::alloc_rar(uint32_t aggr_lvl, const pending_rar_t& rar) +std::pair sf_sched::alloc_rar(uint32_t aggr_lvl, const pending_rar_t& rar) { - uint32_t buf_rar = 7 * rar.nof_grants + 1; // 1+6 bytes per RAR subheader+body and 1 byte for Backoff - uint32_t msg3_grant_size = 3; - uint32_t total_msg3_size = msg3_grant_size * rar.nof_grants; + const uint32_t msg3_grant_size = 3; + std::pair ret = {alloc_outcome_t::ERROR, 0}; - // check if there is enough space for Msg3 - if (last_msg3_prb + total_msg3_size > sched_params->cfg->cell.nof_prb - sched_params->cfg->nrb_pucch) { - return alloc_outcome_t::RB_COLLISION; - } + for (uint32_t nof_grants = rar.nof_grants; nof_grants > 0; nof_grants--) { + uint32_t buf_rar = 7 * nof_grants + 1; // 1+6 bytes per RAR subheader+body and 1 byte for Backoff + uint32_t total_msg3_size = msg3_grant_size * nof_grants; + uint32_t msg3_prb_attempt = last_msg3_prb; - // allocate RBs and PDCCH - sf_sched::ctrl_code_t ret = alloc_dl_ctrl(aggr_lvl, buf_rar, rar.ra_rnti); - if (not ret.first) { - log_h->warning("SCHED: Could not allocate RAR for L=%d, cause=%s\n", aggr_lvl, ret.first.to_string()); - return ret.first; - } + // check if there is enough space for Msg3, try again with a lower number of grants + if (msg3_prb_attempt + total_msg3_size > sched_params->cfg->cell.nof_prb - sched_params->cfg->nrb_pucch) { + ret.first = alloc_outcome_t::RB_COLLISION; + continue; + } - // RAR allocation successful - sched_interface::dl_sched_rar_t rar_grant = {}; - rar_grant.nof_grants = rar.nof_grants; - for (uint32_t i = 0; i < rar.nof_grants; ++i) { - rar_grant.msg3_grant[i].data = rar.msg3_grant[i]; - rar_grant.msg3_grant[i].grant.tpc_pusch = 3; - rar_grant.msg3_grant[i].grant.trunc_mcs = 0; - uint32_t rba = srslte_ra_type2_to_riv(msg3_grant_size, last_msg3_prb, sched_params->cfg->cell.nof_prb); - rar_grant.msg3_grant[i].grant.rba = rba; + // allocate RBs and PDCCH + sf_sched::ctrl_code_t ret2 = alloc_dl_ctrl(aggr_lvl, buf_rar, rar.ra_rnti); + ret.first = ret2.first.result; + ret.second = nof_grants; - last_msg3_prb += msg3_grant_size; - } + // if there was no space for the RAR, try again + if (ret.first == alloc_outcome_t::RB_COLLISION) { + continue; + } + // if any other error, return + if (ret.first != alloc_outcome_t::SUCCESS) { + log_h->warning("SCHED: Could not allocate RAR for L=%d, cause=%s\n", aggr_lvl, ret.first.to_string()); + return ret; + } - rar_allocs.emplace_back(ret.second, rar_grant); + // RAR allocation successful + sched_interface::dl_sched_rar_t rar_grant = {}; + rar_grant.nof_grants = nof_grants; + for (uint32_t i = 0; i < nof_grants; ++i) { + rar_grant.msg3_grant[i].data = rar.msg3_grant[i]; + rar_grant.msg3_grant[i].grant.tpc_pusch = 3; + rar_grant.msg3_grant[i].grant.trunc_mcs = 0; + uint32_t rba = srslte_ra_type2_to_riv(msg3_grant_size, msg3_prb_attempt, sched_params->cfg->cell.nof_prb); + rar_grant.msg3_grant[i].grant.rba = rba; + + msg3_prb_attempt += msg3_grant_size; + } - return ret.first; + rar_allocs.emplace_back(ret2.second, rar_grant); + break; + } + if (ret.first != alloc_outcome_t::SUCCESS) { + log_h->warning("SCHED: Failed to allocate RAR due to lack of RBs\n"); + } + return ret; } alloc_outcome_t sf_sched::alloc_dl_user(sched_ue* user, const rbgmask_t& user_mask, uint32_t pid)