Change in osmo-bsc[master]: refactor lchan counting

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.org
Wed Nov 10 13:27:43 UTC 2021


neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bsc/+/25972 )

Change subject: refactor lchan counting
......................................................................

refactor lchan counting

Add chan_counts_for_trx() and chan_counts_for_bts(). Drop
bts_count_free_ts() and trx_count_free_ts().

Rationale:

The bts_count_free_ts() and trx_count_free_ts() always returned the
number of free lchans, not timeslots. Hence, passing the pchan type as
argument never really matched the semantics.

Especially, when looking for free SDCCH, there is no clear match on a
gsm_phys_chan_config enum value: SDCCH8_SACCH8C, CCCH_SDCCH4,
CCCH_SDCCH4_CBCH, SDCCH8_SACCH8C_CBCH? -- GSM_LCHAN_SDCCH is clear.

==> Rather count free lchans by enum gsm_chan_t.

Counting lchans of distinct types required separate iterations for each
lchan type.

==> Rather compose an array of counts for all types, in one go.

I need to count the amount of free SDCCH lchans in an upcoming patch to
implement the performance indicator allAvailableAllocatedSDCCH (cumulate
time for which no SDCCH are available).

To implement allAvailableAllocated{SDCCH,TCH}, I need a count of both
the used as well as the total lchans for a type: it does not make sense
to flag "all available allocated" if none are ever available.

To properly count dynamic ts, I need the maximum total that can be
possible at any time. And to count currently free lchans, I need the
current total. This may seem counter intuitive, but consider, e.g.:

- Obviously, if a cell has only static TCH/F timeslots, it does not make
  sense to flag that all available TCH/H are occupied, because no TCH/H
  are available ever. Just stating this as contrast to dyn TS.

- If a cell has OSMO_DYN timeslots, I *do* want to flag that all TCH/H
  are occupied when all dyn timeslots are fully occupied.

- If those OSMO_DYN however are all used as TCH/F, the current total of
  TCH/H becomes zero, and it seems like TCH/H should not be considered.

- To count the nr of currently free lchans, I need the currently
  possible total of lchans and the nr of occupied lchans.

So return both a maximum total and a current total of lchans. In above
example, the maximum total shows that there would be TCH/H possible.

BTW, it would be nice to keep a chan_counts array on trx, bts and bsc
level and update as channels are allocated and released, instead of
counting them all over periodically. But it's less error prone this way.

Related: SYS#4878
Change-Id: I2fb48c549186db812b1e9d6b735a92e80f27b8d3
---
M include/osmocom/bsc/Makefile.am
M include/osmocom/bsc/bts.h
M include/osmocom/bsc/bts_trx.h
A include/osmocom/bsc/chan_counts.h
M src/osmo-bsc/Makefile.am
M src/osmo-bsc/abis_rsl.c
M src/osmo-bsc/bts.c
M src/osmo-bsc/bts_trx.c
A src/osmo-bsc/chan_counts.c
M src/osmo-bsc/handover_decision_2.c
10 files changed, 238 insertions(+), 72 deletions(-)

Approvals:
  neels: Looks good to me, approved
  dexter: Looks good to me, but someone else must approve
  Jenkins Builder: Verified



diff --git a/include/osmocom/bsc/Makefile.am b/include/osmocom/bsc/Makefile.am
index 3bccf44..3ddad45 100644
--- a/include/osmocom/bsc/Makefile.am
+++ b/include/osmocom/bsc/Makefile.am
@@ -16,6 +16,7 @@
 	bts_trx.h \
 	bts_ipaccess_nanobts_omlattr.h \
 	chan_alloc.h \
+	chan_counts.h \
 	codec_pref.h \
 	ctrl.h \
 	debug.h \
diff --git a/include/osmocom/bsc/bts.h b/include/osmocom/bsc/bts.h
index 7e73acd..c887ca8 100644
--- a/include/osmocom/bsc/bts.h
+++ b/include/osmocom/bsc/bts.h
@@ -726,8 +726,6 @@
 
 void gsm_bts_all_ts_dispatch(struct gsm_bts *bts, uint32_t ts_ev, void *data);
 
-int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan);
-
 int gsm_bts_set_system_infos(struct gsm_bts *bts);
 
 int gsm_bts_set_c0_power_red(struct gsm_bts *bts, const uint8_t red);
