mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-pcu.git
synced 2025-11-03 05:33:31 +00:00
Compare commits
2 Commits
0.5.0
...
jerlbeck/w
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a4bd9661b | ||
|
|
66ba0844be |
@@ -586,6 +586,23 @@ static uint32_t get_and_reset_avg_queue_delay(void)
|
||||
return avg_delay_ms;
|
||||
}
|
||||
|
||||
static int get_and_reset_measured_leak_rate(int num_pdch)
|
||||
{
|
||||
int rate; /* byte per second */
|
||||
|
||||
if (the_pcu.queue_frames_sent == 0)
|
||||
return -1;
|
||||
|
||||
/* 20ms/num_pdch is the average RLC block duration */
|
||||
rate = the_pcu.queue_bytes_recv * 1000 * num_pdch /
|
||||
(20 * the_pcu.queue_frames_sent);
|
||||
|
||||
the_pcu.queue_frames_sent = 0;
|
||||
the_pcu.queue_bytes_recv = 0;
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
int gprs_bssgp_tx_fc_bvc(void)
|
||||
{
|
||||
struct gprs_rlcmac_bts *bts;
|
||||
@@ -624,6 +641,20 @@ int gprs_bssgp_tx_fc_bvc(void)
|
||||
ms_bucket_size = bts->fc_ms_bucket_size;
|
||||
ms_leak_rate = bts->fc_ms_leak_rate;
|
||||
|
||||
if (leak_rate == 0) {
|
||||
int meas_rate;
|
||||
|
||||
if (num_pdch < 0)
|
||||
num_pdch = count_pdch(bts);
|
||||
|
||||
meas_rate = get_and_reset_measured_leak_rate(num_pdch);
|
||||
if (meas_rate > 0) {
|
||||
leak_rate = meas_rate;
|
||||
LOGP(DBSSGP, LOGL_DEBUG,
|
||||
"Measured BVC leak rate = %d\n", leak_rate);
|
||||
}
|
||||
}
|
||||
|
||||
if (leak_rate == 0) {
|
||||
if (num_pdch < 0)
|
||||
num_pdch = count_pdch(bts);
|
||||
@@ -823,6 +854,16 @@ struct bssgp_bvc_ctx *gprs_bssgp_pcu_current_bctx(void)
|
||||
return the_pcu.bctx;
|
||||
}
|
||||
|
||||
void gprs_bssgp_update_frames_sent()
|
||||
{
|
||||
the_pcu.queue_frames_sent += 1;
|
||||
}
|
||||
|
||||
void gprs_bssgp_update_bytes_received(unsigned bytes_recv)
|
||||
{
|
||||
the_pcu.queue_bytes_recv += bytes_recv;
|
||||
}
|
||||
|
||||
void gprs_bssgp_update_queue_delay(const struct timeval *tv_recv,
|
||||
const struct timeval *tv_now)
|
||||
{
|
||||
|
||||
@@ -62,6 +62,8 @@ struct gprs_bssgp_pcu {
|
||||
struct timeval queue_delay_sum;
|
||||
unsigned queue_delay_count;
|
||||
uint8_t fc_tag;
|
||||
unsigned queue_frames_sent;
|
||||
unsigned queue_bytes_recv;
|
||||
|
||||
/** callbacks below */
|
||||
|
||||
@@ -85,5 +87,7 @@ struct bssgp_bvc_ctx *gprs_bssgp_pcu_current_bctx(void);
|
||||
|
||||
void gprs_bssgp_update_queue_delay(const struct timeval *tv_recv,
|
||||
const struct timeval *tv_now);
|
||||
void gprs_bssgp_update_frames_sent();
|
||||
void gprs_bssgp_update_bytes_received(unsigned bytes_recv);
|
||||
|
||||
#endif // GPRS_BSSGP_PCU_H
|
||||
|
||||
@@ -321,6 +321,10 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts,
|
||||
if (!msg)
|
||||
msg = sched_select_downlink(bts, trx, ts, fn, block_nr, pdch);
|
||||
|
||||
/* Used to calculate the net leak rate, must not include dummy messages */
|
||||
if (msg)
|
||||
gprs_bssgp_update_frames_sent();
|
||||
|
||||
/* Prio 3: send dummy contol message */
|
||||
if (!msg)
|
||||
msg = sched_dummy();
|
||||
|
||||
@@ -505,7 +505,8 @@ int alloc_algorithm_a(struct gprs_rlcmac_bts *bts,
|
||||
|
||||
static int find_multi_slots(struct gprs_rlcmac_bts *bts,
|
||||
struct gprs_rlcmac_trx *trx,
|
||||
const GprsMs *ms, uint8_t *ul_slots, uint8_t *dl_slots)
|
||||
const GprsMs *ms, uint8_t *ul_slots, uint8_t *dl_slots,
|
||||
int first_common_ts)
|
||||
{
|
||||
const struct gprs_ms_multislot_class *ms_class;
|
||||
uint8_t Tx, Sum; /* Maximum Number of Slots: RX, Tx, Sum Rx+Tx */
|
||||
@@ -523,6 +524,8 @@ static int find_multi_slots(struct gprs_rlcmac_bts *bts,
|
||||
unsigned num_tx;
|
||||
enum {MASK_TT, MASK_TR};
|
||||
unsigned mask_sel;
|
||||
uint8_t common_mask = 0;
|
||||
uint8_t common_req = 0;
|
||||
|
||||
if (ms->ms_class() >= 32) {
|
||||
LOGP(DRLCMAC, LOGL_ERROR, "Multislot class %d out of range.\n",
|
||||
@@ -599,6 +602,11 @@ static int find_multi_slots(struct gprs_rlcmac_bts *bts,
|
||||
max_ul_slots = 0;
|
||||
max_dl_slots = 0;
|
||||
|
||||
if (first_common_ts >= 0) {
|
||||
common_req = 1 << first_common_ts;
|
||||
common_mask = (common_req << 1) - 1;
|
||||
}
|
||||
|
||||
/* Iterate through possible numbers of TX slots */
|
||||
for (num_tx = 1; num_tx <= ms_class->tx; num_tx += 1) {
|
||||
uint16_t tx_valid_win = (1 << num_tx) - 1;
|
||||
@@ -735,6 +743,15 @@ static int find_multi_slots(struct gprs_rlcmac_bts *bts,
|
||||
if (!rx_window)
|
||||
continue;
|
||||
|
||||
/* Check required common slots */
|
||||
if (((tx_window & rx_window) & common_mask) != common_req) {
|
||||
LOGP(DRLCMAC, LOGL_INFO,
|
||||
"Common slot pre-selection mismatch: "
|
||||
"%02x %02x %02x %02x\n",
|
||||
tx_window, rx_window, common_mask, common_req);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check number of common slots according to TS 54.002, 6.4.2.2 */
|
||||
common_slot_count = bitcount(tx_window & rx_window);
|
||||
req_common_slots = OSMO_MIN(tx_slot_count, rx_slot_count);
|
||||
@@ -873,7 +890,8 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts,
|
||||
trx = &bts->trx[trx_no];
|
||||
|
||||
if (!dl_slots || !ul_slots) {
|
||||
rc = find_multi_slots(bts, trx, ms, &ul_slots, &dl_slots);
|
||||
rc = find_multi_slots(bts, trx, ms, &ul_slots, &dl_slots,
|
||||
first_common_ts);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
|
||||
@@ -355,6 +355,13 @@ struct gprs_rlcmac_dl_tbf : public gprs_rlcmac_tbf {
|
||||
} m_bw;
|
||||
|
||||
protected:
|
||||
struct ana_result {
|
||||
unsigned received_packets;
|
||||
unsigned lost_packets;
|
||||
unsigned received_bytes;
|
||||
unsigned lost_bytes;
|
||||
};
|
||||
|
||||
struct msgb *create_new_bsn(const uint32_t fn, const uint8_t ts);
|
||||
struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts,
|
||||
const int index);
|
||||
@@ -363,7 +370,7 @@ protected:
|
||||
bool dl_window_stalled() const;
|
||||
void reuse_tbf();
|
||||
void start_llc_timer();
|
||||
int analyse_errors(char *show_rbb, uint8_t ssn);
|
||||
int analyse_errors(char *show_rbb, uint8_t ssn, ana_result *res);
|
||||
void schedule_next_frame();
|
||||
|
||||
struct osmo_timer_list m_llc_timer;
|
||||
|
||||
@@ -689,7 +689,8 @@ static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn, uint16_t mod_sns)
|
||||
return (ssn - 1 - bitnum) & mod_sns;
|
||||
}
|
||||
|
||||
int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn)
|
||||
int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn,
|
||||
ana_result *res)
|
||||
{
|
||||
gprs_rlc_data *rlc_data;
|
||||
uint16_t lost = 0, received = 0, skipped = 0;
|
||||
@@ -697,9 +698,13 @@ int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn)
|
||||
memset(info, '.', sizeof(info));
|
||||
info[64] = 0;
|
||||
uint16_t bsn = 0;
|
||||
unsigned received_bytes = 0, lost_bytes = 0;
|
||||
unsigned received_packets = 0, lost_packets = 0;
|
||||
|
||||
/* SSN - 1 is in range V(A)..V(S)-1 */
|
||||
for (int bitpos = 0; bitpos < m_window.ws(); bitpos++) {
|
||||
bool is_received = show_rbb[m_window.ws() - 1 - bitpos] == 'R';
|
||||
|
||||
bsn = bitnum_to_bsn(bitpos, ssn, m_window.mod_sns());
|
||||
|
||||
if (bsn == ((m_window.v_a() - 1) & m_window.mod_sns())) {
|
||||
@@ -713,6 +718,17 @@ int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get general statistics */
|
||||
if (is_received && !m_window.m_v_b.is_acked(bsn)) {
|
||||
received_packets += 1;
|
||||
received_bytes += rlc_data->len;
|
||||
} else if (!is_received) {
|
||||
lost_packets += 1;
|
||||
lost_bytes += rlc_data->len;
|
||||
}
|
||||
|
||||
/* Get statistics for current CS */
|
||||
|
||||
if (rlc_data->cs != current_cs()) {
|
||||
/* This block has already been encoded with a different
|
||||
* CS, so it doesn't help us to decide, whether the
|
||||
@@ -722,7 +738,7 @@ int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (show_rbb[m_window.ws() - 1 - bitpos] == 'R') {
|
||||
if (is_received) {
|
||||
if (!m_window.m_v_b.is_acked(bsn)) {
|
||||
received += 1;
|
||||
info[bitpos] = 'R';
|
||||
@@ -740,6 +756,11 @@ int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn)
|
||||
name(), m_window.v_a(), m_window.v_s(), lost, received,
|
||||
skipped, bsn, info);
|
||||
|
||||
res->received_packets = received_packets;
|
||||
res->lost_packets = lost_packets;
|
||||
res->received_bytes = received_bytes;
|
||||
res->lost_bytes = lost_bytes;
|
||||
|
||||
if (lost + received <= 1)
|
||||
return -1;
|
||||
|
||||
@@ -755,6 +776,7 @@ int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb)
|
||||
char show_v_b[RLC_MAX_SNS + 1];
|
||||
const uint16_t mod_sns = m_window.mod_sns();
|
||||
int error_rate;
|
||||
struct ana_result ana_res;
|
||||
|
||||
Decoding::extract_rbb(rbb, show_rbb);
|
||||
/* show received array in debug (bit 64..1) */
|
||||
@@ -777,10 +799,10 @@ int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb)
|
||||
return 1; /* indicate to free TBF */
|
||||
}
|
||||
|
||||
if (bts_data()->cs_adj_enabled && ms()) {
|
||||
error_rate = analyse_errors(show_rbb, ssn);
|
||||
error_rate = analyse_errors(show_rbb, ssn, &ana_res);
|
||||
|
||||
if (bts_data()->cs_adj_enabled && ms())
|
||||
ms()->update_error_rate(this, error_rate);
|
||||
}
|
||||
|
||||
m_window.update(bts, show_rbb, ssn,
|
||||
&lost, &received);
|
||||
@@ -788,6 +810,9 @@ int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb)
|
||||
/* report lost and received packets */
|
||||
gprs_rlcmac_received_lost(this, received, lost);
|
||||
|
||||
/* Used to calculate the net leak rate */
|
||||
gprs_bssgp_update_bytes_received(ana_res.received_bytes);
|
||||
|
||||
/* raise V(A), if possible */
|
||||
m_window.raise(m_window.move_window());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user