Merge remote-tracking branch 'origin/fixes-ul-sched' into integration_2025_w37 (!3635)
Fixes and updates for UL scheduling, notably DSUUU Fix a number of problems that stem from !3521, notably regarding Msg3 scheduling, retransmissions in "UL-heavy" TDD scenarios, and BSR handling. Modify a CI test to run a UL-heavy TDD scenario, and add documentation for UL-heavy TDD scenarios.
This commit is contained in:
@@ -197,7 +197,6 @@ MACRLCs = (
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 200; # 150;
|
||||
pucch_TargetSNRx10 = 200; #200;
|
||||
ulsch_max_frame_inactivity = 10;
|
||||
dl_max_mcs = 28;
|
||||
ul_max_mcs = 28;
|
||||
}
|
||||
|
||||
@@ -198,7 +198,6 @@ MACRLCs = (
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
# ulsch_max_frame_inactivity = 0;
|
||||
pusch_TargetSNRx10 = 150;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
dl_max_mcs = 9;
|
||||
|
||||
@@ -206,7 +206,6 @@ MACRLCs = (
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
# ulsch_max_frame_inactivity = 0;
|
||||
pusch_TargetSNRx10 = 150;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
dl_max_mcs = 9;
|
||||
|
||||
@@ -24,6 +24,7 @@ gNBs =
|
||||
pusch_AntennaPorts = 2;
|
||||
do_CSIRS = 1;
|
||||
do_SRS = 1;
|
||||
uess_agg_levels = [4,2,0,0,0];
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
@@ -139,9 +140,9 @@ gNBs =
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 5;
|
||||
nrofDownlinkSlots = 2;
|
||||
nrofDownlinkSlots = 1;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSlots = 3;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = -20;
|
||||
@@ -178,11 +179,12 @@ MACRLCs = (
|
||||
num_cc = 1;
|
||||
tr_s_preference = "local_L1";
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 300;
|
||||
pucch_TargetSNRx10 = 300;
|
||||
ulsch_max_frame_inactivity = 0;
|
||||
pusch_TargetSNRx10 = 320;
|
||||
pucch_TargetSNRx10 = 320;
|
||||
pusch_FailureThres = 100;
|
||||
ul_max_mcs = 28;
|
||||
ul_max_mcs = 28;
|
||||
ul_bler_target_upper = 0.20;
|
||||
ul_bler_target_lower = 0.10;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -175,7 +175,6 @@ MACRLCs = (
|
||||
pusch_TargetSNRx10 = 270;
|
||||
pucch_TargetSNRx10 = 270;
|
||||
pusch_FailureThres = 1000;
|
||||
ulsch_max_frame_inactivity = 0;
|
||||
ul_max_mcs = 25;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -233,7 +233,6 @@ MACRLCs = (
|
||||
tr_n_preference = "local_RRC";
|
||||
pusch_TargetSNRx10 = 250;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
ulsch_max_frame_inactivity = 0;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
-->
|
||||
<testCaseList>
|
||||
<htmlTabRef>TEST-SA-FR1-N310-2x2-60MHz</htmlTabRef>
|
||||
<htmlTabName>60 MHz 2x2 TDD SA</htmlTabName>
|
||||
<htmlTabName>60 MHz 2x2 TDD SA DSUUU</htmlTabName>
|
||||
<htmlTabIcon>tasks</htmlTabIcon>
|
||||
<TestCaseRequestedList>
|
||||
100000
|
||||
@@ -114,8 +114,8 @@
|
||||
|
||||
<testCase id="071000">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/200Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 200M -t 30 -R</iperf_args>
|
||||
<desc>iperf (DL/150Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 150M -t 30 -R</iperf_args>
|
||||
<svr_id>matix-cn5g</svr_id>
|
||||
<id>up2</id>
|
||||
<iperf_packetloss_threshold>25</iperf_packetloss_threshold>
|
||||
@@ -124,8 +124,8 @@
|
||||
|
||||
<testCase id="071001">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (UL/180Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 180M -t 30</iperf_args>
|
||||
<desc>iperf (UL/250Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 250M -t 30</iperf_args>
|
||||
<svr_id>matix-cn5g</svr_id>
|
||||
<id>up2</id>
|
||||
<iperf_packetloss_threshold>10</iperf_packetloss_threshold>
|
||||
@@ -147,8 +147,8 @@
|
||||
<node>matix</node>
|
||||
<yaml_path>ci-scripts/yaml_files/5g_sa_n310_2x2_60MHz</yaml_path>
|
||||
<services>oai-gnb</services>
|
||||
<d_retx_th>10,100,100,100</d_retx_th>
|
||||
<u_retx_th>10,100,100,100</u_retx_th>
|
||||
<d_retx_th>15,100,100,100</d_retx_th>
|
||||
<u_retx_th>20,100,100,100</u_retx_th>
|
||||
</testCase>
|
||||
|
||||
<testCase id="333333">
|
||||
|
||||
+12
-2
@@ -38,7 +38,7 @@ The actual scheduler implementation can be found in functions `pf_dl()` and
|
||||
[`gNB_scheduler_ulsch.c`](../../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c)
|
||||
(for UL), respectively.
|
||||
|
||||
## PDDCH aggregation level
|
||||
## PDCCH aggregation level
|
||||
|
||||
PDCCH aggregation level is selected using closed loop controller, where DL HARQ
|
||||
feedback is the controller feedback signal. It is used to increment `pdcch_cl_adjust`
|
||||
@@ -60,7 +60,7 @@ in aggregation level 2 which translates to `uess_agg_levels` set to `[0, 2, 0,
|
||||
Say we have 90% PDCCH success rate at aggregation level 1, `pdcch_cl_adjust` will stay at 0
|
||||
for most of the time. 2 consecutive PDCCH failures will not result in increasing the aggregation
|
||||
level (because (0.05 + 0.05) * 4 = 0.4 which is closer to 0 than to 1). If PDCCH fails 3 times
|
||||
in a row the aggregation level will change to 2 and hopefully back to 1 once more PDDCH successes
|
||||
in a row the aggregation level will change to 2 and hopefully back to 1 once more PDCCH successes
|
||||
happen.
|
||||
|
||||
### Example 2
|
||||
@@ -404,3 +404,13 @@ pattern2: {
|
||||
nrofUplinkSymbols2 = 0;
|
||||
};
|
||||
```
|
||||
|
||||
#### UL-heavy TDD patterns
|
||||
|
||||
"UL-heavy TDD patterns", i.e., TDD patterns that have many UL slots are
|
||||
supported. Examples for such patterns would be DSUUU or DDDSUUUUUU.
|
||||
|
||||
Note that you should increase the aggregation level candidates as described in
|
||||
[the corresponding section above](#pdcch-aggregation-level). This is because the
|
||||
scheduler has to schedule multiple DCIs in a single DL slots for multiple UL
|
||||
slots. As a suggestion, you could try `uess_agg_levels = [4, 2, 2, 0, 0]`.
|
||||
|
||||
@@ -138,6 +138,10 @@ static uint8_t set_tdd_bmap_period(const NR_TDD_UL_DL_Pattern_t *pattern, tdd_pe
|
||||
n_ul_slot,
|
||||
n_dl_symbols,
|
||||
n_ul_symbols);
|
||||
AssertFatal(n_dl_symbols + n_ul_symbols < 14,
|
||||
"number of mixed slot symbols must be smaller than 14: DL %d, UL %d\n",
|
||||
n_dl_symbols,
|
||||
n_ul_symbols);
|
||||
|
||||
return total_slot;
|
||||
}
|
||||
@@ -174,6 +178,11 @@ static void config_tdd_patterns(const NR_TDD_UL_DL_ConfigCommon_t *tdd, frame_st
|
||||
num_of_patterns,
|
||||
nb_slots_p1,
|
||||
nb_slots_p2);
|
||||
AssertFatal(nb_slots_p1 + nb_slots_p2 == fs->numb_slots_period,
|
||||
"total number of slots must equal to %d: p1 %d + p2 %d\n",
|
||||
fs->numb_slots_period,
|
||||
nb_slots_p1,
|
||||
nb_slots_p2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -595,6 +595,7 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
/* Extract short BSR value */
|
||||
ce_ptr = &pduP[mac_subheader_len];
|
||||
sched_ctrl->estimated_ul_buffer = estimate_ul_buffer_short_bsr((NR_BSR_SHORT *)ce_ptr);
|
||||
sched_ctrl->sched_ul_bytes = 0;
|
||||
LOG_D(NR_MAC, "SHORT BSR at %4d.%2d, est buf %d\n", frameP, slot, sched_ctrl->estimated_ul_buffer);
|
||||
break;
|
||||
|
||||
@@ -603,6 +604,7 @@ static int nr_process_mac_pdu(instance_t module_idP,
|
||||
/* Extract long BSR value */
|
||||
ce_ptr = &pduP[mac_subheader_len];
|
||||
sched_ctrl->estimated_ul_buffer = estimate_ul_buffer_long_bsr((NR_BSR_LONG *)ce_ptr);
|
||||
sched_ctrl->sched_ul_bytes = 0;
|
||||
LOG_D(NR_MAC, "LONG BSR at %4d.%2d, estim buf %d\n", frameP, slot, sched_ctrl->estimated_ul_buffer);
|
||||
break;
|
||||
|
||||
@@ -1805,7 +1807,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
||||
new_sched.bwp_info = bwp_info;
|
||||
DevAssert(new_sched.ul_harq_pid == harq_pid);
|
||||
|
||||
bool reuse_old_tda = (retInfo->tda_info.startSymbolIndex == tda_info->startSymbolIndex) && (retInfo->tda_info.nrOfSymbols <= tda_info->nrOfSymbols);
|
||||
bool reuse_old_tda = retInfo->time_domain_allocation == tda;
|
||||
if (reuse_old_tda && nrOfLayers == retInfo->nrOfLayers) {
|
||||
/* Check the resource is enough for retransmission */
|
||||
const uint16_t slbitmap = SL_to_bitmap(retInfo->tda_info.startSymbolIndex, retInfo->tda_info.nrOfSymbols);
|
||||
@@ -1887,6 +1889,7 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac,
|
||||
fill_pdcch_vrb_map(nrmac, CC_id, &sched_ctrl->sched_pdcch, CCEIndex, sched_ctrl->aggregation_level, dci_beam_idx);
|
||||
|
||||
// signal new allocation
|
||||
DevAssert(new_sched.time_domain_allocation == tda);
|
||||
post_process_ulsch(nrmac, pp_pusch, UE, &new_sched);
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d Allocate UL retransmission RNTI %04x sched %4d.%2d (%d RBs)\n",
|
||||
@@ -2424,16 +2427,11 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE
|
||||
/* Statistics */
|
||||
AssertFatal(cur_harq->round < nr_mac->ul_bler.harq_round_max, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round);
|
||||
UE->mac_stats.ul.rounds[cur_harq->round]++;
|
||||
/* Save information on MCS, TBS etc for the current initial transmission
|
||||
* so we have access to it when retransmitting */
|
||||
cur_harq->sched_pusch = *sched_pusch;
|
||||
if (cur_harq->round == 0) {
|
||||
UE->mac_stats.ulsch_total_bytes_scheduled += sched_pusch->tb_size;
|
||||
/* Save information on MCS, TBS etc for the current initial transmission
|
||||
* so we have access to it when retransmitting */
|
||||
cur_harq->sched_pusch = *sched_pusch;
|
||||
/* save which time allocation and nrOfLayers have been used, to be used on
|
||||
* retransmissions */
|
||||
cur_harq->sched_pusch.time_domain_allocation = sched_pusch->time_domain_allocation;
|
||||
cur_harq->sched_pusch.nrOfLayers = sched_pusch->nrOfLayers;
|
||||
cur_harq->sched_pusch.tpmi = sched_pusch->tpmi;
|
||||
sched_ctrl->sched_ul_bytes += sched_pusch->tb_size;
|
||||
UE->mac_stats.ul.total_rbs += sched_pusch->rbSize;
|
||||
|
||||
|
||||
@@ -1123,20 +1123,22 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay, i
|
||||
|
||||
// make TDA for the mixed slot
|
||||
long mixed_sliv = get_SLIV(NR_NUMBER_OF_SYMBOLS_PER_SLOT - ul_symb, ul_symb - 1);
|
||||
if (ul_symb > 1 && (k2 <= N_dl1 || (p2 && N_ul2 == 0))) {
|
||||
int mixed_min_ul_symb = 3; // need at least two symbols PUSCH + PUCCH
|
||||
bool has_ul_mixed = ul_symb >= mixed_min_ul_symb;
|
||||
if (has_ul_mixed && (k2 <= N_dl1 || (p2 && N_ul2 == 0))) {
|
||||
// UL TDA index 2 for mixed slot (TDD) (no pattern 2 and enough DL slots, or pattern2 only DL)
|
||||
tda = set_TimeDomainResourceAllocation(k2, mixed_sliv); // to be reached from suitable DL slot
|
||||
asn1cSeqAdd(&tda_list->list, tda);
|
||||
} else if (ul_symb > 1 && !p2 && k2 > N_dl1) { // k2 > N_Dl1
|
||||
} else if (has_ul_mixed && !p2 && k2 > N_dl1) { // k2 > N_Dl1
|
||||
// UL TDA for mixed slot without pattern 2 and less DL slots than k2
|
||||
tda = set_TimeDomainResourceAllocation(nb_slots_per_period, mixed_sliv); // to be reached from last DL (mixed) slot, if any
|
||||
asn1cSeqAdd(&tda_list->list, tda);
|
||||
} else if (ul_symb > 1 && N_ul2 > 0 && k2 > N_dl1) {
|
||||
} else if (has_ul_mixed && N_ul2 > 0 && k2 > N_dl1) {
|
||||
// we have pattern 2 with UL, and less p1 DL slots than k2
|
||||
tda = set_TimeDomainResourceAllocation(N_dl1 + N_ul2 + 1, mixed_sliv);
|
||||
asn1cSeqAdd(&tda_list->list, tda);
|
||||
} else {
|
||||
AssertFatal(ul_symb == 0, "unhandled case of mixed slot: N_dl1 %d N_ul1 %d N_dl2 %d N_ul2 %d\n", N_dl1, N_ul1, N_dl2, N_ul2);
|
||||
LOG_I(NR_RRC, "mixed slot has %d UL symbols, cannot create mixed slot TDA\n", ul_symb);
|
||||
}
|
||||
|
||||
// make TDA for UL slots that are not reachable within k2/min_rxtxtime
|
||||
@@ -1149,11 +1151,27 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay, i
|
||||
tda = set_TimeDomainResourceAllocation(i, get_SLIV(0, 13));
|
||||
asn1cSeqAdd(&tda_list->list, tda);
|
||||
if (do_SRS) {
|
||||
tda = set_TimeDomainResourceAllocation(k2, get_SLIV(0, 12));
|
||||
tda = set_TimeDomainResourceAllocation(i, get_SLIV(0, 12));
|
||||
asn1cSeqAdd(&tda_list->list, tda);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for Msg3, an additional get_delta_for_k2(mu) is added to k2.
|
||||
// check that any UL slot is reachable under this condition
|
||||
// the below is designed to only hit specific (known) cases
|
||||
// examples: DDDSU (no TDA in S),
|
||||
int N_dl = max(N_dl1, N_dl2);
|
||||
int delta = get_delta_for_k2(mu);
|
||||
int k2_msg3 = k2 + delta;
|
||||
if (nb_slots_per_period % k2_msg3 == 0 /* see example above */
|
||||
&& k2_msg3 > N_dl /* otherwise, can always have a D that reaches U */
|
||||
&& k2_msg3 > N_ul /* otherwise, can always have a D that reaches U */
|
||||
&& !has_ul_mixed /* if mixed slot, even for DDDSU would reach */) {
|
||||
/* reach next UL from mixed slot in previous period */
|
||||
tda = set_TimeDomainResourceAllocation(k2_msg3, get_SLIV(0, 13));
|
||||
asn1cSeqAdd(&tda_list->list, tda);
|
||||
}
|
||||
}
|
||||
|
||||
AssertFatal(tda_list->list.count <= 16, "cannot reach all UL slots with current TDD configuration\n");
|
||||
@@ -2988,7 +3006,7 @@ static NR_MAC_CellGroupConfig_t *configure_mac_cellgroup(const nr_mac_timers_t *
|
||||
NR_MAC_CellGroupConfig_t * mac_CellGroupConfig = calloc(1, sizeof(*mac_CellGroupConfig));
|
||||
AssertFatal(mac_CellGroupConfig != NULL, "Couldn't allocate mac-CellGroupConfig. Out of memory!\n");
|
||||
mac_CellGroupConfig->bsr_Config = calloc(1, sizeof(*mac_CellGroupConfig->bsr_Config));
|
||||
mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10;
|
||||
mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf5;
|
||||
mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf80;
|
||||
mac_CellGroupConfig->tag_Config = calloc(1, sizeof(*mac_CellGroupConfig->tag_Config));
|
||||
mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL;
|
||||
|
||||
Reference in New Issue
Block a user