diff --git a/include/osmocom/bsc/bts_trx.h b/include/osmocom/bsc/bts_trx.h
index 4d705d0..c8df9d9 100644
--- a/include/osmocom/bsc/bts_trx.h
+++ b/include/osmocom/bsc/bts_trx.h
@@ -95,7 +95,6 @@
 bool trx_is_usable(const struct gsm_bts_trx *trx);
 
 void gsm_trx_all_ts_dispatch(struct gsm_bts_trx *trx, uint32_t ts_ev, void *data);
-int trx_count_free_ts(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan);
 bool trx_has_valid_pchan_config(const struct gsm_bts_trx *trx);
 
 int gsm_bts_trx_set_system_infos(struct gsm_bts_trx *trx);
diff --git a/include/osmocom/bsc/chan_counts.h b/include/osmocom/bsc/chan_counts.h
new file mode 100644
index 0000000..9f73bc4
--- /dev/null
+++ b/include/osmocom/bsc/chan_counts.h
@@ -0,0 +1,76 @@
+/* API to count total, allocated and free channels of all types */
+#pragma once
+
+struct gsm_bts;
+struct gsm_bts_trx;
+
+/* First array index to typedef chan_counts_arr. */
+enum chan_counts_dim1 {
+	CHAN_COUNTS1_ALL = 0,
+	CHAN_COUNTS1_STATIC = 1,
+	CHAN_COUNTS1_DYNAMIC = 2,
+	_CHAN_COUNTS1_NUM
+};
+
+/* Second array index to typedef chan_counts_arr. */
+enum chan_counts_dim2 {
+	/* The maximum possible nr of lchans of this type. Counts all dynamic timeslots as if they are fully available
+	 * for this type, regardless of the current pchan mode. (For CHAN_COUNTS1_STATIC, of course no dyn TS are counted
+	 * at all.) */
+	CHAN_COUNTS2_MAX_TOTAL = 0,
+	/* Like MAX_TOTAL, but as soon as dynamic timeslots are switched to a specific pchan kind, current_total shrinks
+	 * to count only currently present lchans (used and unused). */
+	CHAN_COUNTS2_CURRENT_TOTAL = 1,
+	/* Currently used lchans of this type. To get currently free lchans, calculate CURRENT_TOTAL - ALLOCATED. */
+	CHAN_COUNTS2_ALLOCATED = 2,
+	/* Currently assignable lchans of this type, same as CURRENT_TOTAL - ALLOCATED. */
+	CHAN_COUNTS2_FREE = 3,
+	_CHAN_COUNTS2_NUM
+};
+
+struct chan_counts {
+	unsigned 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 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,
+					enum chan_counts_dim1 add_dim1, enum chan_counts_dim2 add_dim2)
+{
+	int i;
+	for (i = 0; i < _GSM_LCHAN_MAX; i++)
+		dst->val[dst_dim1][dst_dim2][i] += add->val[add_dim1][add_dim2][i];
+}
+
+static inline void chan_counts_dim3_sub(struct chan_counts *dst,
+					enum chan_counts_dim1 dst_dim1, enum chan_counts_dim2 dst_dim2,
+					const struct chan_counts *sub,
+					enum chan_counts_dim1 sub_dim1, enum chan_counts_dim2 sub_dim2)
+{
+	int i;
+	for (i = 0; i < _GSM_LCHAN_MAX; i++)
+		dst->val[dst_dim1][dst_dim2][i] -= sub->val[sub_dim1][sub_dim2][i];
+}
+
+static inline void chan_counts_dim2_add(struct chan_counts *dst, enum chan_counts_dim1 dst_dim1,
+					const struct chan_counts *add, enum chan_counts_dim1 add_dim1)
+{
+	int i;
+	for (i = 0; i < _CHAN_COUNTS2_NUM; i++)
+		chan_counts_dim3_add(dst, dst_dim1, i, add, add_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);
+}
diff --git a/src/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am
index 3d6666e..583fb79 100644
--- a/src/osmo-bsc/Makefile.am
+++ b/src/osmo-bsc/Makefile.am
@@ -57,6 +57,7 @@
 	bts_vty.c \
 	bts_trx_vty.c \
 	chan_alloc.c \
+	chan_counts.c \
 	codec_pref.c \
 	e1_config.c \
 	gsm_04_08_rr.c \
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index 423c2b8..c0d621c 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -56,6 +56,7 @@
 #include <osmocom/bsc/smscb.h>
 #include <osmocom/bsc/bts.h>
 #include <osmocom/bsc/power_control.h>
+#include <osmocom/bsc/chan_counts.h>
 
 static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
 			      struct gsm_meas_rep *resp)
