modem: cmux: Implement modem backend statistics

Implement modem backend statistics into modem CMUX DLCI
channel receive buffer and CMUX transmit and receive buffers.

Signed-off-by: Bjarki Arge Andreasen <bjarki@arge-andreasen.me>
This commit is contained in:
Bjarki Arge Andreasen 2024-05-10 14:23:38 +02:00 committed by Johan Hedberg
parent 9f45102299
commit b636327601
2 changed files with 116 additions and 0 deletions

View File

@ -25,6 +25,7 @@
#include <zephyr/sys/atomic.h>
#include <zephyr/modem/pipe.h>
#include <zephyr/modem/stats.h>
#ifndef ZEPHYR_MODEM_CMUX_
#define ZEPHYR_MODEM_CMUX_
@ -102,6 +103,11 @@ struct modem_cmux_dlci {
/* State */
enum modem_cmux_dlci_state state;
/* Statistics */
#if CONFIG_MODEM_STATS
struct modem_stats_buffer receive_buf_stats;
#endif
};
struct modem_cmux_frame {
@ -160,6 +166,12 @@ struct modem_cmux {
/* Synchronize actions */
struct k_event event;
/* Statistics */
#if CONFIG_MODEM_STATS
struct modem_stats_buffer receive_buf_stats;
struct modem_stats_buffer transmit_buf_stats;
#endif
};
/**

View File

@ -144,6 +144,54 @@ static void modem_cmux_log_received_frame(const struct modem_cmux_frame *frame)
modem_cmux_log_frame(frame, "rcvd", frame->data_len);
}
#if CONFIG_MODEM_STATS
static uint32_t modem_cmux_get_receive_buf_length(struct modem_cmux *cmux)
{
return cmux->receive_buf_len;
}
static uint32_t modem_cmux_get_receive_buf_size(struct modem_cmux *cmux)
{
return cmux->receive_buf_size;
}
static uint32_t modem_cmux_get_transmit_buf_length(struct modem_cmux *cmux)
{
return ring_buf_size_get(&cmux->transmit_rb);
}
static uint32_t modem_cmux_get_transmit_buf_size(struct modem_cmux *cmux)
{
return ring_buf_capacity_get(&cmux->transmit_rb);
}
static void modem_cmux_init_buf_stats(struct modem_cmux *cmux)
{
uint32_t size;
size = modem_cmux_get_receive_buf_size(cmux);
modem_stats_buffer_init(&cmux->receive_buf_stats, "cmux_rx", size);
size = modem_cmux_get_transmit_buf_size(cmux);
modem_stats_buffer_init(&cmux->transmit_buf_stats, "cmux_tx", size);
}
static void modem_cmux_advertise_transmit_buf_stats(struct modem_cmux *cmux)
{
uint32_t length;
length = modem_cmux_get_transmit_buf_length(cmux);
modem_stats_buffer_advertise_length(&cmux->transmit_buf_stats, length);
}
static void modem_cmux_advertise_receive_buf_stats(struct modem_cmux *cmux)
{
uint32_t length;
length = modem_cmux_get_receive_buf_length(cmux);
modem_stats_buffer_advertise_length(&cmux->receive_buf_stats, length);
}
#endif
static const char *modem_cmux_command_type_to_str(enum modem_cmux_command_types command_type)
{
switch (command_type) {
@ -649,6 +697,10 @@ static void modem_cmux_on_dlci_frame(struct modem_cmux *cmux)
static void modem_cmux_on_frame(struct modem_cmux *cmux)
{
#if CONFIG_MODEM_STATS
modem_cmux_advertise_receive_buf_stats(cmux);
#endif
if (cmux->frame.dlci_address == 0) {
modem_cmux_on_control_frame(cmux);
} else {
@ -658,6 +710,10 @@ static void modem_cmux_on_frame(struct modem_cmux *cmux)
static void modem_cmux_drop_frame(struct modem_cmux *cmux)
{
#if CONFIG_MODEM_STATS
modem_cmux_advertise_receive_buf_stats(cmux);
#endif
LOG_WRN("Dropped frame");
cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_SOF;
@ -884,6 +940,10 @@ static void modem_cmux_transmit_handler(struct k_work *item)
k_mutex_lock(&cmux->transmit_rb_lock, K_FOREVER);
#if CONFIG_MODEM_STATS
modem_cmux_advertise_transmit_buf_stats(cmux);
#endif
while (true) {
transmit_rb_empty = ring_buf_is_empty(&cmux->transmit_rb);
@ -975,6 +1035,36 @@ static void modem_cmux_disconnect_handler(struct k_work *item)
k_work_schedule(&cmux->disconnect_work, MODEM_CMUX_T1_TIMEOUT);
}
#if CONFIG_MODEM_STATS
static uint32_t modem_cmux_dlci_get_receive_buf_length(struct modem_cmux_dlci *dlci)
{
return ring_buf_size_get(&dlci->receive_rb);
}
static uint32_t modem_cmux_dlci_get_receive_buf_size(struct modem_cmux_dlci *dlci)
{
return ring_buf_capacity_get(&dlci->receive_rb);
}
static void modem_cmux_dlci_init_buf_stats(struct modem_cmux_dlci *dlci)
{
uint32_t size;
char name[sizeof("dlci_xxxxx_rx")];
size = modem_cmux_dlci_get_receive_buf_size(dlci);
snprintk(name, sizeof(name), "dlci_%u_rx", dlci->dlci_address);
modem_stats_buffer_init(&dlci->receive_buf_stats, name, size);
}
static void modem_cmux_dlci_advertise_receive_buf_stat(struct modem_cmux_dlci *dlci)
{
uint32_t length;
length = modem_cmux_dlci_get_receive_buf_length(dlci);
modem_stats_buffer_advertise_length(&dlci->receive_buf_stats, length);
}
#endif
static int modem_cmux_dlci_pipe_api_open(void *data)
{
struct modem_cmux_dlci *dlci = (struct modem_cmux_dlci *)data;
@ -1010,6 +1100,11 @@ static int modem_cmux_dlci_pipe_api_receive(void *data, uint8_t *buf, size_t siz
uint32_t ret;
k_mutex_lock(&dlci->receive_rb_lock, K_FOREVER);
#if CONFIG_MODEM_STATS
modem_cmux_dlci_advertise_receive_buf_stat(dlci);
#endif
ret = ring_buf_get(&dlci->receive_rb, buf, size);
k_mutex_unlock(&dlci->receive_rb_lock);
return ret;
@ -1126,6 +1221,10 @@ void modem_cmux_init(struct modem_cmux *cmux, const struct modem_cmux_config *co
k_event_init(&cmux->event);
k_event_clear(&cmux->event, MODEM_CMUX_EVENT_CONNECTED_BIT);
k_event_post(&cmux->event, MODEM_CMUX_EVENT_DISCONNECTED_BIT);
#if CONFIG_MODEM_STATS
modem_cmux_init_buf_stats(cmux);
#endif
}
struct modem_pipe *modem_cmux_dlci_init(struct modem_cmux *cmux, struct modem_cmux_dlci *dlci,
@ -1148,6 +1247,11 @@ struct modem_pipe *modem_cmux_dlci_init(struct modem_cmux *cmux, struct modem_cm
k_work_init_delayable(&dlci->close_work, modem_cmux_dlci_close_handler);
dlci->state = MODEM_CMUX_DLCI_STATE_CLOSED;
sys_slist_append(&dlci->cmux->dlcis, &dlci->node);
#if CONFIG_MODEM_STATS
modem_cmux_dlci_init_buf_stats(dlci);
#endif
return &dlci->pipe;
}