Skip to content

Commit

Permalink
llext: flush logging before unloading extensions
Browse files Browse the repository at this point in the history
Extensions could have used logging, when log processing is
deferred, the logging thread can run after the extension has
been unloaded and thereby access invalid memory addresses.
Make sure to flush all logs before unloading extensions.

Signed-off-by: Tom Burdick <thomas.burdick@intel.com>
Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
  • Loading branch information
teburd authored and lyakh committed Aug 29, 2024
1 parent 386263c commit b18b810
Showing 1 changed file with 51 additions and 0 deletions.
51 changes: 51 additions & 0 deletions subsys/llext/llext.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,63 @@ int llext_load(struct llext_loader *ldr, const char *name, struct llext **ext,
return ret;
}

#include <zephyr/logging/log_ctrl.h>

static void llext_log_flush(void)
{
#ifdef CONFIG_LOG_MODE_DEFERRED
extern struct k_thread logging_thread;
int cur_prio = k_thread_priority_get(k_current_get());
int log_prio = k_thread_priority_get(&logging_thread);
int target_prio;
bool adjust_cur, adjust_log;

/*
* Our goal is to raise the logger thread priority above current, but if
* current has the highest possble priority, both need to be adjusted,
* particularly if the logger thread has the lowest possible priority
*/
if (log_prio < cur_prio) {
adjust_cur = false;
adjust_log = false;
target_prio = 0;
} else if (cur_prio == K_HIGHEST_THREAD_PRIO) {
adjust_cur = true;
adjust_log = true;
target_prio = cur_prio;
k_thread_priority_set(k_current_get(), cur_prio + 1);
} else {
adjust_cur = false;
adjust_log = true;
target_prio = cur_prio - 1;
}

/* adjust logging thread priority if needed */
if (adjust_log) {
k_thread_priority_set(&logging_thread, target_prio);
}

log_thread_trigger();
k_yield();

if (adjust_log) {
k_thread_priority_set(&logging_thread, log_prio);
}
if (adjust_cur) {
k_thread_priority_set(&logging_thread, cur_prio);
}
#endif
}

int llext_unload(struct llext **ext)
{
__ASSERT(*ext, "Expected non-null extension");
struct llext *tmp = *ext;

k_mutex_lock(&llext_lock, K_FOREVER);

llext_log_flush();

__ASSERT(tmp->use_count, "A valid LLEXT cannot have a zero use-count!");

if (tmp->use_count-- != 1) {
Expand Down

0 comments on commit b18b810

Please sign in to comment.