implement all_allocated:{sdcch,tch} rate counters

Based on allAvailable{SDCCH,TCH}Allocated performance indicators, see
3GPP TS 52.402.

Related: SYS#4878
Related: Ib3997a827c9cc43d1361bb0cf3bfab9f6d91bf82 (osmo-ttcn3-hacks)
Change-Id: I8b06e435a224c8708cd6c67e97ee5413718fc1ed
This commit is contained in:
Neels Hofmeyr 2021-09-27 08:56:20 +02:00 committed by neels
parent e0458c2e00
commit 41f143827d
9 changed files with 137 additions and 0 deletions

View File

@ -81,6 +81,8 @@ enum {
BSC_CTR_MSCPOOL_SUBSCR_NO_MSC,
BSC_CTR_MSCPOOL_EMERG_FORWARDED,
BSC_CTR_MSCPOOL_EMERG_LOST,
BSC_CTR_ALL_ALLOCATED_SDCCH,
BSC_CTR_ALL_ALLOCATED_TCH,
};
extern const struct rate_ctr_desc bsc_ctr_description[];
@ -105,3 +107,4 @@ enum {
extern const struct osmo_stat_item_group_desc bsc_statg_desc;
void bsc_update_connection_stats(struct gsm_network *net);
void bsc_update_time_cc_all_allocated(struct gsm_network *net);

View File

@ -158,6 +158,8 @@ enum bts_counter_id {
BTS_CTR_SRVCC_TIMEOUT,
BTS_CTR_SRVCC_FAILED,
BTS_CTR_SRVCC_ERROR,
BTS_CTR_ALL_ALLOCATED_SDCCH,
BTS_CTR_ALL_ALLOCATED_TCH,
};
extern const struct rate_ctr_desc bts_ctr_description[];
@ -590,6 +592,9 @@ struct gsm_bts {
/* At what point in the channel allocation sequence to dispatch the Immediate Assignment (Abis optimization) */
enum imm_ass_time imm_ass_time;
struct time_cc all_allocated_sdcch;
struct time_cc all_allocated_tch;
};
#define GSM_BTS_SI2Q(bts, i) (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])

View File

@ -32,6 +32,7 @@
#include <osmocom/bsc/meas_rep.h>
#include <osmocom/bsc/acc.h>
#include <osmocom/bsc/osmux.h>
#include <osmocom/bsc/time_cc.h>
#define GSM_T3122_DEFAULT 10
@ -1260,6 +1261,9 @@ struct gsm_network {
struct osmo_nri_ranges *null_nri_ranges;
struct smlc_config *smlc;
struct time_cc all_allocated_sdcch;
struct time_cc all_allocated_tch;
};
struct gsm_audio_support {

View File

@ -120,6 +120,29 @@ static struct gsm_network *bsc_network_init(void *ctx)
if (!net->bts_unknown_statg)
goto err_free_all;
net->all_allocated_sdcch = (struct time_cc){
.cfg = {
.gran_usec = 1*1000000,
.forget_sum_usec = 60*1000000,
.rate_ctr = rate_ctr_group_get_ctr(net->bsc_ctrs, BSC_CTR_ALL_ALLOCATED_SDCCH),
.T_gran = -16,
.T_round_threshold = -17,
.T_forget_sum = -18,
.T_defs = net->T_defs,
},
};
net->all_allocated_tch = (struct time_cc){
.cfg = {
.gran_usec = 1*1000000,
.forget_sum_usec = 60*1000000,
.rate_ctr = rate_ctr_group_get_ctr(net->bsc_ctrs, BSC_CTR_ALL_ALLOCATED_TCH),
.T_gran = -16,
.T_round_threshold = -17,
.T_forget_sum = -18,
.T_defs = net->T_defs,
},
};
INIT_LLIST_HEAD(&net->bts_rejected);
gsm_net_update_ctype(net);

View File

@ -25,6 +25,7 @@
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/bts.h>
#include <osmocom/bsc/chan_counts.h>
const struct rate_ctr_desc bsc_ctr_description[] = {
[BSC_CTR_ASSIGNMENT_ATTEMPTED] = {"assignment:attempted", "Assignment attempts"},
@ -102,6 +103,8 @@ const struct rate_ctr_desc bsc_ctr_description[] = {
"Emergency call requests forwarded to an MSC (see also per-MSC counters"},
[BSC_CTR_MSCPOOL_EMERG_LOST] = {"mscpool:emerg:lost",
"Emergency call requests lost because no MSC was found available"},
[BSC_CTR_ALL_ALLOCATED_SDCCH] = {"all_allocated:sdcch", "Cumulative counter of seconds where all SDCCH channels were allocated"},
[BSC_CTR_ALL_ALLOCATED_TCH] = {"all_allocated:tch", "Cumulative counter of seconds where all TCH channels were allocated"},
};
const struct rate_ctr_group_desc bsc_ctrg_desc = {
@ -185,4 +188,49 @@ void bsc_update_connection_stats(struct gsm_network *net)
osmo_stat_item_set(osmo_stat_item_group_get_item(net->bsc_statg, BSC_STAT_NUM_TRX_RSL_CONNECTED),
trx_rsl_connected_total);
osmo_stat_item_set(osmo_stat_item_group_get_item(net->bsc_statg, BSC_STAT_NUM_TRX_TOTAL), num_trx_total);
/* Make sure to notice cells that become disconnected */
bsc_update_time_cc_all_allocated(net);
}
void bsc_update_time_cc_all_allocated(struct gsm_network *net)
{
struct gsm_bts *bts;
struct gsm_bts_trx *trx;
struct chan_counts bsc_counts;
chan_counts_zero(&bsc_counts);
llist_for_each_entry(bts, &net->bts_list, list) {
struct chan_counts bts_counts;
chan_counts_zero(&bts_counts);
llist_for_each_entry(trx, &bts->trx_list, list) {
struct chan_counts trx_counts;
chan_counts_for_trx(&trx_counts, trx);
chan_counts_add(&bts_counts, &trx_counts);
}
time_cc_set_flag(&bts->all_allocated_sdcch,
bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_SDCCH]
&& !bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_SDCCH]);
time_cc_set_flag(&bts->all_allocated_tch,
(bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_F]
+ bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_H])
&& !(bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F]
+ bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H]));
chan_counts_add(&bsc_counts, &bts_counts);
}
time_cc_set_flag(&net->all_allocated_sdcch,
bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_SDCCH]
&& !bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_SDCCH]);
time_cc_set_flag(&net->all_allocated_tch,
(bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_F]
+ bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_H])
&& !(bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F]
+ bsc_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H]));
}

