aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2022-04-26 13:58:50 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2022-04-28 16:04:04 +0200
commit1e79745e801db06783dc74348f10208dda776267 (patch)
tree42ae4275e080062b27c4d4430e2ed72523b00363
parenta6474172e4aef3b57b8ac93b1dcab3aeeab29ced (diff)
paging: Decouple retransmit period from regular worker interval
Before this patch, on each BTS a 500ms timer was used to schedule some work, sending up to 20 paging requests verytime. This means, however, for an initial paging request it may take up to 500ms delay to be scheduled to the BTS, which is huge. While we still want to maintain this 500ms interval for retransmits, it doesn't make sense to wait that much for other cases. It's far better sending less requests (10 instead of 20) every half time (250ms instead of 500ms), since it will spread the load and paging more over time, allowing for other work to be done in the middle. Change-Id: I7a1297452cc4734b6ee8c38fb94cf32f38d57c3d
-rw-r--r--include/osmocom/bsc/paging.h2
-rw-r--r--src/osmo-bsc/paging.c33
2 files changed, 33 insertions, 2 deletions
diff --git a/include/osmocom/bsc/paging.h b/include/osmocom/bsc/paging.h
index 2102e0491..d9fd501b6 100644
--- a/include/osmocom/bsc/paging.h
+++ b/include/osmocom/bsc/paging.h
@@ -82,6 +82,8 @@ struct gsm_paging_request {
/* How often did we ask the BTS to page? */
int attempts;
+ /* Timestamp of last time the subscriber was paged */
+ struct timespec last_attempt_ts;
/* MSC that has issued this paging */
struct bsc_msc_data *msc;
diff --git a/src/osmo-bsc/paging.c b/src/osmo-bsc/paging.c
index 3da5f1869..9bc010532 100644
--- a/src/osmo-bsc/paging.c
+++ b/src/osmo-bsc/paging.c
@@ -59,7 +59,19 @@
void *tall_paging_ctx = NULL;
/* How many paging requests to Tx on RSL at max before going back to main loop */
-#define MAX_PAGE_REQ_PER_ITER 20
+#define MAX_PAGE_REQ_PER_ITER 10
+
+/* How often to attempt sending new paging requests (initial, not retrans): 250ms */
+static const struct timespec initial_period = {
+ .tv_sec = 0,
+ .tv_nsec = 250 * 1000 * 1000,
+};
+
+/* Minimum period between retransmits of paging req to a subscriber: 500ms */
+static const struct timespec retrans_period = {
+ .tv_sec = 0,
+ .tv_nsec = 500 * 1000 * 1000,
+};
/*
* Kill one paging request update the internal list...
@@ -185,6 +197,7 @@ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_b
struct gsm_paging_request *request, *initial_request;
unsigned int num_paged = 0;
struct gsm_bts *bts = paging_bts->bts;
+ struct timespec now, retrans_ts;
/*
* Determine if the pending_requests list is empty and
@@ -199,6 +212,8 @@ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_b
if (!bts->c0->rsl_link_primary)
goto sched_next_iter;
+ osmo_clock_gettime(CLOCK_MONOTONIC, &now);
+
/* do while loop: Try send at most first MAX_PAGE_REQ_PER_ITER paging
* requests (or before if there are no more available slots). Since
* transmitted requests are re-appended at the end of the list, we check
@@ -223,9 +238,23 @@ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_b
goto sched_next_iter;
}
+ /* If we reach around back of the queue (retransmitions), check
+ * if time to retransmit has elapsed. Otherwise, wait until its
+ * time to retransmit. */
+ if (request->attempts > 0) {
+ timespecadd(&request->last_attempt_ts, &retrans_period, &retrans_ts);
+ if (timespeccmp(&now, &retrans_ts, <)) {
+ struct timespec tdiff;
+ timespecsub(&retrans_ts, &now, &tdiff);
+ osmo_timer_schedule(&paging_bts->work_timer, tdiff.tv_sec, tdiff.tv_nsec / 1000);
+ return;
+ }
+ }
+
/* handle the paging request now */
page_ms(request);
paging_bts->available_slots--;
+ request->last_attempt_ts = now;
request->attempts++;
num_paged++;
@@ -237,7 +266,7 @@ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_b
/* Once done iterating, prepare next scheduling: */
sched_next_iter:
- osmo_timer_schedule(&paging_bts->work_timer, 0, 500000);
+ osmo_timer_schedule(&paging_bts->work_timer, initial_period.tv_sec, initial_period.tv_nsec / 1000);
}
static void paging_worker(void *data)