@@ -1946,6 +1947,7 @@
 
 struct gsm_lchan *_select_sdcch_for_call(struct gsm_bts *bts, const struct chan_rqd *rqd, enum gsm_chan_t lctype)
 {
+	struct chan_counts bts_counts;
 	struct gsm_lchan *lchan = NULL;
 	int free_tchf, free_tchh;
 	bool needs_dyn_switch;
@@ -1957,8 +1959,9 @@
 	needs_dyn_switch = lchan->ts->pchan_on_init == GSM_PCHAN_OSMO_DYN &&
 					lchan->ts->pchan_is != GSM_PCHAN_SDCCH8_SACCH8C;
 
-	free_tchf = bts_count_free_ts(bts, GSM_PCHAN_TCH_F);
-	free_tchh = bts_count_free_ts(bts, GSM_PCHAN_TCH_H);
+	chan_counts_for_bts(&bts_counts, bts);
+	free_tchf = bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F];
+	free_tchh = bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H];
 	if (free_tchf == 0 && free_tchh == 0) {
 		LOG_BTS(bts, DRSL, LOGL_INFO,
 			"CHAN RQD: 0x%x Requesting %s reason=call but no TCH available\n",
diff --git a/src/osmo-bsc/bts.c b/src/osmo-bsc/bts.c
index 83adcc4..5701957 100644
--- a/src/osmo-bsc/bts.c
+++ b/src/osmo-bsc/bts.c
@@ -719,19 +719,6 @@
 		gsm_trx_all_ts_dispatch(trx, ts_ev, data);
 }
 
-
-/* Count number of free TS of given pchan type */
-int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan)
-{
-	struct gsm_bts_trx *trx;
-	int count = 0;
-
-	llist_for_each_entry(trx, &bts->trx_list, list)
-		count += trx_count_free_ts(trx, pchan);
-
-	return count;
-}
-
 /* set all system information types for a BTS */
 int gsm_bts_set_system_infos(struct gsm_bts *bts)
 {
diff --git a/src/osmo-bsc/bts_trx.c b/src/osmo-bsc/bts_trx.c
index f30c748..0333f70 100644
--- a/src/osmo-bsc/bts_trx.c
+++ b/src/osmo-bsc/bts_trx.c
@@ -292,54 +292,6 @@
 	}
 }
 
