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


Change subject: WIP: llc: schedule frames to MS based on SAPI priority
......................................................................

WIP: llc: schedule frames to MS based on SAPI priority

Related: OS#5508
Related: SYS#5908
Change-Id: Ie8bd91eeac4fa7487d4f11b808dea95737041c7e
---
M src/llc.c
M src/llc.h
2 files changed, 91 insertions(+), 37 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/27/27627/1

diff --git a/src/llc.c b/src/llc.c
index 700585a..d333920 100644
--- a/src/llc.c
+++ b/src/llc.c
@@ -96,19 +96,40 @@

 void llc_queue_init(struct gprs_llc_queue *q)
 {
-       INIT_LLIST_HEAD(&q->queue);
+       int i;
+
        q->queue_size = 0;
        q->queue_octets = 0;
        q->avg_queue_delay = 0;
+       for (i = 0; i < ARRAY_SIZE(q->queue); i++)
+               INIT_LLIST_HEAD(&q->queue[i]);
 }


+static enum gprs_llc_queue_prio llc_sapi2prio(uint8_t sapi)
+{
+       switch (sapi) {
+               case 1:
+                       return LLC_QUEUE_PRIO_GMM;
+               case 2:
+               case 7:
+               case 8:
+                       return LLC_QUEUE_PRIO_TOM_SMS;
+               default:
+                       return LLC_QUEUE_PRIO_OTHER;
+       }
+}
+
 void llc_queue_enqueue(struct gprs_llc_queue *q, struct msgb *llc_msg, const 
struct timespec *expire_time)
 {
        struct MetaInfo *meta_storage;
+       struct gprs_llc_hdr *llc_hdr = (struct gprs_llc_hdr 
*)msgb_data(llc_msg);
+       enum gprs_llc_queue_prio prio;

        osmo_static_assert(sizeof(*meta_storage) <= sizeof(llc_msg->cb), 
info_does_not_fit);

+       prio = llc_sapi2prio(llc_hdr->sapi);
+
        q->queue_size += 1;
        q->queue_octets += msgb_length(llc_msg);

@@ -116,17 +137,20 @@
        osmo_clock_gettime(CLOCK_MONOTONIC, &meta_storage->recv_time);
        meta_storage->expire_time = *expire_time;

-       msgb_enqueue(&q->queue, llc_msg);
+       msgb_enqueue(&q->queue[prio], llc_msg);
 }

 void llc_queue_clear(struct gprs_llc_queue *q, struct gprs_rlcmac_bts *bts)
 {
        struct msgb *msg;
+       unsigned int i;

-       while ((msg = msgb_dequeue(&q->queue))) {
-               if (bts)
-                       bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_DROPPED);
-               msgb_free(msg);
+       for (i = 0; i < ARRAY_SIZE(q->queue); i++) {
+               while ((msg = msgb_dequeue(&q->queue[i]))) {
+                       if (bts)
+                               bts_do_rate_ctr_inc(bts, CTR_LLC_FRAME_DROPPED);
+                       msgb_free(msg);
+               }
        }

        q->queue_size = 0;
@@ -137,51 +161,53 @@
 {
        struct msgb *msg, *msg1 = NULL, *msg2 = NULL;
        struct llist_head new_queue;
+       unsigned int i;
        size_t queue_size = 0;
        size_t queue_octets = 0;
        INIT_LLIST_HEAD(&new_queue);

-       while (1) {
-               if (msg1 == NULL)
-                       msg1 = msgb_dequeue(&q->queue);
+       for (i = 0; i < ARRAY_SIZE(q->queue); i++) {
+               while (1) {
+                       if (msg1 == NULL)
+                               msg1 = msgb_dequeue(&q->queue[i]);

-               if (msg2 == NULL)
-                       msg2 = msgb_dequeue(&o->queue);
+                       if (msg2 == NULL)
+                               msg2 = msgb_dequeue(&o->queue[i]);

-               if (msg1 == NULL && msg2 == NULL)
-                       break;
+                       if (msg1 == NULL && msg2 == NULL)
+                               break;

-               if (msg1 == NULL) {
-                       msg = msg2;
-                       msg2 = NULL;
-               } else if (msg2 == NULL) {
-                       msg = msg1;
-                       msg1 = NULL;
-               } else {
-                       const struct MetaInfo *mi1 = (struct MetaInfo 
*)&msg1->cb[0];
-                       const struct MetaInfo *mi2 = (struct MetaInfo 
*)&msg2->cb[0];
-
-                       if (timespeccmp(&mi2->recv_time, &mi1->recv_time, >)) {
+                       if (msg1 == NULL) {
+                               msg = msg2;
+                               msg2 = NULL;
+                       } else if (msg2 == NULL) {
                                msg = msg1;
                                msg1 = NULL;
                        } else {
-                               msg = msg2;
-                               msg2 = NULL;
+                               const struct MetaInfo *mi1 = (struct MetaInfo 
*)&msg1->cb[0];
+                               const struct MetaInfo *mi2 = (struct MetaInfo 
*)&msg2->cb[0];
+
+                               if (timespeccmp(&mi2->recv_time, 
&mi1->recv_time, >)) {
+                                       msg = msg1;
+                                       msg1 = NULL;
+                               } else {
+                                       msg = msg2;
+                                       msg2 = NULL;
+                               }
                        }
+
+                       msgb_enqueue(&new_queue, msg);
+                       queue_size += 1;
+                       queue_octets += msgb_length(msg);
                }

-               msgb_enqueue(&new_queue, msg);
-               queue_size += 1;
-               queue_octets += msgb_length(msg);
+               OSMO_ASSERT(llist_empty(&q->queue[i]));
+               OSMO_ASSERT(llist_empty(&o->queue[i]));
+               llist_splice_init(&new_queue, &q->queue[i]);
        }

-       OSMO_ASSERT(llist_empty(&q->queue));
-       OSMO_ASSERT(llist_empty(&o->queue));
-
        o->queue_size = 0;
        o->queue_octets = 0;
-
-       llist_splice_init(&new_queue, &q->queue);
        q->queue_size = queue_size;
        q->queue_octets = queue_octets;
 }
@@ -193,9 +219,13 @@
        struct msgb *msg;
        struct timespec *tv, tv_now, tv_result;
        uint32_t lifetime;
+       unsigned int i;
        const struct MetaInfo *meta_storage;

-       msg = msgb_dequeue(&q->queue);
+       for (i = 0; i < ARRAY_SIZE(q->queue); i++) {
+               if ((msg = msgb_dequeue(&q->queue[i])))
+                       break;
+       }
        if (!msg)
                return NULL;

diff --git a/src/llc.h b/src/llc.h
index bd542c0..035fe77 100644
--- a/src/llc.h
+++ b/src/llc.h
@@ -1,4 +1,4 @@
-/*
+/* 3GPP TS 44.064
  * Copyright (C) 2013 by Holger Hans Peter Freyther
  * Copyright (C) 2022 by by Sysmocom s.f.m.c. GmbH
  *
@@ -23,13 +23,31 @@
 #include <string.h>
 #include <time.h>

+#include <osmocom/core/endian.h>
 #include <osmocom/core/linuxlist.h>
 #include <osmocom/core/msgb.h>
+#include <osmocom/core/endian.h>

 #define LLC_MAX_LEN 1543

 struct gprs_rlcmac_bts;

+struct gprs_llc_hdr {
+#if OSMO_IS_LITTLE_ENDIAN
+       union { /* 5.2, 6.2.0 */
+               uint8_t address;
+               uint8_t sapi:4, unused:2, c_r:1, pd:1;
+#elif OSMO_IS_BIG_ENDIAN
+/* auto-generated from the little endian part above 
(libosmocore/contrib/struct_endianess.py) */
+       union {
+               uint8_t address;
+               uint8_t pd:1, c_r:1, unused:2, sapi:4;
+#endif
+       };
+       uint8_t control[0];
+/* TODO: fix for big endian/little endian */
+} __attribute__ ((packed));
+
 /**
  * I represent the LLC data to a MS
  */
@@ -87,11 +105,17 @@
 /**
  * I store the LLC frames that come from the SGSN.
  */
+enum gprs_llc_queue_prio { /* lowest value has highest prio */
+       LLC_QUEUE_PRIO_GMM = 0, /* SAPI 1 */
+       LLC_QUEUE_PRIO_TOM_SMS, /* SAPI 2,7,8 */
+       LLC_QUEUE_PRIO_OTHER, /* Other SAPIs */
+       _LLC_QUEUE_PRIO_SIZE /* used to calculate size of enum */
+};
 struct gprs_llc_queue {
        uint32_t avg_queue_delay; /* Average delay of data going through the 
queue */
        size_t queue_size;
        size_t queue_octets;
-       struct llist_head queue; /* queued LLC DL data */
+       struct llist_head queue[_LLC_QUEUE_PRIO_SIZE]; /* queued LLC DL data. 
See enum gprs_llc_queue_prio. */
 };

 void llc_queue_calc_pdu_lifetime(struct gprs_rlcmac_bts *bts, const uint16_t 
pdu_delay_csec,

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

Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Change-Id: Ie8bd91eeac4fa7487d4f11b808dea95737041c7e
Gerrit-Change-Number: 27627
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <[email protected]>
Gerrit-MessageType: newchange

Reply via email to