update
This commit is contained in:
@@ -86,8 +86,42 @@ static meas_record_lst_t fill_DRB_PdcpSduVolumeUL(__attribute__((unused)) const
|
||||
}
|
||||
|
||||
#if defined (NGRAN_GNB_DU)
|
||||
static uldlcounter_t last_rlc_pdu_total_bytes[MAX_MOBILES_PER_GNB] = {0};
|
||||
static uldlcounter_t last_total_prbs[MAX_MOBILES_PER_GNB] = {0};
|
||||
typedef struct ue_uldlcounter {
|
||||
const NR_UE_info_t *ue;
|
||||
rnti_t rnti;
|
||||
uldlcounter_t value;
|
||||
bool dl_valid;
|
||||
bool ul_valid;
|
||||
} ue_uldlcounter_t;
|
||||
|
||||
static ue_uldlcounter_t last_rlc_pdu_total_bytes[MAX_MOBILES_PER_GNB] = {0};
|
||||
static ue_uldlcounter_t last_total_prbs[MAX_MOBILES_PER_GNB] = {0};
|
||||
|
||||
/* The connected UE list is compacted when a UE leaves, so its iteration index
|
||||
* is not a stable identity. Keep baselines by the MAC-assigned UID instead and
|
||||
* reset them when that UID is reused for another UE. */
|
||||
static ue_uldlcounter_t *get_ue_counter(ue_uldlcounter_t counters[MAX_MOBILES_PER_GNB],
|
||||
const cudu_ue_info_pair_t ue_info)
|
||||
{
|
||||
AssertFatal(ue_info.ue != NULL, "KPM UE measurement requires MAC UE information\n");
|
||||
const uid_t uid = ue_info.ue->uid;
|
||||
AssertFatal(uid < MAX_MOBILES_PER_GNB, "KPM UE UID %u exceeds maximum %u\n", uid, MAX_MOBILES_PER_GNB);
|
||||
|
||||
ue_uldlcounter_t *counter = &counters[uid];
|
||||
if (counter->ue != ue_info.ue || counter->rnti != ue_info.ue->rnti)
|
||||
*counter = (ue_uldlcounter_t){.ue = ue_info.ue, .rnti = ue_info.ue->rnti};
|
||||
return counter;
|
||||
}
|
||||
|
||||
/* A new/reused UE counter and a reset/wrap have no valid preceding sample.
|
||||
* Establish a fresh baseline and report zero for that single period. */
|
||||
static uint32_t counter_delta(uint32_t current, uint32_t *previous, bool *valid)
|
||||
{
|
||||
const uint32_t delta = *valid && current >= *previous ? current - *previous : 0;
|
||||
*previous = current;
|
||||
*valid = true;
|
||||
return delta;
|
||||
}
|
||||
|
||||
static nr_rlc_statistics_t get_rlc_stats_per_drb(const rnti_t rnti, const int rb_id)
|
||||
{
|
||||
@@ -120,8 +154,16 @@ static meas_record_lst_t fill_DRB_RlcSduDelayDl(__attribute__((unused)) const la
|
||||
|
||||
meas_record.value = REAL_MEAS_VALUE;
|
||||
|
||||
// Get the value of sojourn time at the RLC buffer
|
||||
meas_record.real_val = rlc.txsdu_avg_time_to_tx; // [μs]
|
||||
// Report the windowed-average RLC SDU sojourn (mean per-packet wait over the
|
||||
// last 100 ms), not the instantaneous tx_list HOL snapshot. The snapshot
|
||||
// (txsdu_wt_us) reads 0 whenever the tx_list is momentarily drained at the
|
||||
// single sampling instant -- common with bursty DL even at high throughput --
|
||||
// which systematically under-reports delay (era/load-dependent). The averaging
|
||||
// accumulator is now activated once (reset guarded to off->on in
|
||||
// nr_rlc_activate_avg_time_to_tx), so it accumulates continuously instead of
|
||||
// being wiped on every read; it returns 0 only when no SDU was transmitted in
|
||||
// the window (genuine idle/starvation).
|
||||
meas_record.real_val = (double)rlc.txsdu_avg_time_to_tx; // [us] avg RLC SDU sojourn
|
||||
|
||||
return meas_record;
|
||||
}
|
||||
@@ -132,7 +174,7 @@ static meas_record_lst_t fill_DRB_RlcSduDelayDl(__attribute__((unused)) const la
|
||||
static meas_record_lst_t fill_DRB_UEThpDl(__attribute__((unused)) const label_info_lst_t label,
|
||||
uint32_t gran_period_ms,
|
||||
cudu_ue_info_pair_t ue_info,
|
||||
const size_t ue_idx,
|
||||
__attribute__((unused)) const size_t ue_idx,
|
||||
__attribute__((unused))e2_node_level_stats_t* node_stats)
|
||||
{
|
||||
meas_record_lst_t meas_record = {0};
|
||||
@@ -142,8 +184,9 @@ static meas_record_lst_t fill_DRB_UEThpDl(__attribute__((unused)) const label_in
|
||||
meas_record.value = REAL_MEAS_VALUE;
|
||||
|
||||
// Calculate DL Thp
|
||||
meas_record.real_val = (double)(rlc.txpdu_bytes - last_rlc_pdu_total_bytes[ue_idx].dl)*8/gran_period_ms; // [kbps]
|
||||
last_rlc_pdu_total_bytes[ue_idx].dl = rlc.txpdu_bytes;
|
||||
ue_uldlcounter_t *counter = get_ue_counter(last_rlc_pdu_total_bytes, ue_info);
|
||||
const uint32_t bytes = counter_delta(rlc.txpdu_bytes, &counter->value.dl, &counter->dl_valid);
|
||||
meas_record.real_val = gran_period_ms == 0 ? 0 : (double)bytes * 8 / gran_period_ms; // [kbps]
|
||||
|
||||
return meas_record;
|
||||
}
|
||||
@@ -154,7 +197,7 @@ static meas_record_lst_t fill_DRB_UEThpDl(__attribute__((unused)) const label_in
|
||||
static meas_record_lst_t fill_DRB_UEThpUl(__attribute__((unused)) const label_info_lst_t label,
|
||||
uint32_t gran_period_ms,
|
||||
cudu_ue_info_pair_t ue_info,
|
||||
const size_t ue_idx,
|
||||
__attribute__((unused)) const size_t ue_idx,
|
||||
__attribute__((unused))e2_node_level_stats_t* node_stats)
|
||||
{
|
||||
meas_record_lst_t meas_record = {0};
|
||||
@@ -166,8 +209,9 @@ static meas_record_lst_t fill_DRB_UEThpUl(__attribute__((unused)) const label_in
|
||||
meas_record.value = REAL_MEAS_VALUE;
|
||||
|
||||
// Calculate UL Thp
|
||||
meas_record.real_val = (double)(rlc.rxpdu_bytes - last_rlc_pdu_total_bytes[ue_idx].ul)*8/gran_period_ms; // [kbps]
|
||||
last_rlc_pdu_total_bytes[ue_idx].ul = rlc.rxpdu_bytes;
|
||||
ue_uldlcounter_t *counter = get_ue_counter(last_rlc_pdu_total_bytes, ue_info);
|
||||
const uint32_t bytes = counter_delta(rlc.rxpdu_bytes, &counter->value.ul, &counter->ul_valid);
|
||||
meas_record.real_val = gran_period_ms == 0 ? 0 : (double)bytes * 8 / gran_period_ms; // [kbps]
|
||||
|
||||
return meas_record;
|
||||
}
|
||||
@@ -177,7 +221,7 @@ static meas_record_lst_t fill_DRB_UEThpUl(__attribute__((unused)) const label_in
|
||||
static meas_record_lst_t fill_RRU_PrbTotDl(__attribute__((unused)) const label_info_lst_t label,
|
||||
__attribute__((unused)) uint32_t gran_period_ms,
|
||||
cudu_ue_info_pair_t ue_info,
|
||||
const size_t ue_idx,
|
||||
__attribute__((unused)) const size_t ue_idx,
|
||||
e2_node_level_stats_t* node_stats)
|
||||
{
|
||||
meas_record_lst_t meas_record = {0};
|
||||
@@ -185,8 +229,13 @@ static meas_record_lst_t fill_RRU_PrbTotDl(__attribute__((unused)) const label_i
|
||||
meas_record.value = INTEGER_MEAS_VALUE;
|
||||
|
||||
// Get the number of DL PRBs
|
||||
meas_record.int_val = (ue_info.ue->mac_stats.dl.total_rbs - last_total_prbs[ue_idx].dl) * 100 / (node_stats[1].mac_stats.dl.total_prb_aggregate - node_stats[0].mac_stats.dl.total_prb_aggregate); // [%]
|
||||
last_total_prbs[ue_idx].dl = ue_info.ue->mac_stats.dl.total_rbs;
|
||||
ue_uldlcounter_t *counter = get_ue_counter(last_total_prbs, ue_info);
|
||||
const uint32_t ue_delta = counter_delta(ue_info.ue->mac_stats.dl.total_rbs, &counter->value.dl, &counter->dl_valid);
|
||||
const uint64_t current = node_stats[1].mac_stats.dl.total_prb_aggregate;
|
||||
const uint64_t previous = node_stats[0].mac_stats.dl.total_prb_aggregate;
|
||||
const uint64_t total_delta = current >= previous ? current - previous : 0;
|
||||
const uint64_t percentage = total_delta == 0 ? 0 : (uint64_t)ue_delta * 100 / total_delta;
|
||||
meas_record.int_val = percentage > 100 ? 100 : percentage; // [%]
|
||||
|
||||
return meas_record;
|
||||
}
|
||||
@@ -196,7 +245,7 @@ static meas_record_lst_t fill_RRU_PrbTotDl(__attribute__((unused)) const label_i
|
||||
static meas_record_lst_t fill_RRU_PrbTotUl(__attribute__((unused)) const label_info_lst_t label,
|
||||
__attribute__((unused)) uint32_t gran_period_ms,
|
||||
cudu_ue_info_pair_t ue_info,
|
||||
const size_t ue_idx,
|
||||
__attribute__((unused)) const size_t ue_idx,
|
||||
e2_node_level_stats_t* node_stats)
|
||||
{
|
||||
meas_record_lst_t meas_record = {0};
|
||||
@@ -204,8 +253,13 @@ static meas_record_lst_t fill_RRU_PrbTotUl(__attribute__((unused)) const label_i
|
||||
meas_record.value = INTEGER_MEAS_VALUE;
|
||||
|
||||
// Get the number of UL PRBs
|
||||
meas_record.int_val = (ue_info.ue->mac_stats.ul.total_rbs - last_total_prbs[ue_idx].ul) * 100 / (node_stats[1].mac_stats.ul.total_prb_aggregate - node_stats[0].mac_stats.ul.total_prb_aggregate); // [%]
|
||||
last_total_prbs[ue_idx].ul = ue_info.ue->mac_stats.ul.total_rbs;
|
||||
ue_uldlcounter_t *counter = get_ue_counter(last_total_prbs, ue_info);
|
||||
const uint32_t ue_delta = counter_delta(ue_info.ue->mac_stats.ul.total_rbs, &counter->value.ul, &counter->ul_valid);
|
||||
const uint64_t current = node_stats[1].mac_stats.ul.total_prb_aggregate;
|
||||
const uint64_t previous = node_stats[0].mac_stats.ul.total_prb_aggregate;
|
||||
const uint64_t total_delta = current >= previous ? current - previous : 0;
|
||||
const uint64_t percentage = total_delta == 0 ? 0 : (uint64_t)ue_delta * 100 / total_delta;
|
||||
meas_record.int_val = percentage > 100 ? 100 : percentage; // [%]
|
||||
|
||||
return meas_record;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user