diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-07-16 18:33:46 +0200 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-07-16 19:24:16 +0200 |
commit | 77da35515ce40baf2305cf7cf5e4008f6b478e36 (patch) | |
tree | e2547acc07f9437116d49052ff62d0e8b5acca00 /src | |
parent | 7b3675bf7a6203467e6a72e255544365cefc3b06 (diff) |
alloc: Make alloc_algorithm_dynamic stateful
Currently there is no persistent state being used in
alloc_algorithm_dynamic. So algorithm B is even used in persistent
high usage scenarios. If there are many active TBFs, multislot
assigments are not fair, because MS of a "higher" multislot class get
higher troughputs. On the other hand, as long as all PDCH are busy no
bandwidth will be wasted even if all MS use algorithm A.
This commit modifies alloc_algorithm_dynamic to disable algorithm B
when that call fails. It then keeps it disabled until there is a
single PDCH which is idle (it is considered idle, if there is at most
one active DL TBF assigned to it).
Sponsored-by: On-Waves ehf
Diffstat (limited to 'src')
-rw-r--r-- | src/bts.h | 2 | ||||
-rw-r--r-- | src/gprs_rlcmac_ts_alloc.cpp | 46 |
2 files changed, 45 insertions, 3 deletions
@@ -182,6 +182,8 @@ struct gprs_rlcmac_bts { /* list of downlink TBFs */ struct llist_head dl_tbfs; + /* State for dynamic algorithm selection */ + int multislot_disabled; /** * Point back to the C++ object. This is used during the transition diff --git a/src/gprs_rlcmac_ts_alloc.cpp b/src/gprs_rlcmac_ts_alloc.cpp index e2c2a0f4..3714b30c 100644 --- a/src/gprs_rlcmac_ts_alloc.cpp +++ b/src/gprs_rlcmac_ts_alloc.cpp @@ -28,6 +28,9 @@ #include <errno.h> #include <values.h> +/* Consider a PDCH as idle if has at most this number of TBFs assigned to it */ +#define PDCH_IDLE_TBF_THRESH 1 + /* 3GPP TS 05.02 Annex B.1 */ #define MS_NA 255 /* N/A */ @@ -363,6 +366,30 @@ static int find_trx(BTS *bts, const GprsMs *ms, int use_trx) return -EBUSY; } +static struct gprs_rlcmac_pdch * find_idle_pdch(BTS *bts) +{ + unsigned trx_no; + unsigned ts; + struct gprs_rlcmac_bts *bts_data = bts->bts_data(); + + /* Find the first PDCH with an unused DL TS */ + for (trx_no = 0; trx_no < ARRAY_SIZE(bts_data->trx); trx_no += 1) { + struct gprs_rlcmac_trx *trx = &bts_data->trx[trx_no]; + for (ts = 0; ts < ARRAY_SIZE(trx->pdch); ts++) { + struct gprs_rlcmac_pdch *pdch = &trx->pdch[ts]; + if (!pdch->is_enabled()) + continue; + + if (pdch->num_tbfs(GPRS_RLCMAC_DL_TBF) > PDCH_IDLE_TBF_THRESH) + continue; + + return pdch; + } + } + + return NULL; +} + static int tfi_find_free(BTS *bts, const GprsMs *ms, enum gprs_rlcmac_tbf_direction dir, int use_trx, int *trx_no_) { @@ -1030,9 +1057,22 @@ int alloc_algorithm_dynamic(struct gprs_rlcmac_bts *bts, { int rc; - rc = alloc_algorithm_b(bts, ms_, tbf_, cust, single, use_trx); - if (rc >= 0) - return rc; + /* Reset load_is_high if there is at least one idle PDCH */ + if (bts->multislot_disabled) { + bts->multislot_disabled = find_idle_pdch(bts->bts) == NULL; + if (!bts->multislot_disabled) + LOGP(DRLCMAC, LOGL_DEBUG, "Enabling algorithm B\n"); + } + + if (!bts->multislot_disabled) { + rc = alloc_algorithm_b(bts, ms_, tbf_, cust, single, use_trx); + if (rc >= 0) + return rc; + + if (!bts->multislot_disabled) + LOGP(DRLCMAC, LOGL_DEBUG, "Disabling algorithm B\n"); + bts->multislot_disabled = 1; + } rc = alloc_algorithm_a(bts, ms_, tbf_, cust, single, use_trx); return rc; |