|
9 | 9 | */ |
10 | 10 |
|
11 | 11 | #include "cell_harq_manager.h" |
| 12 | +#include "../cell/resource_grid_util.h" |
12 | 13 | #include "srsran/scheduler/scheduler_slot_handler.h" |
13 | 14 |
|
14 | 15 | using namespace srsran; |
@@ -46,21 +47,41 @@ cell_harq_repository<IsDl>::cell_harq_repository(unsigned max_ues, |
46 | 47 | ues[i].harqs.reserve(MAX_NOF_HARQS); |
47 | 48 | } |
48 | 49 |
|
49 | | - const unsigned RING_SIZE = 320; // TODO: use function to define this value. It must account the timeout arg and k |
50 | | - // values |
51 | | - harq_timeout_wheel.resize(RING_SIZE); |
| 50 | + harq_timeout_wheel.resize(get_allocator_ring_size_gt_min(max_ack_wait_timeout + get_max_slot_ul_alloc_delay(0))); |
52 | 51 | } |
53 | 52 |
|
54 | 53 | template <bool IsDl> |
55 | 54 | void cell_harq_repository<IsDl>::slot_indication(slot_point sl_tx) |
56 | 55 | { |
| 56 | + last_sl_ind = sl_tx; |
| 57 | + |
57 | 58 | // Handle HARQs that timed out. |
58 | 59 | auto& harqs_timing_out = harq_timeout_wheel[sl_tx.to_uint() % harq_timeout_wheel.size()]; |
59 | 60 | while (not harqs_timing_out.empty()) { |
60 | 61 | handle_harq_ack_timeout(harqs_timing_out.front(), sl_tx); |
61 | 62 | } |
62 | 63 |
|
63 | | - last_sl_ind = sl_tx; |
| 64 | + // Handle HARQs with pending reTx that are trapped (never scheduled). This is a safety mechanism to account for a |
| 65 | + // potential bug or limitation in the scheduler policy that is leaving HARQ processes with pending reTxs for too long. |
| 66 | + // Note: we assume that the list is ordered based on when they were last ACKed. |
| 67 | + while (not harq_pending_retx_list.empty()) { |
| 68 | + auto& h = harq_pending_retx_list.front(); |
| 69 | + srsran_sanity_check(h.status == harq_state_t::pending_retx, "HARQ process in wrong state"); |
| 70 | + // [Implementation-defined] Maximum time we give to the scheduler policy to retransmit a HARQ process. |
| 71 | + const unsigned max_nof_slots_for_retx = last_sl_ind.nof_slots_per_system_frame() / 4; |
| 72 | + if (last_sl_ind < (h.slot_ack + max_nof_slots_for_retx)) { |
| 73 | + break; |
| 74 | + } |
| 75 | + |
| 76 | + // HARQ is trapped. Remove it. |
| 77 | + logger.warning( |
| 78 | + "rnti={} h_id={}: Discarding {} HARQ. Cause: Too much time has passed since the last HARQ " |
| 79 | + "transmission. The scheduler policy is likely not prioritizing retransmissions of old HARQ processes.", |
| 80 | + h.rnti, |
| 81 | + h.h_id, |
| 82 | + IsDl ? "DL" : "UL"); |
| 83 | + dealloc_harq(h); |
| 84 | + } |
64 | 85 | } |
65 | 86 |
|
66 | 87 | template <bool IsDl> |
@@ -306,6 +327,15 @@ unsigned cell_harq_repository<IsDl>::find_ue_harq_in_state(du_ue_index_t ue_idx, |
306 | 327 | template struct harq_utils::cell_harq_repository<true>; |
307 | 328 | template struct harq_utils::cell_harq_repository<false>; |
308 | 329 |
|
| 330 | +template <bool IsDl> |
| 331 | +void harq_utils::base_harq_process_handle<IsDl>::cancel_retxs() |
| 332 | +{ |
| 333 | + harq_repo->cancel_retxs(fetch_impl()); |
| 334 | +} |
| 335 | + |
| 336 | +template class harq_utils::base_harq_process_handle<true>; |
| 337 | +template class harq_utils::base_harq_process_handle<false>; |
| 338 | + |
309 | 339 | // Cell HARQ manager. |
310 | 340 |
|
311 | 341 | cell_harq_manager::cell_harq_manager(unsigned max_ues, |
@@ -453,11 +483,6 @@ void dl_harq_process_handle::increment_pucch_counter() |
453 | 483 | ++fetch_impl().pucch_ack_to_receive; |
454 | 484 | } |
455 | 485 |
|
456 | | -void dl_harq_process_handle::cancel_retxs() |
457 | | -{ |
458 | | - harq_repo->cancel_retxs(fetch_impl()); |
459 | | -} |
460 | | - |
461 | 486 | void dl_harq_process_handle::save_grant_params(const dl_harq_sched_context& ctx, const pdsch_information& pdsch) |
462 | 487 | { |
463 | 488 | srsran_assert(pdsch.codewords.size() == 1, "Only one codeword supported"); |
@@ -511,11 +536,6 @@ int ul_harq_process_handle::ul_crc_info(bool ack) |
511 | 536 | return ack ? (int)h.prev_tx_params.tbs_bytes : 0; |
512 | 537 | } |
513 | 538 |
|
514 | | -void ul_harq_process_handle::cancel_retxs() |
515 | | -{ |
516 | | - harq_repo->cancel_retxs(fetch_impl()); |
517 | | -} |
518 | | - |
519 | 539 | void ul_harq_process_handle::save_grant_params(const ul_harq_sched_context& ctx, const pusch_information& pusch) |
520 | 540 | { |
521 | 541 | ul_harq_process_impl& impl = fetch_impl(); |
|
0 commit comments