View File

@ -211,6 +211,29 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, struct gsm_bts_sm *bts_sm
}
bts->bts_statg = osmo_stat_item_group_alloc(bts, &bts_statg_desc, bts->nr);
bts->all_allocated_sdcch = (struct time_cc){
.cfg = {
.gran_usec = 1*1000000,
.forget_sum_usec = 60*1000000,
.rate_ctr = rate_ctr_group_get_ctr(bts->bts_ctrs, BTS_CTR_ALL_ALLOCATED_SDCCH),
.T_gran = -16,
.T_round_threshold = -17,
.T_forget_sum = -18,
.T_defs = net->T_defs,
},
};
bts->all_allocated_tch = (struct time_cc){
.cfg = {
.gran_usec = 1*1000000,
.forget_sum_usec = 60*1000000,
.rate_ctr = rate_ctr_group_get_ctr(bts->bts_ctrs, BTS_CTR_ALL_ALLOCATED_TCH),
.T_gran = -16,
.T_round_threshold = -17,
.T_forget_sum = -18,
.T_defs = net->T_defs,
},
};
/* create our primary TRX */
bts->c0 = gsm_bts_trx_alloc(bts);
if (!bts->c0) {
@ -1236,6 +1259,12 @@ const struct rate_ctr_desc bts_ctr_description[] = {
[BTS_CTR_SRVCC_ERROR] = \
{ "srvcc:error",
"Re-assignment failed for other reason" },
[BTS_CTR_ALL_ALLOCATED_SDCCH] = \
{ "all_allocated:sdcch",
"Cumulative counter of seconds where all SDCCH channels were allocated" },
[BTS_CTR_ALL_ALLOCATED_TCH] = \
{ "all_allocated:tch",
"Cumulative counter of seconds where all TCH channels were allocated" },
};
const struct rate_ctr_group_desc bts_ctrg_desc = {

View File

@ -40,6 +40,7 @@
#include <osmocom/bsc/bsc_msc_data.h>
#include <osmocom/bsc/codec_pref.h>
#include <osmocom/bsc/bts.h>
#include <osmocom/bsc/bsc_stats.h>
static struct osmo_fsm lchan_fsm;
@ -517,6 +518,8 @@ static void lchan_fsm_unused_onenter(struct osmo_fsm_inst *fi, uint32_t prev_sta
lchan_reset(lchan);
osmo_fsm_inst_dispatch(lchan->ts->fi, TS_EV_LCHAN_UNUSED, lchan);
bsc_update_time_cc_all_allocated(bts->network);
/* Poll the channel request queue, so that waiting calls can make use of the lchan that just
* has become unused now. */
abis_rsl_chan_rqd_queue_poll(bts);
@ -697,6 +700,8 @@ static void lchan_fsm_wait_ts_ready_onenter(struct osmo_fsm_inst *fi, uint32_t p
return;
}
bsc_update_time_cc_all_allocated(bts->network);
lchan->conn = info->for_conn;
/* If there is a previous lchan, and the new lchan is on the same cell as previous one,

View File

@ -56,6 +56,20 @@ static struct osmo_tdef gsm_network_T_defs[] = {
{ .T=-12, .default_val=5, .desc="Timeout for obtaining TA after BSSLAP TA Request" },
{ .T=-13, .default_val=5, .desc="Timeout for RR Channel Mode Modify ACK (BSC <-> MS)" },
{ .T=-14, .default_val=5, .desc="Timeout for RSL Channel Mode Modify ACK (BSC <-> BTS)" },
{ .T = -16, .default_val = 1000, .unit = OSMO_TDEF_MS,
.desc = "Granularity for all_allocated:* rate counters: amount of milliseconds that one counter increment"
" represents. See also X17, X18" },
{ .T = -17, .default_val = 0, .unit = OSMO_TDEF_MS,
.desc = "Rounding threshold for all_allocated:* rate counters: round up to the next counter increment"
" after this many milliseconds. If set to half of X16 (or 0), employ the usual round() behavior:"
" round up after half of a granularity period. If set to 1, behave like ceil(): already"
" increment the counter immediately when all channels are allocated. If set >= X16, behave like"
" floor(): only increment after a full X16 period of all channels being occupied."
" See also X16, X18" },
{ .T = -18, .default_val = 60000, .unit = OSMO_TDEF_MS,
.desc = "Forget-sum period for all_allocated:* rate counters:"
" after this amount of idle time, forget internally cumulated time remainders. Zero to always"
" keep remainders. See also X16, X17." },
{ .T=-3111, .default_val=4, .desc="Wait time after lchan was released in error (should be T3111 + 2s)" },
{ .T=-3210, .default_val=20, .desc="After L3 Complete, wait for MSC to confirm" },
{}

View File

@ -29,6 +29,9 @@ net: X11 = 5 s Timeout for Perform Location Response from SMLC (default: 5 s)
net: X12 = 5 s Timeout for obtaining TA after BSSLAP TA Request (default: 5 s)
net: X13 = 5 s Timeout for RR Channel Mode Modify ACK (BSC <-> MS) (default: 5 s)
net: X14 = 5 s Timeout for RSL Channel Mode Modify ACK (BSC <-> BTS) (default: 5 s)
net: X16 = 1000 ms Granularity for all_allocated:* rate counters: amount of milliseconds that one counter increment represents. See also X17, X18 (default: 1000 ms)
net: X17 = 0 ms Rounding threshold for all_allocated:* rate counters: round up to the next counter increment after this many milliseconds. If set to half of X16 (or 0), employ the usual round() behavior: round up after half of a granularity period. If set to 1, behave like ceil(): already increment the counter immediately when all channels are allocated. If set >= X16, behave like floor(): only increment after a full X16 period of all channels being occupied. See also X16, X18 (default: 0 ms)
net: X18 = 60000 ms Forget-sum period for all_allocated:* rate counters: after this amount of idle time, forget internally cumulated time remainders. Zero to always keep remainders. See also X16, X17. (default: 60000 ms)
net: X3111 = 4 s Wait time after lchan was released in error (should be T3111 + 2s) (default: 4 s)
net: X3210 = 20 s After L3 Complete, wait for MSC to confirm (default: 20 s)
mgw: X2427 = 5 s timeout for MGCP response from MGW (default: 5 s)
@ -78,6 +81,9 @@ net: X11 = 5 s Timeout for Perform Location Response from SMLC (default: 5 s)
net: X12 = 5 s Timeout for obtaining TA after BSSLAP TA Request (default: 5 s)
net: X13 = 5 s Timeout for RR Channel Mode Modify ACK (BSC <-> MS) (default: 5 s)
net: X14 = 5 s Timeout for RSL Channel Mode Modify ACK (BSC <-> BTS) (default: 5 s)
net: X16 = 1000 ms Granularity for all_allocated:* rate counters: amount of milliseconds that one counter increment represents. See also X17, X18 (default: 1000 ms)
net: X17 = 0 ms Rounding threshold for all_allocated:* rate counters: round up to the next counter increment after this many milliseconds. If set to half of X16 (or 0), employ the usual round() behavior: round up after half of a granularity period. If set to 1, behave like ceil(): already increment the counter immediately when all channels are allocated. If set >= X16, behave like floor(): only increment after a full X16 period of all channels being occupied. See also X16, X18 (default: 0 ms)
net: X18 = 60000 ms Forget-sum period for all_allocated:* rate counters: after this amount of idle time, forget internally cumulated time remainders. Zero to always keep remainders. See also X16, X17. (default: 60000 ms)
net: X3111 = 4 s Wait time after lchan was released in error (should be T3111 + 2s) (default: 4 s)
net: X3210 = 20 s After L3 Complete, wait for MSC to confirm (default: 20 s)
mgw: X2427 = 5 s timeout for MGCP response from MGW (default: 5 s)