Merge remote-tracking branch 'origin/l1-rx-use-queues' into integration_2026_w16 (!3991)
L1 RX: use queues instead of arrays and linear search for PUCCH, PUSCH, SRS, PRACH
This MR is an attempt to reduce the time L1 RX searches in array for the
next job to process, and instead use a queue. This queue is a FIFO,
because the various jobs (FAPI messages) to process come in order, and
need to be processed in order. The MR (hopefully, to be measured)
reduces the amount of time spent searching for the next UE (because the
next job is always at the beginning of the queue), and should scale
better for many UEs.
It does the following:
- introduce two helper libraries for (1) Frame.Slot calculation (sfn_t),
already introduced in !3521 (merged) commit 3102068e, and (2) a ring
buffer with fixed size
- use sfn_t and ring buffer (gNB->pucch_queue) to remove the linear
array for PUCCH (gNB->pucch)
- use sfn_t and ring buffer (gNB->pusch_queue) for some PUSCH lookups.
Because we need to still store PUSCH contexts, gNB->pusch is still
there
- use sfn_t and ring buffer (gNB->srs_queue) to remove the linear array
for SRS (gNB->srs)
- use sfn_t and ring buffers (gNB->prach_ru_queue and
gNB->prach_l1rx_queue) to remove the linear array for PRACH
(gNB->prach_list)
- some minor cleanups, e.g., additional loops over the PUSCH array,
using const, using pointers instead of indices, etc
This commit is contained in:
@@ -2528,34 +2528,6 @@ void post_process_ulsch(gNB_MAC_INST *nr_mac, post_process_pusch_t *pusch, NR_UE
|
||||
nr_mac->cset0_bwp_size);
|
||||
}
|
||||
|
||||
fsn_t fs_add_delta(const frame_structure_t *fs, uint32_t delta, fsn_t fsn)
|
||||
{
|
||||
const int slots_frame = fs->numb_slots_frame;
|
||||
fsn_t res = {
|
||||
.f = (fsn.f + (fsn.s + delta) / slots_frame) % MAX_FRAME_NUMBER,
|
||||
.s = (fsn.s + delta) % slots_frame,
|
||||
};
|
||||
return res;
|
||||
}
|
||||
int fs_get_diff(const frame_structure_t *fs, fsn_t a, fsn_t b)
|
||||
{
|
||||
const int slots_frame = fs->numb_slots_frame;
|
||||
int diff = (a.f * slots_frame + a.s) - (b.f * slots_frame + b.s);
|
||||
if (diff < -512 * slots_frame)
|
||||
diff += 1024 * slots_frame;
|
||||
else if (diff > 512 * slots_frame)
|
||||
diff -= 1024 * slots_frame;
|
||||
return diff;
|
||||
}
|
||||
fsn_t fs_get_max(const frame_structure_t *fs, fsn_t a, fsn_t b)
|
||||
{
|
||||
if (fs_get_diff(fs, a, b) <= 0) {
|
||||
return b;
|
||||
} else {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
static void nr_ulsch_preprocessor(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp_pusch)
|
||||
{
|
||||
int frame = pp_pusch->frame;
|
||||
@@ -2579,8 +2551,8 @@ static void nr_ulsch_preprocessor(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp
|
||||
// FAPI cannot handle more than MAX_DCI_CORESET DCIs
|
||||
max_dci = min(max_dci, MAX_DCI_CORESET);
|
||||
|
||||
fsn_t current = {frame, slot};
|
||||
fsn_t min_next = fs_add_delta(fs, min_rxtx, current);
|
||||
fsn_t current = {frame, slot, *scc->ssbSubcarrierSpacing};
|
||||
fsn_t min_next = fsn_add_delta(current, min_rxtx);
|
||||
/* if it's the last DL slot, we should try all TDAs to make sure that the
|
||||
* scheduler can reach e.g. the next mixed slot. Otherwise, if we don't, we
|
||||
* might starve HARQ processes that need a retransmission in a specific slot
|
||||
@@ -2589,16 +2561,16 @@ static void nr_ulsch_preprocessor(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp
|
||||
fsn_t *next = &nr_mac->ul_next;
|
||||
while (max_dci > 0) {
|
||||
/* go to the next UL slot, skipping DL if necessary */
|
||||
*next = fs_get_max(fs, *next, min_next);
|
||||
*next = fsn_get_max(*next, min_next);
|
||||
while (!is_ul_slot(next->s, fs))
|
||||
*next = fs_add_delta(fs, 1, *next);
|
||||
*next = fsn_add_delta(*next, 1);
|
||||
if (!is_dl_slot(current.s, fs)) // if current slot is not DL, nothing to do
|
||||
break;
|
||||
|
||||
/* get a TDA so that next UL scheduling slot can be reached from current,
|
||||
* and exit if there is no such TDA. Remove koffset, as it is
|
||||
* "cell-specific", i.e., the UE will add it on the computation. */
|
||||
int k2 = fs_get_diff(fs, *next, current) - koffset;
|
||||
int k2 = fsn_get_diff(*next, current) - koffset;
|
||||
DevAssert(k2 > 0);
|
||||
// we assume that all beams have the same symbol utilization in all RBs for
|
||||
// simplification (but this might not be true). Otherwise, we would need to
|
||||
@@ -2631,7 +2603,7 @@ static void nr_ulsch_preprocessor(gNB_MAC_INST *nr_mac, post_process_pusch_t *pp
|
||||
break;
|
||||
max_dci -= sched;
|
||||
|
||||
*next = fs_add_delta(fs, 1, *next);
|
||||
*next = fsn_add_delta(*next, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -293,6 +293,7 @@ void mac_top_init_gNB(ngran_node_t node_type,
|
||||
RC.nrmac[i]->cset0_bwp_start = 0;
|
||||
RC.nrmac[i]->cset0_bwp_size = 0;
|
||||
|
||||
RC.nrmac[i]->ul_next = (fsn_t) {.mu = *scc->ssbSubcarrierSpacing};
|
||||
RC.nrmac[i]->print_ue_stats = true;
|
||||
|
||||
pthread_mutex_init(&RC.nrmac[i]->sched_lock, NULL);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <string.h>
|
||||
#include <complex.h>
|
||||
#include <pthread.h>
|
||||
#include "fsn.h"
|
||||
#include "common/utils/ds/seq_arr.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
#include "common/utils/ds/byte_array.h"
|
||||
@@ -878,14 +879,6 @@ typedef struct {
|
||||
NR_ControlResourceSet_t coreset;
|
||||
} NR_sched_ctrl_sib1_t;
|
||||
|
||||
/// helper type to encapsulate a frame/slot combination in a single type.
|
||||
/// Currently only used in the UL preprocessor. Note: if you use this type
|
||||
/// further, please refactor it into a common type first.
|
||||
typedef struct fsn {
|
||||
frame_t f;
|
||||
slot_t s;
|
||||
} fsn_t;
|
||||
|
||||
typedef struct NR_du_stats {
|
||||
/// cell-wide wide-band CQI distribution, see 28.552 5.1.1.11.1;
|
||||
/// 0-15 CQI, 1-8 RI, 1-3 CQI table
|
||||
|
||||
Reference in New Issue
Block a user