rlc: extend RLC metrics

extend RLC metrics to count Rx/Tx PDUs/SDUs bytes/#
master
Andre Puschmann 5 years ago
parent 48db31c5cf
commit df50dd7d3c

@ -118,6 +118,8 @@ private:
void update_bsr_mch(uint32_t lcid);
};
void rlc_bearer_metrics_print(const rlc_bearer_metrics_t& metrics);
} // namespace srslte
#endif // SRSLTE_RLC_H

@ -23,19 +23,24 @@
#define SRSLTE_RLC_METRICS_H
#include "srslte/common/common.h"
#include <iostream>
namespace srslte {
typedef struct {
// SDU metrics
uint32_t num_tx_sdus;
uint32_t num_rx_sdus;
uint64_t num_tx_sdu_bytes;
uint64_t num_rx_sdu_bytes;
uint32_t num_lost_sdus; //< Count dropped SDUs at Tx due to bearer inactivity or empty buffer
// PDU metrics
uint32_t num_tx_pdus;
uint32_t num_rx_pdus;
uint64_t num_tx_bytes;
uint64_t num_rx_bytes;
uint64_t num_tx_pdu_bytes;
uint64_t num_rx_pdu_bytes;
uint32_t num_lost_pdus; //< Lost PDUs registered at Rx
uint32_t num_dropped_sdus; //< Count dropped SDUs at Tx due to bearer inactivity or empty buffer
} rlc_bearer_metrics_t;
typedef struct {

@ -113,8 +113,8 @@ void rlc::get_metrics(rlc_metrics_t& m)
rlc_bearer_metrics_t metrics = it->second->get_metrics();
rlc_log->info("LCID=%d, RX throughput: %4.6f Mbps. TX throughput: %4.6f Mbps.\n",
it->first,
(metrics.num_rx_bytes * 8 / static_cast<double>(1e6)) / secs,
(metrics.num_tx_bytes * 8 / static_cast<double>(1e6)) / secs);
(metrics.num_rx_pdu_bytes * 8 / static_cast<double>(1e6)) / secs,
(metrics.num_tx_pdu_bytes * 8 / static_cast<double>(1e6)) / secs);
m.bearer[it->first] = metrics;
}
@ -123,7 +123,7 @@ void rlc::get_metrics(rlc_metrics_t& m)
rlc_bearer_metrics_t metrics = it->second->get_metrics();
rlc_log->info("MCH_LCID=%d, RX throughput: %4.6f Mbps\n",
it->first,
(metrics.num_rx_bytes * 8 / static_cast<double>(1e6)) / secs);
(metrics.num_rx_pdu_bytes * 8 / static_cast<double>(1e6)) / secs);
m.bearer[it->first] = metrics;
}
@ -607,4 +607,18 @@ void rlc::update_bsr_mch(uint32_t lcid)
}
}
void rlc_bearer_metrics_print(const rlc_bearer_metrics_t& metrics)
{
std::cout << "num_tx_sdus=" << metrics.num_tx_sdus << "\n";
std::cout << "num_rx_sdus=" << metrics.num_rx_sdus << "\n";
std::cout << "num_tx_sdu_bytes=" << metrics.num_tx_sdu_bytes << "\n";
std::cout << "num_rx_sdu_bytes=" << metrics.num_rx_sdu_bytes << "\n";
std::cout << "num_tx_pdus=" << metrics.num_tx_pdus << "\n";
std::cout << "num_rx_pdus=" << metrics.num_rx_pdus << "\n";
std::cout << "num_tx_pdu_bytes=" << metrics.num_tx_pdu_bytes << "\n";
std::cout << "num_rx_pdu_bytes=" << metrics.num_rx_pdu_bytes << "\n";
std::cout << "num_lost_pdus=" << metrics.num_lost_pdus << "\n";
std::cout << "num_lost_sdus=" << metrics.num_lost_sdus << "\n";
}
} // namespace srslte

