paging: Fix recalculate work timer if waiting for retrans

We want to recalculate the timer based on last time the work_timer was
triggered (that is, the time when the worker re-armed the pag req to
retransmit). We don't want to recalculate based on the last time the pag
ret tro retransmit was scheduled.

In loaded paging queue, there's lots of retrans (let's say 200) and it
may take more than 500ms to actually retransmit them. That means in most
cases we could end up in a situation where only pag req to retrans where
in the queue, hitting this recalculate path. Since the 500ms were for
sure elapsed, that would most probably schedule the work_timer at {0,0}
for each new paging request that arrived. As a result, the worker would
be scheduled lots of times per second (once for each new req arriving)
and only submitting 1 pag req (the new one) plus potentially 1 or
serveral pag req to retransmit.

In summary, there was not throthling applied in the scenario where only
pag req to retransmit where in the queue and new pag reqs kept arriving.
This incurrs into augmented paging throughput and also augmented
frequency of polls().

Related: OS#5922
Fixes: 4821c9f4df
Change-Id: I7ce6f436286b50dc31331d218ff256cf7be3f619
This commit is contained in:
Pau Espin 2022-05-05 18:20:15 +02:00 committed by pespin
parent 38db714588
commit cdd2bbd8b8
2 changed files with 5 additions and 4 deletions

View File

@ -106,6 +106,9 @@ struct gsm_bts_paging_state {
struct osmo_timer_list work_timer;
struct osmo_timer_list credit_timer;
/* Last time paging worker was triggered */
struct timespec last_sched_ts;
/* free chans needed */
int free_chans_need;

View File

@ -225,6 +225,7 @@ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_b
goto sched_next_iter;
osmo_clock_gettime(CLOCK_MONOTONIC, &now);
paging_bts->last_sched_ts = 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
@ -458,11 +459,8 @@ static int _paging_request(const struct bsc_paging_params *params, struct gsm_bt
* which is a longer period.
* Let's recaculate the time to adapt it to initial_period: */
struct timespec now, elapsed, tdiff;
struct gsm_paging_request *first_retrans_req;
osmo_clock_gettime(CLOCK_MONOTONIC, &now);
/* This is what used to be the first req (retrans state) in the queue: */
first_retrans_req = llist_entry(req->entry.next, struct gsm_paging_request, entry);
timespecsub(&now, &first_retrans_req->last_attempt_ts, &elapsed);
timespecsub(&now, &bts_entry->last_sched_ts, &elapsed);
if (timespeccmp(&elapsed, &initial_period, <)) {
timespecsub(&initial_period, &elapsed, &tdiff);
} else {