rlc_um: fix counting of lost PDUs

* change try_push() return value to indicate whether the addition
  of the SDU to the tx queue was successful or not
* count lost PDUs
master
Andre Puschmann 5 years ago
parent 96726a03e0
commit fc3cd24177

@ -34,8 +34,8 @@ typedef struct {
uint64_t num_tx_bytes; uint64_t num_tx_bytes;
uint64_t num_rx_bytes; uint64_t num_rx_bytes;
uint32_t num_lost_pdus; uint32_t num_lost_pdus; //< Lost PDUs registered at Rx
uint32_t num_dropped_sdus; uint32_t num_dropped_sdus; //< Count dropped SDUs at Tx due to bearer inactivity or empty buffer
} rlc_bearer_metrics_t; } rlc_bearer_metrics_t;
typedef struct { typedef struct {

@ -82,7 +82,7 @@ protected:
void empty_queue(); void empty_queue();
void write_sdu(unique_byte_buffer_t sdu); void write_sdu(unique_byte_buffer_t sdu);
void discard_sdu(uint32_t discard_sn); void discard_sdu(uint32_t discard_sn);
void try_write_sdu(unique_byte_buffer_t sdu); int try_write_sdu(unique_byte_buffer_t sdu);
void reset_metrics(); void reset_metrics();
bool has_data(); bool has_data();
virtual uint32_t get_buffer_state() = 0; virtual uint32_t get_buffer_state() = 0;

@ -102,7 +102,9 @@ void rlc_um_base::write_sdu(unique_byte_buffer_t sdu, bool blocking)
if (blocking) { if (blocking) {
tx->write_sdu(std::move(sdu)); tx->write_sdu(std::move(sdu));
} else { } else {
tx->try_write_sdu(std::move(sdu)); if (tx->try_write_sdu(std::move(sdu)) != SRSLTE_SUCCESS) {
metrics.num_dropped_sdus++;
}
} }
} }
@ -251,7 +253,7 @@ void rlc_um_base::rlc_um_base_tx::write_sdu(unique_byte_buffer_t sdu)
} }
} }
void rlc_um_base::rlc_um_base_tx::try_write_sdu(unique_byte_buffer_t sdu) int rlc_um_base::rlc_um_base_tx::try_write_sdu(unique_byte_buffer_t sdu)
{ {
if (sdu) { if (sdu) {
uint8_t* msg_ptr = sdu->msg; uint8_t* msg_ptr = sdu->msg;
@ -260,6 +262,7 @@ void rlc_um_base::rlc_um_base_tx::try_write_sdu(unique_byte_buffer_t sdu)
if (ret) { if (ret) {
log->info_hex( log->info_hex(
msg_ptr, nof_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", rb_name.c_str(), nof_bytes, tx_sdu_queue.size()); msg_ptr, nof_bytes, "%s Tx SDU (%d B, tx_sdu_queue_len=%d)", rb_name.c_str(), nof_bytes, tx_sdu_queue.size());
return SRSLTE_SUCCESS;
} else { } else {
log->info_hex(ret.error()->msg, log->info_hex(ret.error()->msg,
ret.error()->N_bytes, ret.error()->N_bytes,
@ -271,6 +274,7 @@ void rlc_um_base::rlc_um_base_tx::try_write_sdu(unique_byte_buffer_t sdu)
} else { } else {
log->warning("NULL SDU pointer in write_sdu()\n"); log->warning("NULL SDU pointer in write_sdu()\n");
} }
return SRSLTE_ERROR;
} }
void rlc_um_base::rlc_um_base_tx::discard_sdu(uint32_t discard_sn) void rlc_um_base::rlc_um_base_tx::discard_sdu(uint32_t discard_sn)

@ -374,6 +374,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus()
rx_window[vr_ur].buf->msg += len; rx_window[vr_ur].buf->msg += len;
rx_window[vr_ur].buf->N_bytes -= len; rx_window[vr_ur].buf->N_bytes -= len;
rx_sdu->clear(); rx_sdu->clear();
metrics.num_lost_pdus++;
break; break;
} }
@ -387,6 +388,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus()
vr_ur, vr_ur,
vr_ur_in_rx_sdu); vr_ur_in_rx_sdu);
rx_sdu->clear(); rx_sdu->clear();
metrics.num_lost_pdus++;
} else { } else {
log->info_hex(rx_sdu->msg, log->info_hex(rx_sdu->msg,
rx_sdu->N_bytes, rx_sdu->N_bytes,
@ -423,6 +425,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus()
if (pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { if (pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) {
log->warning("Dropping remainder of lost PDU (lower edge last segments)\n"); log->warning("Dropping remainder of lost PDU (lower edge last segments)\n");
rx_sdu->clear(); rx_sdu->clear();
metrics.num_lost_pdus++;
} else { } else {
log->info_hex( 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->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (lower edge last segments)", rb_name.c_str(), vr_ur);
@ -486,6 +489,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus()
rx_window[vr_ur].buf->msg += len; rx_window[vr_ur].buf->msg += len;
rx_window[vr_ur].buf->N_bytes -= len; rx_window[vr_ur].buf->N_bytes -= len;
rx_sdu->clear(); rx_sdu->clear();
metrics.num_lost_pdus++;
// Reset flag, it is safe to process all remaining segments of this PDU // Reset flag, it is safe to process all remaining segments of this PDU
pdu_lost = false; pdu_lost = false;
@ -499,6 +503,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus()
rx_sdu->N_bytes, rx_sdu->N_bytes,
len); len);
rx_sdu->clear(); rx_sdu->clear();
metrics.num_lost_pdus++;
goto clean_up_rx_window; goto clean_up_rx_window;
} }
@ -551,6 +556,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus()
// Advance data pointers and continue with next segment // Advance data pointers and continue with next segment
rx_window[vr_ur].buf->msg += len; rx_window[vr_ur].buf->msg += len;
rx_window[vr_ur].buf->N_bytes -= len; rx_window[vr_ur].buf->N_bytes -= len;
metrics.num_lost_pdus++;
} }
pdu_lost = false; pdu_lost = false;
} }
@ -560,6 +566,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus()
!rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) {
log->warning("Dropping PDU %d during last segment handling due to lost start segment\n", vr_ur); log->warning("Dropping PDU %d during last segment handling due to lost start segment\n", vr_ur);
rx_sdu->clear(); rx_sdu->clear();
metrics.num_lost_pdus++;
goto clean_up_rx_window; goto clean_up_rx_window;
} }
@ -587,6 +594,7 @@ void rlc_um_lte::rlc_um_lte_rx::reassemble_rx_sdus()
if (pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) { if (pdu_lost && !rlc_um_start_aligned(rx_window[vr_ur].header.fi)) {
log->warning("Dropping remainder of lost PDU (update vr_ur last segments)\n"); log->warning("Dropping remainder of lost PDU (update vr_ur last segments)\n");
rx_sdu->clear(); rx_sdu->clear();
metrics.num_lost_pdus++;
} else { } else {
log->info_hex( 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->msg, rx_sdu->N_bytes, "%s Rx SDU vr_ur=%d (update vr_ur last segments)", rb_name.c_str(), vr_ur);

@ -534,6 +534,7 @@ void stress_test(stress_test_args_t args)
static_cast<double>(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_tx_bytes,
metrics.bearer[lcid].num_rx_bytes); metrics.bearer[lcid].num_rx_bytes);
printf("rlc1_num_lost=%d\n", metrics.bearer[lcid].num_lost_pdus);
rlc2.get_metrics(metrics); rlc2.get_metrics(metrics);
printf("RLC2 received %d SDUs in %ds (%.2f/s), Tx=%" PRIu64 " B, Rx=%" PRIu64 " B\n", printf("RLC2 received %d SDUs in %ds (%.2f/s), Tx=%" PRIu64 " B, Rx=%" PRIu64 " B\n",
@ -542,6 +543,7 @@ void stress_test(stress_test_args_t args)
static_cast<double>(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_tx_bytes,
metrics.bearer[lcid].num_rx_bytes); metrics.bearer[lcid].num_rx_bytes);
printf("rlc2_num_lost=%d\n", metrics.bearer[lcid].num_lost_pdus);
} }
int main(int argc, char** argv) int main(int argc, char** argv)

Loading…
Cancel
Save