@ -137,6 +137,7 @@ void rlc_am_lte::write_sdu(unique_byte_buffer_t sdu, bool blocking)
void rlc_am_lte::discard_sdu(uint32_t discard_sn)
{
tx.discard_sdu(discard_sn);
metrics.num_lost_sdus++;
}
/****************************************************************************
@ -155,12 +156,17 @@ uint32_t rlc_am_lte::get_buffer_state()
int rlc_am_lte::read_pdu(uint8_t* payload, uint32_t nof_bytes)
{
return tx.read_pdu(payload, nof_bytes);
int read_bytes = tx.read_pdu(payload, nof_bytes);
metrics.num_tx_pdus++;
metrics.num_tx_pdu_bytes += read_bytes;
return read_bytes;
}
void rlc_am_lte::write_pdu(uint8_t* payload, uint32_t nof_bytes)
{
rx.write_pdu(payload, nof_bytes);
metrics.num_rx_pdus++;
metrics.num_rx_pdu_bytes += nof_bytes;
}
/****************************************************************************
@ -1470,6 +1476,7 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus()
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", RB_NAME, rx_sdu->N_bytes);
rx_sdu->set_timestamp();
parent->pdcp->write_pdu(parent->lcid, std::move(rx_sdu));
parent->metrics.num_rx_sdus++;
rx_sdu = allocate_unique_buffer(*pool, true);
if (rx_sdu == nullptr) {
@ -1513,6 +1520,8 @@ void rlc_am_lte::rlc_am_lte_rx::reassemble_rx_sdus()
log->info_hex(rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU (%d B)", RB_NAME, rx_sdu->N_bytes);
rx_sdu->set_timestamp();
parent->pdcp->write_pdu(parent->lcid, std::move(rx_sdu));
parent->metrics.num_rx_sdus++;
rx_sdu = allocate_unique_buffer(*pool, true);
if (rx_sdu == NULL) {
#ifdef RLC_AM_BUFFER_DEBUG

@ -173,7 +173,7 @@ int rlc_tm::read_pdu(uint8_t* payload, uint32_t nof_bytes)
ul_queue.size(),
ul_queue.size_bytes());
metrics.num_tx_bytes += pdu_size;
metrics.num_tx_pdu_bytes += pdu_size;
return pdu_size;
} else {
log->warning("Queue empty while trying to read\n");
@ -192,7 +192,8 @@ void rlc_tm::write_pdu(uint8_t* payload, uint32_t nof_bytes)
memcpy(buf->msg, payload, nof_bytes);
buf->N_bytes = nof_bytes;
buf->set_timestamp();
metrics.num_rx_bytes += nof_bytes;
metrics.num_rx_pdu_bytes += nof_bytes;
metrics.num_rx_pdus++;
if (rrc->get_rb_name(lcid) == "SRB0") {
rrc->write_pdu(lcid, std::move(buf));
} else {

@ -95,15 +95,18 @@ void rlc_um_base::write_sdu(unique_byte_buffer_t sdu, bool blocking)
{
if (not tx_enabled || not tx) {
log->debug("%s is currently deactivated. Dropping SDU (%d B)\n", rb_name.c_str(), sdu->N_bytes);
metrics.num_dropped_sdus++;
metrics.num_lost_sdus++;
return;
}
if (blocking) {
metrics.num_tx_sdus++;
metrics.num_tx_sdu_bytes += sdu->N_bytes;
tx->write_sdu(std::move(sdu));
} else {
if (tx->try_write_sdu(std::move(sdu)) != SRSLTE_SUCCESS) {
metrics.num_dropped_sdus++;
metrics.num_lost_sdus++;
}
}
}
@ -112,10 +115,10 @@ void rlc_um_base::discard_sdu(uint32_t discard_sn)
{
if (not tx_enabled || not tx) {
log->debug("%s is currently deactivated. Ignoring SDU discard (SN %u)\n", rb_name.c_str(), discard_sn);
metrics.num_dropped_sdus++;
return;
}
tx->discard_sdu(discard_sn);
metrics.num_lost_sdus++;
}
/****************************************************************************
* MAC interface
@ -142,7 +145,7 @@ int rlc_um_base::read_pdu(uint8_t* payload, uint32_t nof_bytes)
if (tx && tx_enabled) {
uint32_t len = tx->build_data_pdu(payload, nof_bytes);
if (len > 0) {
metrics.num_tx_bytes += len;
metrics.num_tx_pdu_bytes += len;
metrics.num_tx_pdus++;
}
return len;
@ -154,7 +157,7 @@ void rlc_um_base::write_pdu(uint8_t* payload, uint32_t nof_bytes)
{
if (rx && rx_enabled) {
metrics.num_rx_pdus++;
metrics.num_rx_bytes += nof_bytes;
metrics.num_rx_pdu_bytes += nof_bytes;
rx->handle_data_pdu(payload, nof_bytes);
}
}

@ -402,6 +402,8 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus()
vr_ur,
i);
rx_sdu->set_timestamp();
metrics.num_rx_sdus++;
metrics.num_rx_sdu_bytes += rx_sdu->N_bytes;
if (cfg.um.is_mrb) {
pdcp->write_pdu_mch(lcid, std::move(rx_sdu));
} else {
@ -435,6 +437,8 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus()
log->info_hex(
rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (lower edge last segments)", rb_name.c_str(), vr_ur);
rx_sdu->set_timestamp();
metrics.num_rx_sdus++;
metrics.num_rx_sdu_bytes += rx_sdu->N_bytes;
if (cfg.um.is_mrb) {
pdcp->write_pdu_mch(lcid, std::move(rx_sdu));
} else {
@ -544,6 +548,8 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus()
vr_ur,
i);
rx_sdu->set_timestamp();
metrics.num_rx_sdus++;
metrics.num_rx_sdu_bytes += rx_sdu->N_bytes;
if (cfg.um.is_mrb) {
pdcp->write_pdu_mch(lcid, std::move(rx_sdu));
} else {
@ -604,6 +610,8 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus()
log->info_hex(
rx_sdu->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (update vr_ur last segments)", rb_name.c_str(), vr_ur);
rx_sdu->set_timestamp();
metrics.num_rx_sdus++;
metrics.num_rx_sdu_bytes += rx_sdu->N_bytes;
if (cfg.um.is_mrb) {
pdcp->write_pdu_mch(lcid, std::move(rx_sdu));
} else {

@ -22,6 +22,7 @@
#include "srslte/common/log_filter.h"
#include "srslte/common/logger_stdout.h"
#include "srslte/common/rlc_pcap.h"
#include "srslte/common/test_common.h"
#include "srslte/common/threads.h"
#include "srslte/upper/rlc_am_lte.h"
#include <assert.h>
@ -36,6 +37,18 @@ using namespace srslte;
srslte::log_ref rrc_log1("RLC_AM_1");
srslte::log_ref rrc_log2("RLC_AM_2");
bool rx_is_tx(const rlc_bearer_metrics_t& rlc1_metrics, const rlc_bearer_metrics_t& rlc2_metrics)
{
if (rlc1_metrics.num_tx_pdu_bytes != rlc2_metrics.num_rx_pdu_bytes) {
return false;
}
if (rlc2_metrics.num_tx_pdu_bytes != rlc1_metrics.num_rx_pdu_bytes) {
return false;
}
return true;
}
class rlc_am_tester : public pdcp_interface_rlc, public rrc_interface_rlc
{
public:
@ -178,18 +191,9 @@ bool meas_obj_test()
}
// Check statistics
rlc_bearer_metrics_t rlc1_metrics = rlc1.get_metrics();
rlc_bearer_metrics_t rlc2_metrics = rlc2.get_metrics();
if (rlc1_metrics.num_tx_bytes != rlc2_metrics.num_rx_bytes) {
return -1;
}
TESTASSERT(rx_is_tx(rlc1.get_metrics(), rlc2.get_metrics()));
if (rlc2_metrics.num_tx_bytes != rlc1_metrics.num_rx_bytes) {
return -1;
}
return 0;
return SRSLTE_SUCCESS;
}
bool concat_test()
@ -239,18 +243,9 @@ bool concat_test()
}
// Check statistics
rlc_bearer_metrics_t rlc1_metrics = rlc1.get_metrics();
rlc_bearer_metrics_t rlc2_metrics = rlc2.get_metrics();
TESTASSERT(rx_is_tx(rlc1.get_metrics(), rlc2.get_metrics()));
if (rlc1_metrics.num_tx_bytes != rlc2_metrics.num_rx_bytes) {
return -1;
}
if (rlc2_metrics.num_tx_bytes != rlc1_metrics.num_rx_bytes) {
return -1;
}
return 0;
return SRSLTE_SUCCESS;
}
bool segment_test(bool in_seq_rx)
@ -330,18 +325,9 @@ bool segment_test(bool in_seq_rx)
}
// Check statistics
rlc_bearer_metrics_t rlc1_metrics = rlc1.get_metrics();
rlc_bearer_metrics_t rlc2_metrics = rlc2.get_metrics();
TESTASSERT(rx_is_tx(rlc1.get_metrics(), rlc2.get_metrics()));
if (rlc1_metrics.num_tx_bytes != rlc2_metrics.num_rx_bytes) {
return -1;
}
if (rlc2_metrics.num_tx_bytes != rlc1_metrics.num_rx_bytes) {
return -1;
}
return 0;
return SRSLTE_SUCCESS;
}
bool retx_test()

@ -533,18 +533,18 @@ void stress_test(stress_test_args_t args)
tester1.get_nof_rx_pdus(),
args.test_duration_sec,
static_cast<double>(tester1.get_nof_rx_pdus() / args.test_duration_sec),
metrics.bearer[lcid].num_tx_bytes,
metrics.bearer[lcid].num_rx_bytes);
printf("rlc1_num_lost=%d\n", metrics.bearer[lcid].num_lost_pdus);
metrics.bearer[lcid].num_tx_pdu_bytes,
metrics.bearer[lcid].num_rx_pdu_bytes);
rlc_bearer_metrics_print(metrics.bearer[lcid]);
rlc2.get_metrics(metrics);
printf("RLC2 received %d SDUs in %ds (%.2f/s), Tx=%" PRIu64 " B, Rx=%" PRIu64 " B\n",
tester2.get_nof_rx_pdus(),
args.test_duration_sec,
static_cast<double>(tester2.get_nof_rx_pdus() / args.test_duration_sec),
metrics.bearer[lcid].num_tx_bytes,
metrics.bearer[lcid].num_rx_bytes);
printf("rlc2_num_lost=%d\n", metrics.bearer[lcid].num_lost_pdus);
metrics.bearer[lcid].num_tx_pdu_bytes,
metrics.bearer[lcid].num_rx_pdu_bytes);
rlc_bearer_metrics_print(metrics.bearer[lcid]);
}
int main(int argc, char** argv)

Loading…
Cancel
Save