gbproxy: Implement scaling of BVC flow control in SGSN pool
When there are multiple SGSNs inside a pool, we need to decide how much of the per-BVC capacity advertised by the BSS in its BVC-FLOW-CONTROL we should announce to each of the pool members. A conservative approach would be to advertise 1/num_sgsn, but there may also be use case where over-provisioning (announcing more than an equal share of the capacity) is useful. Hence, let's introduce "pool bvc-flow-control-ratio <1-100>" in order to allow the administrator to decide. Related: OS#4891 Change-Id: Ibe5addf657e7237499ca0205bacfe999ecd1e771
This commit is contained in:
parent
d10afca811
commit
209dc9fa73
|
@ -4,3 +4,29 @@ TBD. Unfortunately this chapter of the manual still needs to be written.
|
|||
Osmocom has very limited funding and support resources; Feel free to help
|
||||
us completing this documentation by contributing with code, documentation
|
||||
or by supporting the developers financially.
|
||||
|
||||
|
||||
=== SGSN pool support
|
||||
|
||||
In a SGSN pool, osmo-gbproxy is facing the problem of dividing the downlink
|
||||
capacity of a cell towards the SGSN. The BSS advertises the per-BVC capacity
|
||||
by means of the BSSGP FLOW-CONTROL-BVC messages, but as there are multiple
|
||||
SGSN in a pool, they all have to share / divide that total capacity.
|
||||
|
||||
By default, osmo-gbproxy advertises the full capacity to _each_ of the SGSN
|
||||
pool members, which results in significant over-provisioning and can lead to
|
||||
overload situations.
|
||||
|
||||
The administrator can configure the _percentage_ of the overall BSS-advertised
|
||||
capacity that shall be reported to each pool member SGSN using the
|
||||
`pool bvc-flow-control-ratio <1-100>` configuration command.
|
||||
|
||||
A setting of 100 means that each pool member is informed of 100% of the
|
||||
BSS side capacity.
|
||||
|
||||
A setting of 25 means that each pool member is informed of 25% of the
|
||||
BSS side capacity. This would make most sense in a set-up with four
|
||||
SGSN of equal share.
|
||||
|
||||
More complex capacity division schemes are so far not supported by
|
||||
osmo-gbproxy.
|
||||
|
|
|
@ -52,6 +52,11 @@ struct gbproxy_config {
|
|||
/* NS instance of libosmogb */
|
||||
struct gprs_ns2_inst *nsi;
|
||||
|
||||
struct {
|
||||
/* percentage of BVC flow control advertised to each SGSN in the pool */
|
||||
uint8_t bvc_fc_ratio;
|
||||
} pool;
|
||||
|
||||
/* Linked list of all BSS side Gb peers */
|
||||
DECLARE_HASHTABLE(bss_nses, 8);
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
#include <osmocom/gprs/gprs_ns2.h>
|
||||
#include <osmocom/gprs/gprs_bssgp.h>
|
||||
#include <osmocom/gprs/gprs_bssgp2.h>
|
||||
#include <osmocom/gprs/gprs_bssgp_bss.h>
|
||||
#include <osmocom/gprs/bssgp_bvc_fsm.h>
|
||||
|
||||
|
@ -566,15 +567,28 @@ static void bss_ptp_bvc_state_chg_notif(uint16_t nsei, uint16_t bvci, int old_st
|
|||
/* BVC FSM informs us about BVC-FC PDU receive */
|
||||
static void bss_ptp_bvc_fc_bvc(uint16_t nsei, uint16_t bvci, const struct bssgp2_flow_ctrl *fc, void *priv)
|
||||
{
|
||||
struct bssgp2_flow_ctrl fc_reduced;
|
||||
struct gbproxy_bvc *bss_bvc = priv;
|
||||
struct gbproxy_cell *cell = bss_bvc->cell;
|
||||
struct gbproxy_cell *cell;
|
||||
struct gbproxy_config *cfg;
|
||||
|
||||
OSMO_ASSERT(bss_bvc);
|
||||
OSMO_ASSERT(fc);
|
||||
|
||||
cell = bss_bvc->cell;
|
||||
if (!cell)
|
||||
return;
|
||||
|
||||
/* FIXME: actually split the bandwidth among the SGSNs! */
|
||||
cfg = cell->cfg;
|
||||
|
||||
dispatch_to_all_sgsn_bvc(cell, BSSGP_BVCFSM_E_REQ_FC_BVC, (void *) fc);
|
||||
/* reduce / scale according to configuration to make sure we only advertise a fraction
|
||||
* of the capacity to each of the SGSNs in the pool */
|
||||
fc_reduced = *fc;
|
||||
fc_reduced.bucket_size_max = (fc->bucket_size_max * cfg->pool.bvc_fc_ratio) / 100;
|
||||
fc_reduced.bucket_leak_rate = (fc->bucket_leak_rate * cfg->pool.bvc_fc_ratio) / 100;
|
||||
/* we don't modify the per-MS related values as any single MS is only served by one SGSN */
|
||||
|
||||
dispatch_to_all_sgsn_bvc(cell, BSSGP_BVCFSM_E_REQ_FC_BVC, (void *) &fc_reduced);
|
||||
}
|
||||
|
||||
static const struct bssgp_bvc_fsm_ops bss_ptp_bvc_fsm_ops = {
|
||||
|
@ -1270,6 +1284,8 @@ int gbproxy_init_config(struct gbproxy_config *cfg)
|
|||
{
|
||||
struct timespec tp;
|
||||
|
||||
/* by default we advertise 100% of the BSS-side capacity to _each_ SGSN */
|
||||
cfg->pool.bvc_fc_ratio = 100;
|
||||
hash_init(cfg->bss_nses);
|
||||
cfg->ctrg = rate_ctr_group_alloc(tall_sgsn_ctx, &global_ctrg_desc, 0);
|
||||
if (!cfg->ctrg) {
|
||||
|
|
|
@ -76,6 +76,9 @@ static int config_write_gbproxy(struct vty *vty)
|
|||
|
||||
vty_out(vty, "gbproxy%s", VTY_NEWLINE);
|
||||
|
||||
if (g_cfg->pool.bvc_fc_ratio != 100)
|
||||
vty_out(vty, " pool bvc-flow-control-ratio %u%s", g_cfg->pool.bvc_fc_ratio, VTY_NEWLINE);
|
||||
|
||||
hash_for_each(g_cfg->sgsn_nses, i, nse, list) {
|
||||
vty_out(vty, " sgsn nsei %u%s", nse->nsei, VTY_NEWLINE);
|
||||
}
|
||||
|
@ -134,6 +137,17 @@ free_nothing:
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
DEFUN(cfg_pool_bvc_fc_ratio,
|
||||
cfg_pool_bvc_fc_ratio_cmd,
|
||||
"pool bvc-flow-control-ratio <1-100>",
|
||||
"SGSN Pool related configuration\n"
|
||||
"Ratio of BSS-advertised bucket size + leak rate advertised to each SGSN\n"
|
||||
"Ratio of BSS-advertised bucket size + leak rate advertised to each SGSN (Percent)\n")
|
||||
{
|
||||
g_cfg->pool.bvc_fc_ratio = atoi(argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void log_set_bvc_filter(struct log_target *target,
|
||||
const uint16_t *bvci)
|
||||
{
|
||||
|
@ -315,6 +329,7 @@ int gbproxy_vty_init(void)
|
|||
install_element(CONFIG_NODE, &cfg_gbproxy_cmd);
|
||||
install_node(&gbproxy_node, config_write_gbproxy);
|
||||
install_element(GBPROXY_NODE, &cfg_nsip_sgsn_nsei_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_pool_bvc_fc_ratio_cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue