aboutsummaryrefslogtreecommitdiffstats
path: root/src/tbf_dl.cpp
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2022-04-04 13:45:56 +0200
committerpespin <pespin@sysmocom.de>2022-04-05 11:16:17 +0000
commit6b1e9515c9e82f8e99128a4de051889e82e25892 (patch)
treeab808e66cf2084ed4e3155eb84a11204fbb3b02d /src/tbf_dl.cpp
parent9c2512a638368f5b74c275c38d404414cf2d8b02 (diff)
llc_queue: Refactor to handle codel_state per prio queue internally
A CoDel state per prio queue is needed, otherwise the sojourn time state is not properly reset when a high prio packet is dequeued. If we have a global codel state shared for all prio queues of an MS, then basically high prio (GMM) packets will "never" be dropped because they are handled/dequeued way quicker, so it's sojourn time will be below the threshold most probably, stopping the "dropping" state for the rest of lower prio packets. The handling of different codel states is moved from MS object to the llc_queue, also offloading already loaded dl_tbf.cpp in the process. This will also allow in the future setting different CoDel parameters for different priority queues if needed. Tests need to be adapted since now the CoDel and PDU lifetime are incorporated into the llc_queue_dequeue(). Also because dequeue now also accesses related MS fields. Related: OS#5508 Change-Id: I2bce2e82ab6389d8a70130a5c26a966a316b0fa4
Diffstat (limited to 'src/tbf_dl.cpp')
-rw-r--r--src/tbf_dl.cpp79
1 files changed, 1 insertions, 78 deletions
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index 01b8f684..9c99cf6d 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -343,83 +343,6 @@ int dl_tbf_handle(struct gprs_rlcmac_bts *bts,
return rc;
}
-struct msgb *gprs_rlcmac_dl_tbf::llc_dequeue(bssgp_bvc_ctx *bctx)
-{
- struct msgb *msg;
- struct timespec tv_now, tv_now2;
- uint32_t octets = 0, frames = 0;
- struct timespec hyst_delta = {0, 0};
- const unsigned keep_small_thresh = 60;
- const MetaInfo *info;
-
- if (the_pcu->vty.llc_discard_csec)
- csecs_to_timespec(the_pcu->vty.llc_discard_csec, &hyst_delta);
-
- osmo_clock_gettime(CLOCK_MONOTONIC, &tv_now);
- timespecadd(&tv_now, &hyst_delta, &tv_now2);
-
- while ((msg = llc_queue_dequeue(llc_queue(), &info))) {
- const struct timespec *tv_disc = &info->expire_time;
- const struct timespec *tv_recv = &info->recv_time;
-
- gprs_bssgp_update_queue_delay(tv_recv, &tv_now);
-
- if (ms() && ms_codel_state(ms())) {
- int bytes = llc_queue_octets(llc_queue());
- if (gprs_codel_control(ms_codel_state(ms()),
- tv_recv, &tv_now, bytes))
- goto drop_frame;
- }
-
- /* Is the age below the low water mark? */
- if (!llc_queue_is_frame_expired(&tv_now2, tv_disc))
- break;
-
- /* Is the age below the high water mark */
- if (!llc_queue_is_frame_expired(&tv_now, tv_disc)) {
- /* Has the previous message not been dropped? */
- if (frames == 0)
- break;
-
- /* Hysteresis mode, try to discard LLC messages until
- * the low water mark has been reached */
-
- /* Check whether to abort the hysteresis mode */
-
- /* Is the frame small, perhaps only a TCP ACK? */
- if (msg->len <= keep_small_thresh)
- break;
-
- /* Is it a GMM message? */
- if (!llc_is_user_data_frame(msg->data, msg->len))
- break;
- }
-
- bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_TIMEDOUT);
-drop_frame:
- frames++;
- octets += msg->len;
- msgb_free(msg);
- bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_DROPPED);
- continue;
- }
-
- if (frames) {
- LOGPTBFDL(this, LOGL_NOTICE, "Discarding LLC PDU "
- "because lifetime limit reached, "
- "count=%u new_queue_size=%zu\n",
- frames, llc_queue_size(llc_queue()));
- if (frames > 0xff)
- frames = 0xff;
- if (octets > 0xffffff)
- octets = 0xffffff;
- if (bctx)
- bssgp_tx_llc_discarded(bctx, tlli(), frames, octets);
- }
-
- return msg;
-}
-
bool gprs_rlcmac_dl_tbf::restart_bsn_cycle()
{
/* If V(S) == V(A) and finished state, we would have received
@@ -628,7 +551,7 @@ void gprs_rlcmac_dl_tbf::schedule_next_frame()
return;
/* dequeue next LLC frame, if any */
- msg = llc_dequeue(bts->pcu->bssgp.bctx);
+ msg = llc_queue_dequeue(llc_queue());
if (!msg)
return;