This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
neels gerrit-no-reply at lists.osmocom.orgneels has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/22269 ) Change subject: hodec2: fix congestion balancing on dyn TS ...................................................................... hodec2: fix congestion balancing on dyn TS When balancing congestion, not only look at TCH/F or TCH/H separately, but also to take into account the effects on the other TCH kind from using/freeing dynamic TS. Related: OS#5298 Change-Id: I433df6f343650f9056b1bab926bc19ac1d867ad5 --- M src/osmo-bsc/handover_decision_2.c M tests/handover/test_dyn_ts_balance_congestion.ho_vty 2 files changed, 106 insertions(+), 17 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/69/22269/1 diff --git a/src/osmo-bsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c index 379970f..c4144a2 100644 --- a/src/osmo-bsc/handover_decision_2.c +++ b/src/osmo-bsc/handover_decision_2.c @@ -106,8 +106,17 @@ struct gsm_lchan *lchan; struct gsm_bts *bts; int rxlev; + /* free/min-free for the current TCH kind, same as either free_tch_f or free_tch_h below */ int free_tch; int min_free_tch; + /* free/min-free for the two TCH kinds, to calculate F<->H cross effects for dynamic timeslots */ + int free_tchf; + int min_free_tchf; + int free_tchh; + int min_free_tchh; + /* Effects of freeing a dynamic timeslot: */ + int lchan_frees_tchf; + int lchan_frees_tchh; } current; struct { struct neighbor_ident_key nik; /* neighbor ARFCN+BSIC */ @@ -155,6 +164,17 @@ static void congestion_check_cb(void *arg); +static unsigned int ts_usage_count(struct gsm_bts_trx_ts *ts) +{ + struct gsm_lchan *lchan; + unsigned int count = 0; + ts_for_each_lchan(lchan, ts) { + if (lchan_state_is(lchan, LCHAN_ST_ESTABLISHED)) + count++; + } + return count; +} + /* This function gets called on ho2 init, whenever the congestion check interval is changed, and also * when the timer has fired to trigger again after the next congestion check timeout. */ static void reinit_congestion_timer(struct gsm_network *net) @@ -659,21 +679,75 @@ * congestion on the current cell, hence the - 1 on the target. */ current_overbooked = load_above_congestion(c->current.free_tch, c->current.min_free_tch); if (requirement & REQUIREMENT_A_TCHF) { + bool ok; int32_t target_overbooked = load_above_congestion(c->target.free_tchf - 1, c->target.min_free_tchf); LOGPHOLCHANTOBTS(c->current.lchan, c->target.bts, LOGL_DEBUG, "current overbooked = %s%%, TCH/F target overbooked after HO = %s%%\n", osmo_int_to_float_str_c(OTC_SELECT, current_overbooked, LOAD_PRECISION - 2), osmo_int_to_float_str_c(OTC_SELECT, target_overbooked, LOAD_PRECISION - 2)); - if (target_overbooked < current_overbooked) + ok = target_overbooked < current_overbooked; + /* Look at dynamic timeslot effects on TCH/H: */ + if (ok && c->target.next_tchf_reduces_tchh) { + /* Looking at the current TCH type and the target cell's TCH/F alone, congestion balancing + * should happen. However, what if the target TCH/F is a dynamic timeslot -- would that cause + * congestion on TCH/H above the current cell's TCH/H congestion? */ + int32_t current_tchh_overbooked = load_above_congestion(c->current.free_tchh, + c->current.min_free_tchh); + int32_t target_tchh_overbooked; + int target_free_tchh_after_ho = c->target.free_tchh - c->target.next_tchf_reduces_tchh; + /* If this is a re-assignment within the same cell, and if the current candidate would free a + * dynamic timeslot, then the target-overbooking after HO is reduced again by the freed dynamic + * TS. */ + if (c->current.bts == c->target.bts) + target_free_tchh_after_ho += c->current.lchan_frees_tchh; + target_tchh_overbooked = load_above_congestion(target_free_tchh_after_ho, + c->target.min_free_tchh); + LOGPHOLCHANTOBTS(c->current.lchan, c->target.bts, LOGL_DEBUG, + "dyn TS: current TCH/H overbooked = %s%%, TCH/H target overbooked after HO = %s%%\n", + osmo_int_to_float_str_c(OTC_SELECT, current_tchh_overbooked, LOAD_PRECISION - 2), + osmo_int_to_float_str_c(OTC_SELECT, target_tchh_overbooked, LOAD_PRECISION - 2)); + /* For the current TCH kind, a handover should only happen if things actually get better + * (condition is '<'). For dynamic timeslot cross effects TCH/F->TCH/H, it is fine to not make + * it worse. Hence the smaller-or-equal condition. */ + ok = target_tchh_overbooked <= current_tchh_overbooked; + } + if (ok) requirement |= REQUIREMENT_C_TCHF; } if (requirement & REQUIREMENT_A_TCHH) { + bool ok; int32_t target_overbooked = load_above_congestion(c->target.free_tchh - 1, c->target.min_free_tchh); LOGPHOLCHANTOBTS(c->current.lchan, c->target.bts, LOGL_DEBUG, "current overbooked = %s%%, TCH/H target overbooked after HO = %s%%\n", osmo_int_to_float_str_c(OTC_SELECT, current_overbooked, LOAD_PRECISION - 2), osmo_int_to_float_str_c(OTC_SELECT, target_overbooked, LOAD_PRECISION - 2)); - if (target_overbooked < current_overbooked) + ok = target_overbooked < current_overbooked; + /* Look at dynamic timeslot effects on TCH/F: */ + if (ok && c->target.next_tchh_reduces_tchf) { + /* Looking at the current TCH type and the target cell's TCH/H alone, congestion balancing + * should happen. However, what if the target TCH/H is a dynamic timeslot -- would that cause + * congestion on TCH/F above the current cell's TCH/F congestion? */ + int32_t current_tchf_overbooked = load_above_congestion(c->current.free_tchf, + c->current.min_free_tchf); + int32_t target_tchf_overbooked; + int target_free_tchf_after_ho = c->target.free_tchf - c->target.next_tchh_reduces_tchf; + /* If this is a re-assignment within the same cell, and if the current candidate would free a + * dynamic timeslot, then the target-overbooking after HO is reduced again by the freed dynamic + * TS. */ + if (c->current.bts == c->target.bts) + target_free_tchf_after_ho += c->current.lchan_frees_tchf; + target_tchf_overbooked = load_above_congestion(target_free_tchf_after_ho, + c->target.min_free_tchf); + LOGPHOLCHANTOBTS(c->current.lchan, c->target.bts, LOGL_DEBUG, + "dyn TS: current TCH/F overbooked = %s%%, TCH/F target overbooked after HO = %s%%\n", + osmo_int_to_float_str_c(OTC_SELECT, current_tchf_overbooked, LOAD_PRECISION - 2), + osmo_int_to_float_str_c(OTC_SELECT, target_tchf_overbooked, LOAD_PRECISION - 2)); + /* For the current TCH kind, a handover should only happen if things actually get better + * (condition is '<'). For dynamic timeslot cross effects TCH/H->TCH/F, it is fine to not make + * it worse. Hence the smaller-or-equal condition. */ + ok = target_tchf_overbooked <= current_tchf_overbooked; + } + if (ok) requirement |= REQUIREMENT_C_TCHH; } @@ -904,17 +978,37 @@ { struct gsm_lchan *next_lchan; - c->current.free_tch = bts_count_free_ts(c->current.bts, c->current.lchan->ts->pchan_is); + c->current.free_tchf = bts_count_free_ts(c->current.bts, GSM_PCHAN_TCH_F); + c->current.min_free_tchf = ho_get_hodec2_tchf_min_slots(c->current.bts->ho); + c->current.free_tchh = bts_count_free_ts(c->current.bts, GSM_PCHAN_TCH_H); + c->current.min_free_tchh = ho_get_hodec2_tchh_min_slots(c->current.bts->ho); switch (c->current.lchan->ts->pchan_is) { case GSM_PCHAN_TCH_F: - c->current.min_free_tch = ho_get_hodec2_tchf_min_slots(c->current.bts->ho); + c->current.free_tch = c->current.free_tchf; + c->current.min_free_tch = c->current.min_free_tchf; + c->current.lchan_frees_tchf = 1; + if (c->current.lchan->ts->pchan_on_init == GSM_PCHAN_TCH_F_TCH_H_PDCH) + c->current.lchan_frees_tchh = 2; + else + c->current.lchan_frees_tchh = 0; break; case GSM_PCHAN_TCH_H: - c->current.min_free_tch = ho_get_hodec2_tchh_min_slots(c->current.bts->ho); + c->current.free_tch = c->current.free_tchh; + c->current.min_free_tch = c->current.min_free_tchh; + c->current.lchan_frees_tchh = 1; + /* Freeing one of two TCH/H does not free a dyn TS and would not free a TCH/F. It has to be the last + * TCH/H of a dynamic timeslot that is freed to get a new TCH/F in the current cell from the handover. + * Hence the ts_usage_count() condition. */ + if (c->current.lchan->ts->pchan_on_init == GSM_PCHAN_TCH_F_TCH_H_PDCH + && ts_usage_count(c->current.lchan->ts) == 1) + c->current.lchan_frees_tchf = 1; + else + c->current.lchan_frees_tchf = 0; break; default: break; } + c->target.free_tchf = bts_count_free_ts(c->target.bts, GSM_PCHAN_TCH_F); c->target.min_free_tchf = ho_get_hodec2_tchf_min_slots(c->target.bts->ho); c->target.free_tchh = bts_count_free_ts(c->target.bts, GSM_PCHAN_TCH_H); @@ -1454,17 +1548,6 @@ || lchan->ts->pchan_on_init == GSM_PCHAN_TCH_F_PDCH; } -static unsigned int ts_usage_count(struct gsm_bts_trx_ts *ts) -{ - struct gsm_lchan *lchan; - unsigned int count = 0; - ts_for_each_lchan(lchan, ts) { - if (lchan_state_is(lchan, LCHAN_ST_ESTABLISHED)) - count++; - } - return count; -} - static bool is_upgrade_to_tchf(const struct ho_candidate *c, uint8_t for_requirement) { return c->current.lchan diff --git a/tests/handover/test_dyn_ts_balance_congestion.ho_vty b/tests/handover/test_dyn_ts_balance_congestion.ho_vty index ad9d6a5..2fa11b6 100644 --- a/tests/handover/test_dyn_ts_balance_congestion.ho_vty +++ b/tests/handover/test_dyn_ts_balance_congestion.ho_vty @@ -27,5 +27,11 @@ # not congested. No handover is performed because 50% in the target is more congestion for TCH/H than 0% in the source # cell. congestion-check -# FAIL: should not increase TCH/H congestion by occupying a dyn TS +expect-no-chan + +# If there is no constraint on TCH/H in the target cell, the handover does take place. +network + bts 1 + handover2 min-free-slots tch/h 2 +congestion-check expect-ho from lchan 0 0 1 0 to lchan 1 0 5 0 -- To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/22269 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-bsc Gerrit-Branch: master Gerrit-Change-Id: I433df6f343650f9056b1bab926bc19ac1d867ad5 Gerrit-Change-Number: 22269 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofmeyr at sysmocom.de> Gerrit-MessageType: newchange -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210117/ae9f5946/attachment.htm>