2021-08-29 11:18:40 +00:00
|
|
|
/* osmo-bsc statistics */
|
|
|
|
/* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
|
|
|
* All Rights Reserved
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Affero General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <osmocom/bsc/bsc_stats.h>
|
|
|
|
|
|
|
|
#include <osmocom/core/utils.h>
|
|
|
|
#include <osmocom/core/stats.h>
|
|
|
|
#include <osmocom/core/stat_item.h>
|
|
|
|
|
2021-08-29 11:31:05 +00:00
|
|
|
#include <osmocom/bsc/gsm_data.h>
|
|
|
|
#include <osmocom/bsc/bts.h>
|
2021-09-27 06:56:20 +00:00
|
|
|
#include <osmocom/bsc/chan_counts.h>
|
2021-08-29 11:31:05 +00:00
|
|
|
|
2021-08-29 11:18:40 +00:00
|
|
|
const struct rate_ctr_desc bsc_ctr_description[] = {
|
|
|
|
[BSC_CTR_ASSIGNMENT_ATTEMPTED] = {"assignment:attempted", "Assignment attempts"},
|
|
|
|
[BSC_CTR_ASSIGNMENT_COMPLETED] = {"assignment:completed", "Assignment completed"},
|
|
|
|
[BSC_CTR_ASSIGNMENT_STOPPED] = {"assignment:stopped", "Connection ended during Assignment"},
|
|
|
|
[BSC_CTR_ASSIGNMENT_NO_CHANNEL] = {"assignment:no_channel", "Failure to allocate lchan for Assignment"},
|
|
|
|
[BSC_CTR_ASSIGNMENT_TIMEOUT] = {"assignment:timeout", "Assignment timed out"},
|
|
|
|
[BSC_CTR_ASSIGNMENT_FAILED] = {"assignment:failed", "Received Assignment Failure message"},
|
|
|
|
[BSC_CTR_ASSIGNMENT_ERROR] = {"assignment:error", "Assignment failed for other reason"},
|
|
|
|
|
2021-11-02 12:26:54 +00:00
|
|
|
[BSC_CTR_HANDOVER_ATTEMPTED] = {"handover:attempted", "Handover attempts"},
|
|
|
|
[BSC_CTR_HANDOVER_COMPLETED] = {"handover:completed", "Handover completed"},
|
2021-08-29 11:18:40 +00:00
|
|
|
[BSC_CTR_HANDOVER_STOPPED] = {"handover:stopped", "Connection ended during HO"},
|
|
|
|
[BSC_CTR_HANDOVER_NO_CHANNEL] = {"handover:no_channel", "Failure to allocate lchan for HO"},
|
|
|
|
[BSC_CTR_HANDOVER_TIMEOUT] = {"handover:timeout", "Handover timed out"},
|
|
|
|
[BSC_CTR_HANDOVER_FAILED] = {"handover:failed", "Received Handover Fail messages"},
|
2021-11-02 12:26:54 +00:00
|
|
|
[BSC_CTR_HANDOVER_ERROR] = {"handover:error", "Handover failed for other reason"},
|
2021-08-29 11:18:40 +00:00
|
|
|
|
|
|
|
[BSC_CTR_INTRA_CELL_HO_ATTEMPTED] = {"intra_cell_ho:attempted", "Intra-Cell handover attempts"},
|
|
|
|
[BSC_CTR_INTRA_CELL_HO_COMPLETED] = {"intra_cell_ho:completed", "Intra-Cell handover completed"},
|
|
|
|
[BSC_CTR_INTRA_CELL_HO_STOPPED] = {"intra_cell_ho:stopped", "Connection ended during HO"},
|
|
|
|
[BSC_CTR_INTRA_CELL_HO_NO_CHANNEL] = {"intra_cell_ho:no_channel", "Failure to allocate lchan for HO"},
|
|
|
|
[BSC_CTR_INTRA_CELL_HO_TIMEOUT] = {"intra_cell_ho:timeout", "Handover timed out"},
|
|
|
|
[BSC_CTR_INTRA_CELL_HO_FAILED] = {"intra_cell_ho:failed", "Received Handover Fail messages"},
|
2021-11-02 12:26:54 +00:00
|
|
|
[BSC_CTR_INTRA_CELL_HO_ERROR] = {"intra_cell_ho:error", "Intra-cell handover failed for other reason"},
|
2021-08-29 11:18:40 +00:00
|
|
|
|
2021-11-02 12:26:54 +00:00
|
|
|
[BSC_CTR_INTRA_BSC_HO_ATTEMPTED] = {"intra_bsc_ho:attempted", "Intra-BSC inter-cell handover attempts"},
|
|
|
|
[BSC_CTR_INTRA_BSC_HO_COMPLETED] = {"intra_bsc_ho:completed", "Intra-BSC inter-cell handover completed"},
|
2021-08-29 11:18:40 +00:00
|
|
|
[BSC_CTR_INTRA_BSC_HO_STOPPED] = {"intra_bsc_ho:stopped", "Connection ended during HO"},
|
|
|
|
[BSC_CTR_INTRA_BSC_HO_NO_CHANNEL] = {"intra_bsc_ho:no_channel", "Failure to allocate lchan for HO"},
|
|
|
|
[BSC_CTR_INTRA_BSC_HO_TIMEOUT] = {"intra_bsc_ho:timeout", "Handover timed out"},
|
|
|
|
[BSC_CTR_INTRA_BSC_HO_FAILED] = {"intra_bsc_ho:failed", "Received Handover Fail messages"},
|
2021-11-02 12:26:54 +00:00
|
|
|
[BSC_CTR_INTRA_BSC_HO_ERROR] = {"intra_bsc_ho:error", "Intra-BSC inter-cell HO failed for other reason"},
|
2021-08-29 11:18:40 +00:00
|
|
|
|
|
|
|
[BSC_CTR_INTER_BSC_HO_OUT_ATTEMPTED] = {"interbsc_ho_out:attempted",
|
|
|
|
"Attempts to handover to remote BSS"},
|
|
|
|
[BSC_CTR_INTER_BSC_HO_OUT_COMPLETED] = {"interbsc_ho_out:completed",
|
|
|
|
"Handover to remote BSS completed"},
|
|
|
|
[BSC_CTR_INTER_BSC_HO_OUT_STOPPED] = {"interbsc_ho_out:stopped", "Connection ended during HO"},
|
|
|
|
[BSC_CTR_INTER_BSC_HO_OUT_TIMEOUT] = {"interbsc_ho_out:timeout", "Handover timed out"},
|
|
|
|
[BSC_CTR_INTER_BSC_HO_OUT_FAILED] = {"interbsc_ho_out:failed", "Received Handover Fail message"},
|
|
|
|
[BSC_CTR_INTER_BSC_HO_OUT_ERROR] = {"interbsc_ho_out:error",
|
|
|
|
"Handover to remote BSS failed for other reason"},
|
|
|
|
|
|
|
|
[BSC_CTR_INTER_BSC_HO_IN_ATTEMPTED] = {"interbsc_ho_in:attempted",
|
|
|
|
"Attempts to handover from remote BSS"},
|
|
|
|
[BSC_CTR_INTER_BSC_HO_IN_COMPLETED] = {"interbsc_ho_in:completed",
|
|
|
|
"Handover from remote BSS completed"},
|
|
|
|
[BSC_CTR_INTER_BSC_HO_IN_STOPPED] = {"interbsc_ho_in:stopped", "Connection ended during HO"},
|
|
|
|
[BSC_CTR_INTER_BSC_HO_IN_NO_CHANNEL] = {"interbsc_ho_in:no_channel",
|
|
|
|
"Failure to allocate lchan for HO"},
|
|
|
|
[BSC_CTR_INTER_BSC_HO_IN_TIMEOUT] = {"interbsc_ho_in:timeout", "Handover from remote BSS timed out"},
|
|
|
|
[BSC_CTR_INTER_BSC_HO_IN_FAILED] = {"interbsc_ho_in:failed", "Received Handover Fail message"},
|
|
|
|
[BSC_CTR_INTER_BSC_HO_IN_ERROR] = {"interbsc_ho_in:error",
|
|
|
|
"Handover from remote BSS failed for other reason"},
|
|
|
|
|
|
|
|
[BSC_CTR_SRVCC_ATTEMPTED] = {"srvcc:attempted", "Intra-BSC SRVCC attempts"},
|
|
|
|
[BSC_CTR_SRVCC_COMPLETED] = {"srvcc:completed", "Intra-BSC SRVCC completed"},
|
|
|
|
[BSC_CTR_SRVCC_STOPPED] = {"srvcc:stopped", "Connection ended during HO"},
|
|
|
|
[BSC_CTR_SRVCC_NO_CHANNEL] = {"srvcc:no_channel", "Failure to allocate lchan for HO"},
|
|
|
|
[BSC_CTR_SRVCC_TIMEOUT] = {"srvcc:timeout", "SRVCC timed out"},
|
|
|
|
[BSC_CTR_SRVCC_FAILED] = {"srvcc:failed", "Received SRVCC Fail messages"},
|
|
|
|
[BSC_CTR_SRVCC_ERROR] = {"srvcc:error", "Re-assignment failed for other reason"},
|
|
|
|
|
|
|
|
[BSC_CTR_PAGING_ATTEMPTED] = {"paging:attempted", "Paging attempts for a subscriber"},
|
|
|
|
[BSC_CTR_PAGING_DETACHED] = {"paging:detached", "Paging request send failures because no responsible BTS was found"},
|
|
|
|
[BSC_CTR_PAGING_RESPONDED] = {"paging:responded", "Paging attempts with successful response"},
|
2021-11-25 11:14:09 +00:00
|
|
|
[BSC_CTR_PAGING_EXPIRED] = {"paging:expired", "Paging Request expired because of timeout T3113"},
|
2021-08-29 11:18:40 +00:00
|
|
|
[BSC_CTR_PAGING_NO_ACTIVE_PAGING] = {"paging:no_active_paging", "Paging response without an active paging request (arrived after paging expiration?)"},
|
|
|
|
|
|
|
|
[BSC_CTR_UNKNOWN_UNIT_ID] = {"abis:unknown_unit_id", "Connection attempts from unknown IPA CCM Unit ID"},
|
|
|
|
|
|
|
|
[BSC_CTR_MSCPOOL_SUBSCR_NO_MSC] = {"mscpool:subscr:no_msc",
|
|
|
|
"Complete Layer 3 requests lost because no connected MSC is found available"},
|
|
|
|
[BSC_CTR_MSCPOOL_EMERG_FORWARDED] = {"mscpool:emerg:forwarded",
|
|
|
|
"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"},
|
2021-09-27 06:56:20 +00:00
|
|
|
[BSC_CTR_ALL_ALLOCATED_SDCCH] = {"all_allocated:sdcch", "Cumulative counter of seconds where all SDCCH channels were allocated"},
|
2021-09-27 06:56:20 +00:00
|
|
|
[BSC_CTR_ALL_ALLOCATED_STATIC_SDCCH] = {"all_allocated:static_sdcch",
|
|
|
|
"Cumulative counter of seconds where all non-dynamic SDCCH channels were allocated"},
|
2021-09-27 06:56:20 +00:00
|
|
|
[BSC_CTR_ALL_ALLOCATED_TCH] = {"all_allocated:tch", "Cumulative counter of seconds where all TCH channels were allocated"},
|
2021-09-27 06:56:20 +00:00
|
|
|
[BSC_CTR_ALL_ALLOCATED_STATIC_TCH] = {"all_allocated:static_tch",
|
|
|
|
"Cumulative counter of seconds where all non-dynamic TCH channels were allocated"},
|
2021-08-29 11:18:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const struct rate_ctr_group_desc bsc_ctrg_desc = {
|
|
|
|
"bsc",
|
|
|
|
"base station controller",
|
|
|
|
OSMO_STATS_CLASS_GLOBAL,
|
|
|
|
ARRAY_SIZE(bsc_ctr_description),
|
|
|
|
bsc_ctr_description,
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct osmo_stat_item_desc bsc_stat_desc[] = {
|
2021-08-29 11:31:05 +00:00
|
|
|
[BSC_STAT_NUM_BTS_OML_CONNECTED] = { "num_bts:oml_connected", "Number of BTS for this BSC where OML is up", "", 16, 0 },
|
|
|
|
[BSC_STAT_NUM_BTS_ALL_TRX_RSL_CONNECTED] = { "num_bts:all_trx_rsl_connected", "Number of BTS for this BSC where RSL is up for all TRX", "", 16, 0 },
|
2021-08-29 11:18:40 +00:00
|
|
|
[BSC_STAT_NUM_BTS_TOTAL] = { "num_bts:total", "Number of configured BTS for this BSC", "", 16, 0 },
|
2021-08-29 11:31:05 +00:00
|
|
|
[BSC_STAT_NUM_TRX_RSL_CONNECTED] = { "num_trx:rsl_connected", "Number of TRX where RSL is up, total sum across all BTS", "", 16, 0 },
|
|
|
|
[BSC_STAT_NUM_TRX_TOTAL] = { "num_trx:total", "Number of configured TRX, total sum across all BTS", "", 1, 0 },
|
2021-08-19 17:04:14 +00:00
|
|
|
[BSC_STAT_NUM_MSC_CONNECTED] = { "num_msc:connected", "Number of actively connected MSCs", "", 16, 0 },
|
|
|
|
[BSC_STAT_NUM_MSC_TOTAL] = { "num_msc:total", "Number of configured MSCs, not necessarily connected", "", 1, 0 },
|
2021-08-29 11:18:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const struct osmo_stat_item_group_desc bsc_statg_desc = {
|
|
|
|
.group_name_prefix = "bsc",
|
|
|
|
.group_description = "base station controller",
|
|
|
|
.class_id = OSMO_STATS_CLASS_GLOBAL,
|
|
|
|
.num_items = ARRAY_SIZE(bsc_stat_desc),
|
|
|
|
.item_desc = bsc_stat_desc,
|
|
|
|
};
|
2021-08-29 11:31:05 +00:00
|
|
|
|
|
|
|
/* Count all BTS and TRX OML and RSL stati and update stat items */
|
|
|
|
void bsc_update_connection_stats(struct gsm_network *net)
|
|
|
|
{
|
|
|
|
struct gsm_bts *bts;
|
|
|
|
struct gsm_bts_trx *trx;
|
|
|
|
|
|
|
|
/* Nr of configured BTS and total sum of configured TRX across all BTS */
|
|
|
|
int num_bts = 0;
|
|
|
|
int num_trx_total = 0;
|
|
|
|
/* Nr of BTS where OML is up */
|
|
|
|
int bts_oml_connected = 0;
|
|
|
|
/* Nr of TRX across all BTS where RSL is up */
|
|
|
|
int trx_rsl_connected_total = 0;
|
|
|
|
/* Nr of BTS that have all TRX RSL up */
|
|
|
|
int bts_rsl_all_trx_connected = 0;
|
|
|
|
|
|
|
|
llist_for_each_entry(bts, &net->bts_list, list) {
|
|
|
|
bool oml_connected = false;
|
|
|
|
int num_trx = 0;
|
|
|
|
int trx_rsl_connected = 0;
|
|
|
|
|
|
|
|
llist_for_each_entry(trx, &bts->trx_list, list) {
|
|
|
|
/* If any one trx is usable, it means OML for this BTS is connected */
|
|
|
|
if (trx_is_usable(trx))
|
|
|
|
oml_connected = true;
|
|
|
|
|
|
|
|
/* Count nr of TRX for this BTS */
|
|
|
|
num_trx++;
|
|
|
|
if (trx->ts[0].is_rsl_ready)
|
|
|
|
trx_rsl_connected++;
|
|
|
|
}
|
|
|
|
|
2021-09-19 11:14:10 +00:00
|
|
|
osmo_stat_item_set(osmo_stat_item_group_get_item(bts->bts_statg, BTS_STAT_NUM_TRX_RSL_CONNECTED),
|
|
|
|
trx_rsl_connected);
|
2021-09-19 11:13:45 +00:00
|
|
|
osmo_stat_item_set(osmo_stat_item_group_get_item(bts->bts_statg, BTS_STAT_NUM_TRX_TOTAL),
|
|
|
|
num_trx);
|
|
|
|
|
2021-08-29 11:31:05 +00:00
|
|
|
num_trx_total += num_trx;
|
|
|
|
trx_rsl_connected_total += trx_rsl_connected;
|
|
|
|
|
|
|
|
num_bts++;
|
|
|
|
if (oml_connected)
|
|
|
|
bts_oml_connected++;
|
|
|
|
if (trx_rsl_connected == num_trx)
|
|
|
|
bts_rsl_all_trx_connected++;
|
fix performance for chan_counts and all_allocated stats
The all_allocated_update_bsc() does inefficient iterating to count
active/inactive lchans, which scales badly for high numbers of TRX
managed by osmo-bsc.
We need to update the all_allocated flags immediately (periodic counting
alone would suffer from undersampling), so, until now, we are calling
this inefficient function every time a channel state changes.
Instead of iterating all channels for any chan state changes anywhere,
keep global state of the current channel counts, and on channel state
change only update those ts, trx, bts counts that actually change.
A desirable side effect: for connection stats and handover decision 2,
we can now also use the globally updated channel counts and save a bunch
of inefficient iterations.
To get accurate channel counts at all times, spread around some
chan_counts_ts_update() calls in pivotal places. It re-counts the given
timeslot and cascades counter changes, iff required.
Just in case I missed some channel accounting, still run an inefficient
iterating count regularly that detects errors, logs them and fixes them.
No real harm done if such error appears. None show in ttcn3 BSC_Tests.
It is fine to do the inefficient iteration once per second; channel
state changes can realistically happen hundreds of times per second.
Related: SYS#5976
Change-Id: I580bfae329aac8d4552723164741536af6512011
2022-05-30 00:39:17 +00:00
|
|
|
|
|
|
|
all_allocated_update_bts(bts);
|
2021-08-29 11:31:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
osmo_stat_item_set(osmo_stat_item_group_get_item(net->bsc_statg, BSC_STAT_NUM_BTS_OML_CONNECTED),
|
|
|
|
bts_oml_connected);
|
|
|
|
osmo_stat_item_set(osmo_stat_item_group_get_item(net->bsc_statg, BSC_STAT_NUM_BTS_ALL_TRX_RSL_CONNECTED),
|
|
|
|
bts_rsl_all_trx_connected);
|
|
|
|
osmo_stat_item_set(osmo_stat_item_group_get_item(net->bsc_statg, BSC_STAT_NUM_BTS_TOTAL), num_bts);
|
|
|
|
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);
|
2021-09-27 06:56:20 +00:00
|
|
|
|
fix performance for chan_counts and all_allocated stats
The all_allocated_update_bsc() does inefficient iterating to count
active/inactive lchans, which scales badly for high numbers of TRX
managed by osmo-bsc.
We need to update the all_allocated flags immediately (periodic counting
alone would suffer from undersampling), so, until now, we are calling
this inefficient function every time a channel state changes.
Instead of iterating all channels for any chan state changes anywhere,
keep global state of the current channel counts, and on channel state
change only update those ts, trx, bts counts that actually change.
A desirable side effect: for connection stats and handover decision 2,
we can now also use the globally updated channel counts and save a bunch
of inefficient iterations.
To get accurate channel counts at all times, spread around some
chan_counts_ts_update() calls in pivotal places. It re-counts the given
timeslot and cascades counter changes, iff required.
Just in case I missed some channel accounting, still run an inefficient
iterating count regularly that detects errors, logs them and fixes them.
No real harm done if such error appears. None show in ttcn3 BSC_Tests.
It is fine to do the inefficient iteration once per second; channel
state changes can realistically happen hundreds of times per second.
Related: SYS#5976
Change-Id: I580bfae329aac8d4552723164741536af6512011
2022-05-30 00:39:17 +00:00
|
|
|
/* This is optional, just running this to catch bugs in chan_counts accounting. If there is a bug, there will be
|
|
|
|
* a DLGLOBAL ERROR logged, and the error gets fixed. */
|
|
|
|
chan_counts_bsc_verify();
|
2021-09-27 06:56:20 +00:00
|
|
|
}
|
|
|
|
|
2022-05-29 21:57:59 +00:00
|
|
|
static void all_allocated_update(struct all_allocated *all_allocated, const struct chan_counts *c)
|
2021-09-27 06:56:20 +00:00
|
|
|
{
|
2022-05-29 21:57:59 +00:00
|
|
|
osmo_time_cc_set_flag(&all_allocated->sdcch,
|
|
|
|
c->val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_SDCCH]
|
|
|
|
&& !c->val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_SDCCH]);
|
|
|
|
|
|
|
|
osmo_time_cc_set_flag(&all_allocated->static_sdcch,
|
|
|
|
c->val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_SDCCH]
|
|
|
|
&& !c->val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_SDCCH]);
|
|
|
|
|
|
|
|
osmo_time_cc_set_flag(&all_allocated->tch,
|
|
|
|
(c->val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_F]
|
|
|
|
+ c->val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_H])
|
|
|
|
&& !(c->val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F]
|
|
|
|
+ c->val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H]));
|
|
|
|
|
|
|
|
osmo_time_cc_set_flag(&all_allocated->static_tch,
|
|
|
|
(c->val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_F]
|
|
|
|
+ c->val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_MAX_TOTAL][GSM_LCHAN_TCH_H])
|
|
|
|
&& !(c->val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F]
|
|
|
|
+ c->val[CHAN_COUNTS1_STATIC][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H]));
|
|
|
|
}
|
2021-09-27 06:56:20 +00:00
|
|
|
|
fix performance for chan_counts and all_allocated stats
The all_allocated_update_bsc() does inefficient iterating to count
active/inactive lchans, which scales badly for high numbers of TRX
managed by osmo-bsc.
We need to update the all_allocated flags immediately (periodic counting
alone would suffer from undersampling), so, until now, we are calling
this inefficient function every time a channel state changes.
Instead of iterating all channels for any chan state changes anywhere,
keep global state of the current channel counts, and on channel state
change only update those ts, trx, bts counts that actually change.
A desirable side effect: for connection stats and handover decision 2,
we can now also use the globally updated channel counts and save a bunch
of inefficient iterations.
To get accurate channel counts at all times, spread around some
chan_counts_ts_update() calls in pivotal places. It re-counts the given
timeslot and cascades counter changes, iff required.
Just in case I missed some channel accounting, still run an inefficient
iterating count regularly that detects errors, logs them and fixes them.
No real harm done if such error appears. None show in ttcn3 BSC_Tests.
It is fine to do the inefficient iteration once per second; channel
state changes can realistically happen hundreds of times per second.
Related: SYS#5976
Change-Id: I580bfae329aac8d4552723164741536af6512011
2022-05-30 00:39:17 +00:00
|
|
|
void all_allocated_update_bts(struct gsm_bts *bts)
|
|
|
|
{
|
|
|
|
all_allocated_update(&bts->all_allocated, &bts->chan_counts);
|
|
|
|
}
|
|
|
|
|
2022-05-29 21:57:59 +00:00
|
|
|
void all_allocated_update_bsc()
|
|
|
|
{
|
|
|
|
struct gsm_network *net = bsc_gsmnet;
|
fix performance for chan_counts and all_allocated stats
The all_allocated_update_bsc() does inefficient iterating to count
active/inactive lchans, which scales badly for high numbers of TRX
managed by osmo-bsc.
We need to update the all_allocated flags immediately (periodic counting
alone would suffer from undersampling), so, until now, we are calling
this inefficient function every time a channel state changes.
Instead of iterating all channels for any chan state changes anywhere,
keep global state of the current channel counts, and on channel state
change only update those ts, trx, bts counts that actually change.
A desirable side effect: for connection stats and handover decision 2,
we can now also use the globally updated channel counts and save a bunch
of inefficient iterations.
To get accurate channel counts at all times, spread around some
chan_counts_ts_update() calls in pivotal places. It re-counts the given
timeslot and cascades counter changes, iff required.
Just in case I missed some channel accounting, still run an inefficient
iterating count regularly that detects errors, logs them and fixes them.
No real harm done if such error appears. None show in ttcn3 BSC_Tests.
It is fine to do the inefficient iteration once per second; channel
state changes can realistically happen hundreds of times per second.
Related: SYS#5976
Change-Id: I580bfae329aac8d4552723164741536af6512011
2022-05-30 00:39:17 +00:00
|
|
|
all_allocated_update(&net->all_allocated, &net->chan_counts);
|
2021-08-29 11:31:05 +00:00
|
|
|
}
|