-int trx_count_free_ts(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan)
-{
-	struct gsm_bts_trx_ts *ts;
-	struct gsm_lchan *lchan;
-	int j;
-	int count = 0;
-
-	if (!trx_is_usable(trx))
-		return 0;
-
-	for (j = 0; j < ARRAY_SIZE(trx->ts); j++) {
-		ts = &trx->ts[j];
-		if (!ts_is_usable(ts))
-			continue;
-
-		if (ts->pchan_is == GSM_PCHAN_PDCH) {
-			/* Dynamic timeslots in PDCH mode will become TCH if needed. */
-			switch (ts->pchan_on_init) {
-			case GSM_PCHAN_TCH_F_PDCH:
-				if (pchan == GSM_PCHAN_TCH_F)
-					count++;
-				continue;
-
-			case GSM_PCHAN_OSMO_DYN:
-				if (pchan == GSM_PCHAN_TCH_F)
-					count++;
-				else if (pchan == GSM_PCHAN_TCH_H)
-					count += 2;
-				continue;
-
-			default:
-				/* Not dynamic, not applicable. */
-				continue;
-			}
-		}
-
-		if (ts->pchan_is != pchan)
-			continue;
-
-		ts_for_n_lchans(lchan, ts, ts->max_primary_lchans) {
-			if (lchan_state_is(lchan, LCHAN_ST_UNUSED))
-				count++;
-		}
-	}
-
-	return count;
-}
-
 bool trx_has_valid_pchan_config(const struct gsm_bts_trx *trx)
 {
 	bool combined = false;
diff --git a/src/osmo-bsc/chan_counts.c b/src/osmo-bsc/chan_counts.c
new file mode 100644
index 0000000..99e6e76
--- /dev/null
+++ b/src/osmo-bsc/chan_counts.c
@@ -0,0 +1,142 @@
+/* count total, allocated and free channels of all types.
+ *
+ * (C) 2021 by sysmocom - s.f.m.c. GmbH <info at sysmocom.de>
+ * All Rights Reserved
+ *
+ * Author: Neels Hofmeyr <nhofmeyr at sysmocom.de>
+ *
+ * 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/gsm/gsm_utils.h>
+
+#include <osmocom/bsc/bts.h>
+#include <osmocom/bsc/bts_trx.h>
+#include <osmocom/bsc/lchan_fsm.h>
+#include <osmocom/bsc/chan_counts.h>
+
+static const unsigned int lchans_per_pchan[_GSM_PCHAN_MAX][_GSM_LCHAN_MAX] = {
+	[GSM_PCHAN_NONE] = {0},
+	[GSM_PCHAN_CCCH] = { [GSM_LCHAN_CCCH] = 1, },
+	[GSM_PCHAN_PDCH] = { [GSM_LCHAN_PDTCH] = 1, },
+	[GSM_PCHAN_CCCH_SDCCH4] = {
+		[GSM_LCHAN_CCCH] = 1,
+		[GSM_LCHAN_SDCCH] = 3,
+	},
+	[GSM_PCHAN_TCH_F] = { [GSM_LCHAN_TCH_F] = 1, },
+	[GSM_PCHAN_TCH_H] = { [GSM_LCHAN_TCH_H] = 2, },
+	[GSM_PCHAN_SDCCH8_SACCH8C] = { [GSM_LCHAN_SDCCH] = 8, },
+	[GSM_PCHAN_CCCH_SDCCH4_CBCH] = {
+		[GSM_LCHAN_CCCH] = 1,
+		[GSM_LCHAN_SDCCH] = 3,
+		[GSM_LCHAN_CBCH] = 1,
+	},
+	[GSM_PCHAN_SDCCH8_SACCH8C_CBCH] = {
+		[GSM_LCHAN_SDCCH] = 8,
+		[GSM_LCHAN_CBCH] = 1,
+	},
+	[GSM_PCHAN_OSMO_DYN] = {
+		[GSM_LCHAN_TCH_F] = 1,
+		[GSM_LCHAN_TCH_H] = 2,
+		[GSM_LCHAN_SDCCH] = 8,
+		[GSM_LCHAN_PDTCH] = 1,
+	},
+	[GSM_PCHAN_TCH_F_PDCH] = {
+		[GSM_LCHAN_TCH_F] = 1,
+		[GSM_LCHAN_PDTCH] = 1,
+	},
+};
+
+static inline void chan_counts_per_pchan_add(struct chan_counts *dst,
+					     enum chan_counts_dim1 dim1, enum chan_counts_dim2 dim2,
+					     enum gsm_phys_chan_config pchan)
+{
+	int i;
+	for (i = 0; i < _GSM_LCHAN_MAX; i++)
+		dst->val[dim1][dim2][i] += lchans_per_pchan[pchan][i];
+}
+
+void chan_counts_for_trx(struct chan_counts *trx_counts, const struct gsm_bts_trx *trx)
+{
+	const struct gsm_bts_trx_ts *ts;
+	const struct gsm_lchan *lchan;
+	int i;
+
+	chan_counts_zero(trx_counts);
+
+	if (!trx_is_usable(trx))
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
+		bool ts_is_dynamic;
+		struct chan_counts ts_count = {0};
+		ts = &trx->ts[i];
+		if (!ts_is_usable(ts))
+			continue;
+
+		/* Count the full potential nr of lchans for dynamic TS */
+		chan_counts_per_pchan_add(&ts_count, CHAN_COUNTS1_ALL, CHAN_COUNTS2_MAX_TOTAL, ts->pchan_on_init);
+
+		switch (ts->pchan_on_init) {
+		case GSM_PCHAN_TCH_F_PDCH:
+		case GSM_PCHAN_OSMO_DYN:
+			ts_is_dynamic = true;
+			break;
+		default:
+			ts_is_dynamic = false;
+			break;
+		}
+
+		if (ts_is_dynamic && ts->pchan_is == GSM_PCHAN_PDCH) {
+			/* Dynamic timeslots in PDCH mode can become TCH or SDCCH immediately,
+			 * so set CURRENT_TOTAL = MAX_TOTAL. */
+			chan_counts_dim3_add(&ts_count, CHAN_COUNTS1_ALL, CHAN_COUNTS2_CURRENT_TOTAL,
+					     &ts_count, CHAN_COUNTS1_ALL, CHAN_COUNTS2_MAX_TOTAL);
+		} else {
+			/* Static TS, or dyn TS that are currently fixed on a specific pchan: count lchans for the
+			 * current pchan mode. */
+			chan_counts_per_pchan_add(&ts_count, CHAN_COUNTS1_ALL, CHAN_COUNTS2_CURRENT_TOTAL, ts->pchan_is);
+		}
+
+		/* Count currently allocated lchans */
+		ts_for_n_lchans(lchan, ts, ts->max_primary_lchans) {
+			if (!lchan_state_is(lchan, LCHAN_ST_UNUSED))
+				ts_count.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_ALLOCATED][lchan->type]++;
+		}
+
+		chan_counts_dim3_add(&ts_count, CHAN_COUNTS1_ALL, CHAN_COUNTS2_FREE,
+				     &ts_count, CHAN_COUNTS1_ALL, CHAN_COUNTS2_CURRENT_TOTAL);
+		chan_counts_dim3_sub(&ts_count, CHAN_COUNTS1_ALL, CHAN_COUNTS2_FREE,
+				     &ts_count, CHAN_COUNTS1_ALL, CHAN_COUNTS2_ALLOCATED);
+
+		if (ts_is_dynamic)
+			chan_counts_dim2_add(trx_counts, CHAN_COUNTS1_DYNAMIC, &ts_count, CHAN_COUNTS1_ALL);
+		else
+			chan_counts_dim2_add(trx_counts, CHAN_COUNTS1_STATIC, &ts_count, CHAN_COUNTS1_ALL);
+		chan_counts_dim2_add(trx_counts, CHAN_COUNTS1_ALL, &ts_count, CHAN_COUNTS1_ALL);
+	}
+}
+
+void chan_counts_for_bts(struct chan_counts *bts_counts, const struct gsm_bts *bts)
+{
+	struct gsm_bts_trx *trx;
+	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);
+	}
+}
diff --git a/src/osmo-bsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c
index e384feb..6730f26 100644
--- a/src/osmo-bsc/handover_decision_2.c
+++ b/src/osmo-bsc/handover_decision_2.c
@@ -42,6 +42,7 @@
 #include <osmocom/bsc/timeslot_fsm.h>
 #include <osmocom/bsc/bts.h>
 #include <osmocom/bsc/lchan_select.h>
