aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2022-05-30 02:39:17 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2022-06-02 14:24:30 +0200
commitc1bfc88b6bbb370207e1dcb70af21bd806867ea2 (patch)
tree0247e7b4bc22c10e604fee4eaf8f592837b38af7 /include
parent4c89001ccbd4dfb505454ae2b5f31ac09af7848a (diff)
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
Diffstat (limited to 'include')
-rw-r--r--include/osmocom/bsc/bsc_stats.h2
-rw-r--r--include/osmocom/bsc/bts.h1
-rw-r--r--include/osmocom/bsc/bts_trx.h2
-rw-r--r--include/osmocom/bsc/chan_counts.h43
-rw-r--r--include/osmocom/bsc/gsm_data.h4
5 files changed, 48 insertions, 4 deletions
diff --git a/include/osmocom/bsc/bsc_stats.h b/include/osmocom/bsc/bsc_stats.h
index edd36b656..e8837aa1e 100644
--- a/include/osmocom/bsc/bsc_stats.h
+++ b/include/osmocom/bsc/bsc_stats.h
@@ -22,6 +22,7 @@
struct osmo_stat_item_group_desc;
struct gsm_network;
+struct gsm_bts;
/* OsmoBSC rate_ctr indexes */
enum {
@@ -111,4 +112,5 @@ extern const struct osmo_stat_item_group_desc bsc_statg_desc;
void bsc_update_connection_stats(struct gsm_network *net);
+void all_allocated_update_bts(struct gsm_bts *bts);
void all_allocated_update_bsc();
diff --git a/include/osmocom/bsc/bts.h b/include/osmocom/bsc/bts.h
index fc3ebce12..66cf68f02 100644
--- a/include/osmocom/bsc/bts.h
+++ b/include/osmocom/bsc/bts.h
@@ -637,6 +637,7 @@ 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 chan_counts chan_counts;
struct all_allocated all_allocated;
};
diff --git a/include/osmocom/bsc/bts_trx.h b/include/osmocom/bsc/bts_trx.h
index c8df9d9c4..eab5fecd5 100644
--- a/include/osmocom/bsc/bts_trx.h
+++ b/include/osmocom/bsc/bts_trx.h
@@ -79,6 +79,8 @@ struct gsm_bts_trx {
} rbs2000;
};
struct gsm_bts_trx_ts ts[TRX_NR_TS];
+
+ struct chan_counts chan_counts;
};
static inline struct gsm_bts_trx *gsm_bts_bb_trx_get_trx(struct gsm_bts_bb_trx *bb_transc) {
diff --git a/include/osmocom/bsc/chan_counts.h b/include/osmocom/bsc/chan_counts.h
index 31a1adc92..c11473e71 100644
--- a/include/osmocom/bsc/chan_counts.h
+++ b/include/osmocom/bsc/chan_counts.h
@@ -3,6 +3,14 @@
struct gsm_bts;
struct gsm_bts_trx;
+struct gsm_bts_trx_ts;
+struct gsm_lchan;
+
+void chan_counts_sig_init();
+void chan_counts_ts_update(struct gsm_bts_trx_ts *ts);
+void chan_counts_ts_clear(struct gsm_bts_trx_ts *ts);
+void chan_counts_trx_update(struct gsm_bts_trx *trx);
+void chan_counts_bsc_verify();
/* First array index to chan_counts.val. */
enum chan_counts_dim1 {
@@ -29,17 +37,29 @@ enum chan_counts_dim2 {
};
struct chan_counts {
- unsigned int val[_CHAN_COUNTS1_NUM][_CHAN_COUNTS2_NUM][_GSM_LCHAN_MAX];
+ /* Signed type, so that chan_counts_diff() can return negative values. */
+ int val[_CHAN_COUNTS1_NUM][_CHAN_COUNTS2_NUM][_GSM_LCHAN_MAX];
};
-void chan_counts_for_bts(struct chan_counts *bts_counts, const struct gsm_bts *bts);
-void chan_counts_for_trx(struct chan_counts *trx_counts, const struct gsm_bts_trx *trx);
-
static inline void chan_counts_zero(struct chan_counts *counts)
{
*counts = (struct chan_counts){0};
}
+static inline bool chan_counts_is_zero(const struct chan_counts *counts)
+{
+ int i1, i2, i3;
+ for (i1 = 0; i1 < _CHAN_COUNTS1_NUM; i1++) {
+ for (i2 = 0; i2 < _CHAN_COUNTS2_NUM; i2++) {
+ for (i3 = 0; i3 < _GSM_LCHAN_MAX; i3++) {
+ if (counts->val[i1][i2][i3])
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
static inline void chan_counts_dim3_add(struct chan_counts *dst,
enum chan_counts_dim1 dst_dim1, enum chan_counts_dim2 dst_dim2,
const struct chan_counts *add,
@@ -68,9 +88,24 @@ static inline void chan_counts_dim2_add(struct chan_counts *dst, enum chan_count
chan_counts_dim3_add(dst, dst_dim1, i, add, add_dim1, i);
}
+static inline void chan_counts_dim2_sub(struct chan_counts *dst, enum chan_counts_dim1 dst_dim1,
+ const struct chan_counts *sub, enum chan_counts_dim1 sub_dim1)
+{
+ int i;
+ for (i = 0; i < _CHAN_COUNTS2_NUM; i++)
+ chan_counts_dim3_sub(dst, dst_dim1, i, sub, sub_dim1, i);
+}
+
static inline void chan_counts_add(struct chan_counts *dst, const struct chan_counts *add)
{
int i;
for (i = 0; i < _CHAN_COUNTS1_NUM; i++)
chan_counts_dim2_add(dst, i, add, i);
}
+
+static inline void chan_counts_sub(struct chan_counts *dst, const struct chan_counts *sub)
+{
+ int i;
+ for (i = 0; i < _CHAN_COUNTS1_NUM; i++)
+ chan_counts_dim2_sub(dst, i, sub, i);
+}
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 88c6474c9..126c7a79b 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -34,6 +34,7 @@
#include <osmocom/bsc/meas_rep.h>
#include <osmocom/bsc/acc.h>
#include <osmocom/bsc/osmux.h>
+#include <osmocom/bsc/chan_counts.h>
#define GSM_T3122_DEFAULT 10
@@ -962,6 +963,8 @@ struct gsm_bts_trx_ts {
* Does not include count of secondary VAMOS lchans. */
uint8_t max_primary_lchans;
struct gsm_lchan lchan[TS_MAX_LCHAN];
+
+ struct chan_counts chan_counts;
};
#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i][0])
@@ -1320,6 +1323,7 @@ struct gsm_network {
struct smlc_config *smlc;
+ struct chan_counts chan_counts;
struct all_allocated all_allocated;
};