From 9a85a89313b18fbfed2e966ff62f8efaea3f4b7f Mon Sep 17 00:00:00 2001 From: Krzysztof Chruscinski Date: Tue, 6 Apr 2021 11:44:04 +0200 Subject: [PATCH] shell: logging: Fix assertion when shell is overflowed with logging When shell had too many pending log messages it was attempting to drop expired messages and retrying to put the new message. There was an assumption that enough messages are dropped and new message can be put. It may not be the case if no message expired during given time. Wrapped the operation in loop to continue until expired message is freed and new message is enqueued. Signed-off-by: Krzysztof Chruscinski --- subsys/shell/shell_log_backend.c | 45 ++++++++++++++++---------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/subsys/shell/shell_log_backend.c b/subsys/shell/shell_log_backend.c index 613e00285cf..9fa9fca6dc1 100644 --- a/subsys/shell/shell_log_backend.c +++ b/subsys/shell/shell_log_backend.c @@ -92,36 +92,37 @@ static void msg_to_fifo(const struct shell *shell, struct log_msg *msg) { int err; + bool cont; struct shell_log_backend_msg t_msg = { .msg = msg, .timestamp = k_uptime_get_32() }; - err = k_msgq_put(shell->log_backend->msgq, &t_msg, - K_MSEC(shell->log_backend->timeout)); + do { + cont = false; + err = k_msgq_put(shell->log_backend->msgq, &t_msg, + K_MSEC(shell->log_backend->timeout)); - switch (err) { - case 0: - break; - case -EAGAIN: - case -ENOMSG: - { - flush_expired_messages(shell); + switch (err) { + case 0: + break; + case -EAGAIN: + case -ENOMSG: + { + /* Attempt to drop old message. */ + flush_expired_messages(shell); - err = k_msgq_put(shell->log_backend->msgq, &msg, K_NO_WAIT); - if (err) { - /* Unexpected case as we just freed one element and - * there is no other context that puts into the msgq. - */ - __ASSERT_NO_MSG(0); + /* Retry putting message. */ + cont = true; + + break; } - break; - } - default: - /* Other errors are not expected. */ - __ASSERT_NO_MSG(0); - break; - } + default: + /* Other errors are not expected. */ + __ASSERT_NO_MSG(0); + break; + } + } while (cont); } void z_shell_log_backend_disable(const struct shell_log_backend *backend)