diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-09-07 18:49:00 +0200 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-09-11 11:52:02 +0200 |
commit | 2db0f08e08d074dc2876b780c76f7261851e7296 (patch) | |
tree | de7b47483ea75519b7a22297c74c7adeada9d2d6 /src/gprs_bssgp_pcu.cpp | |
parent | 7c8d39a67b7568cda38829c774ea541250f3142f (diff) |
bssgp: Use measured leak rate for flow control
The leak rate sent to the SGSN does not reflect the current CS level,
lost frames, and control message overhead. So the SGSN cannot do
proper queue control under non-optimal conditions.
This commit computes the leak rate for the last flow control interval
by computing the maximum theoretical leak rate and basically
substracting control blocks, nacked blocks, and reduced block sizes
due to CS downgrade. By using this approach, the value will by more
stable on low load, where the value will tend to be near the value
derived from the configuration. On full load the transmitted value is
completely derived from the measurements.
Note that the MS default values are no adapted to the adapted BVC
leak rate, since a single MS which has a lower link quality would
otherwise be reducing the rate of another MS with good radio
conditions, which would not make much sense if they did not share any
PDCH.
Sponsored-by: On-Waves ehf
Diffstat (limited to 'src/gprs_bssgp_pcu.cpp')
-rw-r--r-- | src/gprs_bssgp_pcu.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index 7f50e17d..cce184d5 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -591,6 +591,32 @@ static uint32_t get_and_reset_avg_queue_delay(void) return avg_delay_ms; } +static int get_and_reset_measured_leak_rate(int *usage_by_1000, unsigned num_pdch) +{ + int rate; /* byte per second */ + + if (the_pcu.queue_frames_sent == 0) + return -1; + + if (the_pcu.queue_frames_recv == 0) + return -1; + + *usage_by_1000 = the_pcu.queue_frames_recv * 1000 / + the_pcu.queue_frames_sent; + + /* 20ms/num_pdch is the average RLC block duration, so the rate is + * calculated as: + * rate = bytes_recv / (block_dur * block_count) */ + rate = the_pcu.queue_bytes_recv * 1000 * num_pdch / + (20 * the_pcu.queue_frames_recv); + + the_pcu.queue_frames_sent = 0; + the_pcu.queue_bytes_recv = 0; + the_pcu.queue_frames_recv = 0; + + return rate; +} + int gprs_bssgp_tx_fc_bvc(void) { struct gprs_rlcmac_bts *bts; @@ -630,6 +656,26 @@ int gprs_bssgp_tx_fc_bvc(void) ms_leak_rate = bts->fc_ms_leak_rate; if (leak_rate == 0) { + int meas_rate; + int usage; /* in 0..1000 */ + + if (num_pdch < 0) + num_pdch = count_pdch(bts); + + meas_rate = get_and_reset_measured_leak_rate(&usage, num_pdch); + if (meas_rate > 0) { + leak_rate = gprs_bssgp_max_leak_rate(max_cs_dl, num_pdch); + leak_rate = + (meas_rate * usage + leak_rate * (1000 - usage)) / + 1000; + LOGP(DBSSGP, LOGL_DEBUG, + "Estimated BVC leak rate = %d " + "(measured %d, usage %d%%)\n", + leak_rate, meas_rate, usage/10); + } + } + + if (leak_rate == 0) { if (num_pdch < 0) num_pdch = count_pdch(bts); @@ -853,6 +899,17 @@ 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, unsigned frames_recv) +{ + the_pcu.queue_bytes_recv += bytes_recv; + the_pcu.queue_frames_recv += frames_recv; +} + void gprs_bssgp_update_queue_delay(const struct timeval *tv_recv, const struct timeval *tv_now) { |