pespin has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-bsc/+/30347 )


Change subject: paging: Replace reqs waiting for retransmission with new 
incoming inital req if queue is full
......................................................................

paging: Replace reqs waiting for retransmission with new incoming inital req if 
queue is full

If queue size (in transmit delay of requests) is too long (above
threshold) when a new initial incoming request arrives, instead of
directly discarding it, see if we can drop a pending retransmission and
insert the new one instead, in order to avoid losing initial requests.

This is done under the assumption that is it more important to transmit
intial requests than to retransmit already transmitted ones. The
rationale is that there's lower chances than an MS which didn't answer
lately will answer now (aka being reachable at the cell), so it's better
to allocate resources for new requests (new MS) which may be available
in the cell.

Related: OS#5552
Change-Id: Idfd93254ae456b1ee08416e05479488299dd063d
---
M src/osmo-bsc/paging.c
1 file changed, 42 insertions(+), 8 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/47/30347/1

diff --git a/src/osmo-bsc/paging.c b/src/osmo-bsc/paging.c
index 32ae627..50cc1ed 100644
--- a/src/osmo-bsc/paging.c
+++ b/src/osmo-bsc/paging.c
@@ -416,17 +416,10 @@
        unsigned int reqs_before = 0, reqs_before_same_pgroup = 0;
        uint8_t pgroup = gsm0502_calc_paging_group(&bts->si_common.chan_desc,
                                                   
str_to_imsi(params->bsub->imsi));
+       bool queue_full = false;

        rate_ctr_inc(rate_ctr_group_get_ctr(bts->bts_ctrs, 
BTS_CTR_PAGING_ATTEMPTED));

-       /* Don't try to queue more requests than we can realistically handle 
within X3113 seconds,
-        * see PAGING_THRESHOLD_X3113_DEFAULT_SEC. */
-       OSMO_ASSERT(td_x3113);
-       if (paging_pending_requests_nr(bts) > 
paging_estimate_available_slots(bts, td_x3113->val)) {
-               rate_ctr_inc(rate_ctr_group_get_ctr(bts->bts_ctrs, 
BTS_CTR_PAGING_OVERLOAD));
-               return -ENOSPC;
-       }
-
        /* 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");
@@ -434,6 +427,22 @@
                return -EEXIST;
        }

+       /* Don't try to queue more requests than we can realistically handle 
within X3113 seconds,
+        * see PAGING_THRESHOLD_X3113_DEFAULT_SEC. */
+       OSMO_ASSERT(td_x3113);
+       if (paging_pending_requests_nr(bts) > 
paging_estimate_available_slots(bts, td_x3113->val)) {
+               struct gsm_paging_request *last_req;
+               rate_ctr_inc(rate_ctr_group_get_ctr(bts->bts_ctrs, 
BTS_CTR_PAGING_OVERLOAD));
+               OSMO_ASSERT(!llist_empty(&bts_entry->pending_requests));
+               last_req = llist_last_entry(&bts_entry->pending_requests, 
struct gsm_paging_request, entry);
+               if (last_req->attempts == 0) {
+                       /* Queue is full of initial requests, discard new one */
+                       return -ENOSPC;
+               }
+               /* There's at least 1 retrans. Flag to remove first retrans in 
queue once found below. */
+               queue_full = true;
+       }
+
        /* 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
@@ -465,6 +474,31 @@
                        reqs_before_same_pgroup++;
        }
 
+       /* Need to drop a retrans from the queue if possible, in order to make 
space for the new initial req. */
+       if (queue_full) {
+               if (!last_initial_req) {
+                       /* Queue is full of retransmissions only, drop first 
one to free some space: */
+                       struct gsm_paging_request *first_retrans_req;
+                       first_retrans_req = 
llist_first_entry_or_null(&bts_entry->pending_requests, struct 
gsm_paging_request, entry);
+                       OSMO_ASSERT(first_retrans_req);
+                       reqs_before--;
+                       if (first_retrans_req->pgroup == pgroup)
+                               reqs_before_same_pgroup--;
+                       paging_remove_request(first_retrans_req);
+               } else {
+                       struct gsm_paging_request *last_req;
+                       last_req = 
llist_last_entry(&bts_entry->pending_requests, struct gsm_paging_request, 
entry);
+                       OSMO_ASSERT(last_req);
+                       if (&last_initial_req->entry == 
llist_last(&bts_entry->pending_requests)) {
+                               /* Queue is full of initial requests only, 
discard the current new req: */
+                               return -ENOSPC;
+                       }
+                       /* We checked beforehand (set queue_full = true) that 
queue contains a retrans.
+                        * Hence queue contains [1..N intials, 1..N retrans]: 
Drop first retransmission to free some space: */
+                       
paging_remove_request(llist_entry(last_initial_req->entry.next, struct 
gsm_paging_request, entry));
+               }
+       }
+
        LOG_PAGING_BTS(params, bts, DPAG, LOGL_DEBUG, "Start paging\n");
        req = talloc_zero(tall_paging_ctx, struct gsm_paging_request);
        OSMO_ASSERT(req);

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

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: Idfd93254ae456b1ee08416e05479488299dd063d
Gerrit-Change-Number: 30347
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>
Gerrit-MessageType: newchange

Reply via email to