paging: Use bsub->active_paging_requests to allow early loop termination adding paging_req
Before this patch, the entire queue of paging_request had to be iterated in order to find if the subscriber already had an active paging request (discarding duplicates). Now that bsc_subscriber holds a list of its active paging requests, it's easier to look at its list to find out if it is already active on that BTS. As a result, there's no need to unconditionally iterate the whole list and we can optimize the loop finding the spot to insert the new queue: - First the potentially way smaller loop over bsub->active_paging_requests is done - Second, only if the first loop allowed, the bts->pending_requests is iterated and potentially early terminated. Related: SYS#6200 Change-Id: I7912275026c4d4983269c8870aa5565c93277c5a
This commit is contained in:
parent
70a1d60a83
commit
0ed7700c1e
|
@ -415,31 +415,42 @@ static int _paging_request(const struct bsc_paging_params *params, struct gsm_bt
|
|||
return -ENOSPC;
|
||||
}
|
||||
|
||||
/* Iterate list of pending requests to find if we already have one for
|
||||
* the given subscriber. While on it, find the last
|
||||
* not-yet-ever-once-transmitted request; the new request will be added
|
||||
* immediately after it, giving higher prio to initial transmissions
|
||||
* (no retrans). This avoids new subscribers being paged to be delayed
|
||||
* if the paging queue is full due to a lot of retranmissions.
|
||||
/* Find if we already have one for the given subscriber on this BTS: */
|
||||
if (bsc_subscr_find_req_by_bts(params->bsub, bts)) {
|
||||
LOG_PAGING_BTS(params, bts, DPAG, LOGL_INFO, "Paging request already pending for this subscriber\n");
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(bts->bts_ctrs, BTS_CTR_PAGING_ALREADY));
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
/* Find the last not-yet-ever-once-transmitted request; the new request
|
||||
* will be added immediately after it, giving higher prio to initial
|
||||
* transmissions (no retrans). This avoids new subscribers being paged to
|
||||
* be delayed if the paging queue is full due to a lot of retranmissions.
|
||||
* Retranmissions usually mean MS are not reachable/available, so the
|
||||
* rationale here is to prioritize new subs which may be available. */
|
||||
* rationale here is to prioritize new subs which may be available.
|
||||
*/
|
||||
llist_for_each_entry(req, &bts_entry->pending_requests, entry) {
|
||||
if (params->bsub == req->bsub) {
|
||||
LOG_PAGING_BTS(params, bts, DPAG, LOGL_INFO, "Paging request already pending for this subscriber\n");
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(bts->bts_ctrs, BTS_CTR_PAGING_ALREADY));
|
||||
return -EEXIST;
|
||||
}
|
||||
if (req->attempts == 0) {
|
||||
/* Keep counting no-retransmits (general and per same pgroup): */
|
||||
last_initial_req = req;
|
||||
reqs_before++;
|
||||
if (req->pgroup == pgroup)
|
||||
reqs_before_same_pgroup++;
|
||||
} else if (last_initial_req == NULL) {
|
||||
/* If no req with attempts=0 was found, we'll append to end of list, so keep counting. */
|
||||
reqs_before++;
|
||||
if (req->pgroup == pgroup)
|
||||
reqs_before_same_pgroup++;
|
||||
continue;
|
||||
}
|
||||
/* Here first retransmit in queue is reached: */
|
||||
if (last_initial_req) {
|
||||
/* There were no-retransmit in the queue, done
|
||||
* iterating, new req will be inserted here
|
||||
* (see below the current loop). */
|
||||
break;
|
||||
}
|
||||
|
||||
/* last_initial_req == NULL: No req with attempts=0 was found,
|
||||
* we'll append to end of list, so keep counting. */
|
||||
reqs_before++;
|
||||
if (req->pgroup == pgroup)
|
||||
reqs_before_same_pgroup++;
|
||||
}
|
||||
|
||||
LOG_PAGING_BTS(params, bts, DPAG, LOGL_DEBUG, "Start paging\n");
|
||||
|
|
Loading…
Reference in New Issue