aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2021-06-14 17:54:38 +0200
committerPhilipp Maier <pmaier@sysmocom.de>2021-07-06 11:35:50 +0200
commitdda5cf4bb7622eba600042464910c02fab1aaa49 (patch)
tree5c5fc2e2f635fe967831f155b44fb22d4ed37132
parenta5602d593ce14077152b921e53bb37b66e1c579c (diff)
paging: prioritize CS related paging over PS related pagings.
When the paging queue is filled up to a critical level, pagings from the PCU should be dropped as each immediate assignment paging from the PCU is worth 4 normal CS pagings. Also the PCU may still issue pagings if the paginging queue is already full and CS pagings are dropped. In a congestion situation it is more important to get the CS rather than PS pagings through. Change-Id: I30f97672d7a0c369c4a656e878ab8cbbd83e31ea Related: SYS#5306
-rw-r--r--include/osmo-bts/bts.h2
-rw-r--r--include/osmo-bts/paging.h2
-rw-r--r--src/common/bts.c2
-rw-r--r--src/common/paging.c47
-rw-r--r--src/common/pcu_sock.c2
5 files changed, 52 insertions, 3 deletions
diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h
index e1166182..6a61d015 100644
--- a/include/osmo-bts/bts.h
+++ b/include/osmo-bts/bts.h
@@ -18,7 +18,9 @@ enum bts_global_status {
enum {
BTS_CTR_PAGING_RCVD,
BTS_CTR_PAGING_DROP,
+ BTS_CTR_PAGING_DROP_PS,
BTS_CTR_PAGING_SENT,
+ BTS_CTR_PAGING_CONG,
BTS_CTR_RACH_RCVD,
BTS_CTR_RACH_DROP,
BTS_CTR_RACH_HO,
diff --git a/include/osmo-bts/paging.h b/include/osmo-bts/paging.h
index 7fc0bf05..ef1fc93d 100644
--- a/include/osmo-bts/paging.h
+++ b/include/osmo-bts/paging.h
@@ -37,7 +37,7 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
/* Add an IMM.ASS message to the paging queue */
int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data,
- uint8_t len);
+ uint8_t len, bool from_pcu);
/* generate paging message for given gsm time */
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt,
diff --git a/src/common/bts.c b/src/common/bts.c
index d2226997..27c7f74c 100644
--- a/src/common/bts.c
+++ b/src/common/bts.c
@@ -90,6 +90,8 @@ static int bts_signal_cbfn(unsigned int subsys, unsigned int signal,
static const struct rate_ctr_desc bts_ctr_desc[] = {
[BTS_CTR_PAGING_RCVD] = {"paging:rcvd", "Received paging requests (Abis)"},
[BTS_CTR_PAGING_DROP] = {"paging:drop", "Dropped paging requests (Abis)"},
+ [BTS_CTR_PAGING_DROP_PS] = {"paging:drop-ps", "Dropped paging requests (PS/PCU)"},
+ [BTS_CTR_PAGING_CONG] = {"paging:cong", "Paging congestion detected (Abis)"},
[BTS_CTR_PAGING_SENT] = {"paging:sent", "Sent paging requests (Um)"},
[BTS_CTR_RACH_RCVD] = {"rach:rcvd", "Received RACH requests (Um)"},
diff --git a/src/common/paging.c b/src/common/paging.c
index 29731419..54d72635 100644
--- a/src/common/paging.c
+++ b/src/common/paging.c
@@ -80,8 +80,37 @@ struct paging_state {
/* total number of currently active paging records in queue */
unsigned int num_paging;
struct llist_head paging_queue[MAX_PAGING_BLOCKS_CCCH*MAX_BS_PA_MFRMS];
+
+ /* prioritization of cs pagings will automatically become
+ * active on congestions (queue almost full) */
+ bool cs_priority_active;
};
+/* The prioritization of cs pagings is controlled by a hysteresis. When the
+ * fill state of the paging queue exceeds the upper fill level
+ * THRESHOLD_CONGESTED [%], then PS pagings (immediate assignments) will be
+ * dropped until fill state of the paging queue drops under the lower fill
+ * level THRESHOLD_CLEAR [%]. */
+#define THRESHOLD_CONGESTED 66 /* (percent of num_paging_max) */
+#define THRESHOLD_CLEAR 50 /* (percent of num_paging_max) */
+
+/* Check the queue fill status and decide if prioritization of CS pagings
+ * must be turned on to flatten the negative effects of the congestion
+ * situation on the CS domain. */
+static void check_congestion(struct paging_state *ps)
+{
+ int pag_queue_len = paging_queue_length(ps);
+ int pag_queue_max = paging_get_queue_max(ps);
+ unsigned int treshold_upper = pag_queue_max * THRESHOLD_CONGESTED / 100;
+ unsigned int treshold_lower = pag_queue_max * THRESHOLD_CLEAR / 100;
+
+ if (pag_queue_len > treshold_upper && ps->cs_priority_active == false) {
+ ps->cs_priority_active = true;
+ rate_ctr_inc2(ps->bts->ctrs, BTS_CTR_PAGING_CONG);
+ } else if (pag_queue_len < treshold_lower)
+ ps->cs_priority_active = false;
+}
+
unsigned int paging_get_lifetime(struct paging_state *ps)
{
return ps->paging_lifetime;
@@ -181,6 +210,8 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
int blocks = gsm48_number_of_paging_subchannels(&ps->chan_desc);
struct paging_record *pr;
+ check_congestion(ps);
+
rate_ctr_inc2(ps->bts->ctrs, BTS_CTR_PAGING_RCVD);
if (paging_group >= blocks) {
@@ -238,12 +269,21 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
/* Add an IMM.ASS message to the paging queue */
int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data,
- uint8_t len)
+ uint8_t len, bool from_pcu)
{
struct llist_head *group_q;
struct paging_record *pr;
uint16_t imsi, paging_group;
+ check_congestion(ps);
+
+ if (ps->cs_priority_active && from_pcu) {
+ LOGP(DPAG, LOGL_NOTICE, "Dropping paging for PS, queue congested (%u)\n",
+ ps->num_paging);
+ rate_ctr_inc2(ps->bts->ctrs, BTS_CTR_PAGING_DROP_PS);
+ return -ENOSPC;
+ }
+
if (len != GSM_MACBLOCK_LEN + 3) {
LOGP(DPAG, LOGL_ERROR, "IMM.ASS invalid length %d\n", len);
return -EINVAL;
@@ -530,6 +570,10 @@ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *g
int group;
int len;
+ /* This will have no effect on behavior of this function, we just need
+ * need to check the congestion status of the queue from time to time. */
+ check_congestion(ps);
+
*is_empty = 0;
bts->load.ccch.pch_total += 1;
@@ -711,6 +755,7 @@ struct paging_state *paging_init(struct gsm_bts *bts,
ps->bts = bts;
ps->paging_lifetime = paging_lifetime;
ps->num_paging_max = num_paging_max;
+ ps->cs_priority_active = false;
for (i = 0; i < ARRAY_SIZE(ps->paging_queue); i++)
INIT_LLIST_HEAD(&ps->paging_queue[i]);
diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c
index 41a5ffc5..03f1a05d 100644
--- a/src/common/pcu_sock.c
+++ b/src/common/pcu_sock.c
@@ -673,7 +673,7 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
switch (data_req->sapi) {
case PCU_IF_SAPI_PCH:
- paging_add_imm_ass(bts->paging_state, data_req->data, data_req->len);
+ paging_add_imm_ass(bts->paging_state, data_req->data, data_req->len, true);
break;
case PCU_IF_SAPI_AGCH:
msg = msgb_alloc(data_req->len, "pcu_agch");