pespin has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-pcu/+/40885?usp=email )
Change subject: llc_queue: Store MetaInfo in msgb headroom instead of cb[]
......................................................................
llc_queue: Store MetaInfo in msgb headroom instead of cb[]
"sizeof(*meta_storage) <= sizeof(llc_msg->cb)" assert fails on debian 13
armv7l.
Since struct MetaInfo cannot always fit inside msgb->cb, move the struct
MetaInfo into the headroom of the msgb.
Related: OS#6831
Change-Id: I98d966c257d50d3b2fc326dce85ead5591acf51f
---
M src/gprs_ms.c
M src/llc.c
M src/llc.h
M tests/llc/LlcTest.cpp
4 files changed, 35 insertions(+), 42 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-pcu refs/changes/85/40885/1
diff --git a/src/gprs_ms.c b/src/gprs_ms.c
index ff7316b..1577a4a 100644
--- a/src/gprs_ms.c
+++ b/src/gprs_ms.c
@@ -1369,13 +1369,10 @@
LOGPMS(ms, DTBFDL, LOGL_DEBUG, "appending %u bytes to DL LLC queue\n", len);
- struct msgb *llc_msg = msgb_alloc(len, "llc_pdu_queue");
- if (!llc_msg)
- return -ENOMEM;
-
llc_queue_calc_pdu_lifetime(ms->bts, pdu_delay_csec, &expire_time);
- memcpy(msgb_put(llc_msg, len), data, len);
- llc_queue_enqueue(ms_llc_queue(ms), llc_msg, &expire_time);
+ rc = llc_queue_enqueue(ms_llc_queue(ms), data, len, &expire_time);
+ if (rc < 0)
+ return rc;
ms_start_llc_timer(ms);
dl_tbf = ms_dl_tbf(ms);
diff --git a/src/llc.c b/src/llc.c
index 633ae49..478d23d 100644
--- a/src/llc.c
+++ b/src/llc.c
@@ -141,24 +141,34 @@
}
}
-void llc_queue_enqueue(struct gprs_llc_queue *q, struct msgb *llc_msg, const struct
timespec *expire_time)
+int llc_queue_enqueue(struct gprs_llc_queue *q, const uint8_t *data, uint16_t len, const
struct timespec *expire_time)
{
+ struct msgb *llc_msg;
struct MetaInfo *meta_storage;
- struct gprs_llc_hdr *llc_hdr = (struct gprs_llc_hdr *)msgb_data(llc_msg);
+ struct gprs_llc_hdr *llc_hdr;
enum gprs_llc_queue_prio prio;
- osmo_static_assert(sizeof(*meta_storage) <= sizeof(llc_msg->cb),
info_does_not_fit);
+ llc_msg = msgb_alloc_headroom(sizeof(*meta_storage) + len, sizeof(*meta_storage),
"llc_pdu_queue");
+ if (!llc_msg)
+ return -ENOMEM;
- prio = llc_sapi2prio(llc_hdr->sapi);
-
- q->queue_size += 1;
- q->queue_octets += msgb_length(llc_msg);
-
- meta_storage = (struct MetaInfo *)&llc_msg->cb[0];
+ /* Fist set up MetaInfo in the msgb headroom: */
+ meta_storage = (struct MetaInfo *)llc_msg->head;
osmo_clock_gettime(CLOCK_MONOTONIC, &meta_storage->recv_time);
meta_storage->expire_time = *expire_time;
+ /* Copy PDU to msgb data: */
+ llc_hdr = (struct gprs_llc_hdr *)msgb_put(llc_msg, len);
+ memcpy(llc_hdr, data, len);
+
+ prio = llc_sapi2prio(llc_hdr->sapi);
+
+ /* Append: */
+ q->queue_size += 1;
+ q->queue_octets += msgb_length(llc_msg);
msgb_enqueue(&q->pq[prio].queue, llc_msg);
+
+ return 0;
}
void llc_queue_clear(struct gprs_llc_queue *q, struct gprs_rlcmac_bts *bts)
@@ -205,8 +215,8 @@
msg = msg1;
msg1 = NULL;
} else {
- const struct MetaInfo *mi1 = (struct MetaInfo *)&msg1->cb[0];
- const struct MetaInfo *mi2 = (struct MetaInfo *)&msg2->cb[0];
+ const struct MetaInfo *mi1 = (struct MetaInfo *)msg1->head;
+ const struct MetaInfo *mi2 = (struct MetaInfo *)msg2->head;
if (timespeccmp(&mi2->recv_time, &mi1->recv_time, >)) {
msg = msg1;
@@ -236,20 +246,21 @@
/* Prepend / Put back a previously dequeued LLC frame (llc_queue_dequeue()) */
void llc_queue_merge_prepend(struct gprs_llc_queue *q, const struct gprs_llc *llc)
{
+ struct msgb *llc_msg;
struct MetaInfo *meta_storage;
unsigned int len = llc_frame_length(llc);
- struct msgb *llc_msg = msgb_alloc(len, "llc_pdu_queue");
+ llc_msg = msgb_alloc_headroom(sizeof(*meta_storage) + len, sizeof(*meta_storage),
"llc_pdu_queue");
OSMO_ASSERT(llc_msg);
- memcpy(msgb_put(llc_msg, len), llc->frame, len);
- q->queue_size += 1;
- q->queue_octets += msgb_length(llc_msg);
-
- meta_storage = (struct MetaInfo *)&llc_msg->cb[0];
+ meta_storage = (struct MetaInfo *)llc_msg->head;
memcpy(meta_storage, &llc->meta_info, sizeof(struct MetaInfo));
+ memcpy(msgb_put(llc_msg, len), llc->frame, len);
+
/* Prepend: */
+ q->queue_size += 1;
+ q->queue_octets += msgb_length(llc_msg);
llist_add(&llc_msg->list, &q->pq[llc->prio].queue);
}
@@ -272,7 +283,7 @@
if (!msg)
return NULL;
- meta_storage = (struct MetaInfo *)&msg->cb[0];
+ meta_storage = (struct MetaInfo *)msg->head;
q->queue_size -= 1;
q->queue_octets -= msgb_length(msg);
@@ -305,7 +316,7 @@
timespecadd(&tv_now, &hyst_delta, &tv_now2);
while ((msg = llc_queue_pick_msg(q, &prio))) {
- info = (const struct MetaInfo *)&msg->cb[0];
+ info = (const struct MetaInfo *)msg->head;
const struct timespec *tv_disc = &info->expire_time;
const struct timespec *tv_recv = &info->recv_time;
diff --git a/src/llc.h b/src/llc.h
index b9f3180..31e427d 100644
--- a/src/llc.h
+++ b/src/llc.h
@@ -139,7 +139,7 @@
void llc_queue_set_codel_interval(struct gprs_llc_queue *q, unsigned int interval);
void llc_queue_move_and_merge(struct gprs_llc_queue *q, struct gprs_llc_queue *o);
void llc_queue_merge_prepend(struct gprs_llc_queue *q, const struct gprs_llc *llc);
-void llc_queue_enqueue(struct gprs_llc_queue *q, struct msgb *llc_msg, const struct
timespec *expire_time);
+int llc_queue_enqueue(struct gprs_llc_queue *q, const uint8_t *data, uint16_t len, const
struct timespec *expire_time);
struct msgb *llc_queue_dequeue(struct gprs_llc_queue *q, enum gprs_llc_queue_prio
*out_prio, struct MetaInfo *out_info);
static inline size_t llc_queue_size(const struct gprs_llc_queue *q)
diff --git a/tests/llc/LlcTest.cpp b/tests/llc/LlcTest.cpp
index 9ed6f21..c0101fb 100644
--- a/tests/llc/LlcTest.cpp
+++ b/tests/llc/LlcTest.cpp
@@ -56,21 +56,6 @@
return ms_llc_queue(ms);
}
-static void enqueue_data(gprs_llc_queue *queue, const uint8_t *data, size_t len,
- const struct timespec *expire_time)
-{
- struct timespec *tv;
- uint8_t *msg_data;
- struct msgb *llc_msg = msgb_alloc(len + sizeof(*tv) * 2,
- "llc_pdu_queue");
-
- msg_data = (uint8_t *)msgb_put(llc_msg, len);
-
- memcpy(msg_data, data, len);
-
- llc_queue_enqueue(queue, llc_msg, expire_time);
-}
-
static void dequeue_and_check(gprs_llc_queue *queue, const uint8_t *exp_data,
size_t len, const MetaInfo *exp_info)
{
@@ -96,7 +81,7 @@
static void enqueue_data(gprs_llc_queue *queue, const char *message,
const struct timespec *expire_time)
{
- enqueue_data(queue, (uint8_t *)(message), strlen(message), expire_time);
+ llc_queue_enqueue(queue, (uint8_t *)(message), strlen(message), expire_time);
}
static void dequeue_and_check(gprs_llc_queue *queue, const char *exp_message,
--
To view, visit
https://gerrit.osmocom.org/c/osmo-pcu/+/40885?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: osmo-pcu
Gerrit-Branch: master
Gerrit-Change-Id: I98d966c257d50d3b2fc326dce85ead5591acf51f
Gerrit-Change-Number: 40885
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin(a)sysmocom.de>