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: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
  • Loading branch information
teburd authored and lyakh committed Aug 27, 2024
1 parent 47a0813 commit 3a2c476
Showing 1 changed file with 47 additions and 0 deletions.
47 changes: 47 additions & 0 deletions subsys/llext/llext.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,59 @@ int llext_load(struct llext_loader *ldr, const char *name, struct llext **ext,
return ret;
}

#include <zephyr/logging/log_ctrl.h>

extern struct k_thread logging_thread;

static void llext_log_flush(void)
{
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);
}

Check notice on line 225 in subsys/llext/llext.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/llext/llext.c:225 - if (adjust_log) + if (adjust_log) { k_thread_priority_set(&logging_thread, target_prio); + } log_thread_trigger(); k_yield(); - if (adjust_log) + if (adjust_log) { k_thread_priority_set(&logging_thread, log_prio); - if (adjust_cur) + } + if (adjust_cur) { k_thread_priority_set(&logging_thread, cur_prio); + }

Check notice on line 225 in subsys/llext/llext.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

subsys/llext/llext.c:225 - if (adjust_log) + if (adjust_log) { k_thread_priority_set(&logging_thread, target_prio); + } log_thread_trigger(); k_yield(); - if (adjust_log) + if (adjust_log) { k_thread_priority_set(&logging_thread, log_prio); - if (adjust_cur) + } + if (adjust_cur) { k_thread_priority_set(&logging_thread, cur_prio); + }

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 3a2c476

Please sign in to comment.