+#include <osmocom/bsc/chan_counts.h>
 
 #define LOGPHOBTS(bts, level, fmt, args...) \
 	LOGP(DHODEC, level, "(BTS %u) " fmt, bts->nr, ## args)
@@ -990,12 +991,15 @@
 
 static void candidate_set_free_tch(struct ho_candidate *c)
 {
+	struct chan_counts bts_counts;
 	struct gsm_lchan *next_lchan;
 
-	c->current.free_tchf = bts_count_free_ts(c->current.bts, GSM_PCHAN_TCH_F);
+	chan_counts_for_bts(&bts_counts, c->current.bts);
+	c->current.free_tchf = bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_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.free_tchh = bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_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.free_tch = c->current.free_tchf;
@@ -1023,9 +1027,10 @@
 		break;
 	}
 
-	c->target.free_tchf = bts_count_free_ts(c->target.bts, GSM_PCHAN_TCH_F);
+	chan_counts_for_bts(&bts_counts, c->target.bts);
+	c->target.free_tchf = bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_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);
+	c->target.free_tchh = bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H];
 	c->target.min_free_tchh = ho_get_hodec2_tchh_min_slots(c->target.bts->ho);
 
 	/* Would the next TCH/F lchan occupy a dynamic timeslot that currently counts for free TCH/H timeslots? */
@@ -1928,6 +1933,7 @@
 
 static void bts_congestion_check(struct gsm_bts *bts)
 {
+	struct chan_counts bts_counts;
 	int min_free_tchf, min_free_tchh;
 	int free_tchf, free_tchh;
 
@@ -1955,8 +1961,9 @@
 		return;
 	}
 
-	free_tchf = bts_count_free_ts(bts, GSM_PCHAN_TCH_F);
-	free_tchh = bts_count_free_ts(bts, GSM_PCHAN_TCH_H);
+	chan_counts_for_bts(&bts_counts, bts);
+	free_tchf = bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_F];
+	free_tchh = bts_counts.val[CHAN_COUNTS1_ALL][CHAN_COUNTS2_FREE][GSM_LCHAN_TCH_H];
 	LOGPHOBTS(bts, LOGL_INFO, "Congestion check: (free/want-free) TCH/F=%d/%d TCH/H=%d/%d\n",
 		  free_tchf, min_free_tchf, free_tchh, min_free_tchh);
 

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/25972
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I2fb48c549186db812b1e9d6b735a92e80f27b8d3
Gerrit-Change-Number: 25972
Gerrit-PatchSet: 9
Gerrit-Owner: neels <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: dexter <pmaier at sysmocom.de>
Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: neels <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20211110/b69c286c/attachment.htm>


More information about the gerrit-log mailing list