vprintk_unlocked() formats straight to the character output hook, which
lives in kernel memory and cannot be reached from a user thread. Since
assert_print() uses it, an assert taken in user mode faults instead of
printing. tests/ztest/error_hook times out on qemu_arc/qemu_arc_em and
dies on qemu_x86.
Use the same buffered path vprintk() already uses for user threads,
handing the result to the kernel through k_str_out(), and route
printk_unlocked() through vprintk_unlocked() so both variants agree.
The lock free property is kept: k_str_out() skips the lock once
printk_panic() has been called.
Introduced by commit 0ecb6caf0f ("lib: os: assert: print the
assertion message unlocked").
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
printk_unlocked() serves callers that know they cannot lock, not the ones
that find out too late. A fault taken inside printk() leaves the spinlock
held by a context about to die, so every later printk() blocks and the
crash report is lost along with everything after it. CONFIG_SPIN_VALIDATE
makes it louder rather than better: validation fails, the assertion is
reported through printk, and the system spins there repeating itself.
That happens on a uniprocessor too, where the lock is uncontended but
still recorded as held.
Converting call sites cannot fix it, because code reached after the
failure does not know it is in a crash. So make printk() itself aware:
printk_panic() switches it to the unlocked path and the reporting paths
call it before emitting anything.
The switch is one way. Clearing it would also require releasing the
orphaned lock, and telling "orphaned" from "held by a CPU that is still
running" needs the owner, which only CONFIG_SPIN_VALIDATE records. So a
system that has reported a fatal error keeps unserialized output for the
rest of its life, which costs interleaving and no content.
Linux does the same: bust_spinlocks(), called from its oops and panic
paths, raises oops_in_progress so printk skips console locking. This
mechanism is narrower, printk simply stops locking, but the reasoning is
identical.
Because it cannot be undone, it must only be thrown once the fault is
terminal, which rules out the architecture entry points: several return.
z_arm64_fatal_error() resumes once demand paging has serviced the fault,
so switching there would cost a paging system its printk locking on the
first page fault. EXCEPTION_DUMP() runs only after the recoverable cases
are ruled out and also covers arch-specific dumps such as the Cortex-M
one behind PR_FAULT_INFO, and z_fatal_error() covers reports with no
dump, like k_panic() from a failed assertion. OpenRISC switches at entry
because it reports with LOG_ERR(), which is safe there since its handler
never returns.
k_str_out() shares the lock and honours the switch, so crashes reported
through printf() or puts() are covered too.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
An assertion can fire from inside printk()'s own locked region, where
reporting through vprintk() takes a spinlock this CPU already holds. The
lock is not recursive, so the message never appears and the CPU hangs
where it was supposed to say what went wrong. CONFIG_SPIN_VALIDATE makes
that worse: the validation failure is itself reported through
assert_print(), so it recurses until the stack is gone. The lock may
equally be held by another CPU that cannot release it, which is the
situation an assertion is likely reporting.
Use vprintk_unlocked() so the message goes out regardless.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
printk() is unusable where its spinlock cannot be taken, and Zephyr has
no answer for any of the three cases. A fatal error or failed assertion
may happen with the lock held, by the failing context itself or by a CPU
that will never release it, so reporting hangs instead of printing. An
assertion firing mid-message deadlocks on the same non-recursive lock.
And on some architectures the atomics a spinlock is built from do not
work until the MMU is on, so an early printk() faults.
Add printk_unlocked() and vprintk_unlocked(). They never take the lock,
and bypass the logging subsystem and the user mode buffer because those
have locks of their own, going straight to the platform's character
output hook. Output may interleave with a concurrent printk(), which
beats deadlocking or losing it.
Formatting is factored into vprintk_core() and shared with printk(), so
both produce identical text and only the locking differs. Nothing changes
for existing callers.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Add prompt to CBPRINTF_CONVERT_CHECK_PTR and extend the description.
Runtime string validation takes ~500 bytes of code (on riscv32) and
additional time when creating a log message so there are cases where
user would like to disable it.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Refactor function to gain code space. Function takes significant
amount of code due to suboptimal implemention. Refactor to
reduce code (1200->800 on riscv32).
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
User code should not re-define prototypes defined in C library headers,
but, for prototypes of extensions (like strnlen()) should reuqest them
by setting the appropriate feature test macro.
So, instead of defining the strnlen() prototype in the user code, let's
set the appropriate SOURCE macro and get the prototype from its header
(string.h).
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
'round' is a standard library identifier reserved for any use, so
naming a local after it violates MISRA C:2012 Rule 21.2.
Rename it to 'rounding', which also reads better next to the comment
about rounding to the last printed digit. Pure rename.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
In CONFIG_SCHED_CPU_MASK_PIN_ONLY mode a thread must always have
exactly one CPU bit set in its mask. The static_init() code was
unconditionally calling k_thread_cpu_mask_clear() for threads with
K_P4WQ_USER_CPU_MASK, which zeroes the mask and violates the
PIN_ONLY invariant.
After commit 7798570a03 this violation triggers an assertion in
cpu_mask_mod(), preventing SOF (and any other PIN_ONLY user of p4wq
with USER_CPU_MASK) from booting.
Fix by guarding the k_thread_cpu_mask_clear() call with
!CONFIG_SCHED_CPU_MASK_PIN_ONLY. Under PIN_ONLY the thread keeps
its default pin (CPU 0) until k_p4wq_enable_static_thread() sets the
real affinity via k_thread_cpu_pin().
Fixes: 7798570a03 ("kernel: sched: enforce non-zero CPU mask invariant
in PIN_ONLY mode")
Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
The periodic report and the threshold callback sampled cpu_load_get(),
i.e. the CPU that the timer happened to expire on. Which CPU that is on
SMP is arbitrary, and it is usually not the loaded one, so the reported
load and the callbacks described a CPU picked at random.
Iterate over the CPUs instead and report each one, so the report says
something well defined on SMP and the threshold callback fires for the
CPU that actually crossed it. On a single-CPU system this is exactly what
it did before, one report per period.
The initialization only resets the current CPU: SYS_INIT runs at
POST_KERNEL, while the secondary CPUs are brought up at INIT_LEVEL_SMP,
so their per-CPU kernel state does not exist yet and touching it faults.
The other CPUs simply start their first window at the first report.
Bound the iteration with arch_num_cpus() rather than the configured
maximum, so only CPUs that actually exist are sampled.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Idle time was only added to a CPU's total once its idle window closed. A
CPU that is idle right now still has an open window, so a reader on
another CPU saw no idle time at all for it and reported a 100% load for a
CPU that was doing nothing.
Fold the still-open window into the value returned by cpu_load_get_cpu(),
and re-open it at the sampling point when the window is reset so the idle
time just accounted for is not counted twice when it eventually closes.
This can only happen for a CPU other than the reader's own, which is by
definition not idle.
Two locking fixes come with it, both only reachable now that another CPU
can sample an open window:
- The idle-enter hook publishes enter_ts and the open flag under the
per-CPU lock, so a reader cannot observe a half-updated window.
- The idle-exit hook takes its timestamp under the lock. A reader that
moves enter_ts forward between the stamp and the lock would otherwise
make the delta go negative and wrap.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The idle-hook backend closed its idle window from the idle-exit hook that
the architecture runs after the wait instruction. That only works on
architectures which wait with interrupts locked (Arm, RISC-V): the wait
returns without servicing the interrupt, so the exit hook runs before any
ISR.
Architectures that wait with interrupts enabled (x86 "sti; hlt", Xtensa
"waiti 0") let the wake-up ISR run first, and it can reschedule away from
the idle thread. The idle-exit hook is then deferred until the idle thread
is next scheduled, long after idle actually ended, so the busy time in
between is attributed to idle. Measured on qemu_xtensa, a window that was
100% idle reported a load of 1000 per mille instead of 0.
Make closing the window idempotent and also drive it from the ISR entry
hook, sys_trace_isr_enter().
The first interrupt after the CPU went idle is exactly the instant idle
ended, so closing there is accurate; a deferred idle-exit hook then finds
the window already closed and does nothing. Interrupts that did not
interrupt idle only pay one flag test.
Architectures that wait with interrupts locked are unaffected: their
idle-exit hook still closes the window before any ISR runs.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The idle-hook CPU load backend kept a single global set of idle-tracking
state (enter_ts, cyc_start, ticks_idle), so it could only ever describe
one CPU and would race if several CPUs entered idle concurrently. That
is why it depended on !SMP.
Make the state per-CPU. The idle enter/exit hooks run on the idle CPU
with interrupts locked, so each CPU only mutates its own slot; a per-CPU
spinlock serializes the accumulation done in the exit hook against a
reader on another CPU calling cpu_load_get_cpu(). The !SMP dependency is
dropped.
The optional hardware counter path stays single-CPU, as a single shared
counter cannot track the idle time of several CPUs concurrently, so
CPU_LOAD_USE_COUNTER now depends on !SMP.
Replace the hard-coded architecture allowlist with a dependency on the
new ARCH_HAS_CPU_IDLE_HOOKS capability, which expresses the actual
requirement. Also guard against a division by zero when the measurement
window is empty, which back-to-back resets now make reachable.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The two CPU load modules that previously lived side by side (the
scheduler-runtime-statistics metric in lib/os/cpu_load_metric and the
idle-hook measurement in lib/os/cpu_load) are merged into a single
CONFIG_CPU_LOAD module with a pluggable backend selected through the
CPU_LOAD_BACKEND choice:
- CPU_LOAD_BACKEND_RUNTIME_STATS: scheduler runtime statistics,
portable and multi-CPU capable (formerly CPU_LOAD_METRIC).
- CPU_LOAD_BACKEND_IDLE_HOOK: architecture idle hooks, low overhead
with an optional hardware counter, single CPU.
A shared feature layer above the backends provides the current-CPU
getter, the periodic report timer and the threshold callback, so both
backends gain the periodic logging and callback features. The unified
getter pair returns the load in per mille:
int cpu_load_get(bool reset); /* current CPU */
int cpu_load_get_cpu(unsigned int cpu_id, bool reset);
CONFIG_CPU_LOAD_METRIC and cpu_load_metric_get() are kept as deprecated
compatibility wrappers; the latter returns percent as before. The
<zephyr/sys/cpu_load_metric.h> header now just includes
<zephyr/sys/cpu_load.h>. The tracing backends now gate the idle
accounting on CPU_LOAD_BACKEND_IDLE_HOOK rather than CPU_LOAD, since the
idle hooks only exist for that backend.
The cpu_freq on-demand policy is migrated to cpu_load_get_cpu() and
selects CPU_LOAD together with the new CPU_LOAD_MULTICPU helper to pull
in the runtime-statistics backend.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The idle-hook based CPU load module lived under subsys/debug, required
CONFIG_TRACING, and exposed its API through <zephyr/debug/cpu_load.h>.
It does not conceptually belong to the debug subsystem, and its only
dependency on tracing was the idle notification hooks, now available
through CONFIG_SYS_IDLE_HOOKS.
Move the module to lib/os/cpu_load with its own CMakeLists and Kconfig,
relocate the public header to <zephyr/sys/cpu_load.h>, and select
SYS_IDLE_HOOKS instead of TRACING. Update all includers (the tracing
backends, samples and tests) to the new header path.
CONFIG_CPU_LOAD now builds and runs without the tracing subsystem.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The scheduler-runtime-stats based CPU load module lived in
lib/os/cpu_load and exposed cpu_load_metric_get() through
<zephyr/sys/cpu_load.h>. Its logging module name (CPU_LOAD) collided
with the idle-hook based CPU load module, and the shared directory and
header name made the two hard to tell apart.
Move the module to lib/os/cpu_load_metric, rename the source and public
header to cpu_load_metric.c and <zephyr/sys/cpu_load_metric.h>, and give
it its own log module (CPU_LOAD_METRIC) so the two no longer share a log
level symbol. Update the cpu_freq on-demand policy and its sample and
test to include the renamed header and use
CONFIG_CPU_LOAD_METRIC_LOG_LEVEL_DBG.
This frees the lib/os/cpu_load directory and the sys/cpu_load.h header
for the idle-hook based module, which moves there next.
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The `cbprintf_cb` callback function taken by `cbvprintf()` may return a
negative number to indicate an I/O error. The `str_out()` function can
never error (it just copies the input to a buffer), but it always returns
its input. For regular ASCII input, this is merely nonsense; however, when
writing out a character with its MSB set (e.g., UTF-8-encoded text), the
character is sign-extended, and the function returns a negative number.
This is interpreted as an error by `outs()` (in `cbprintf_complete.c`), and
so printing concludes after a single character.
For example, prior to this change, the assertion in this snippet fails:
char buf[16];
int len = snprintfcb(buf, sizeof(buf), "\xED\xA0\xBD\xED\xB1\x8D");
assert(len == 6);
Signed-off-by: Samuel Coleman <samuel.coleman@rbr-global.com>
the boot banner is printed at the end of
the init process with
``SYS_INIT(boot_banner, APPLICATION, 0);``
we don't need the early console for it.
When CONFIG_EARLY_CONSOLE is enabled,
the console will init with PRE_KERNEL_1, otherwise
with POST_KERNEL. Both are before APPLICATION.
For compatibility `EARLY_CONSOLE` will now be enabled by default,
as it was selected by the boot banner before, that is also
enabled by default.
Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
Added option CONFIG_LOG_PRINTK_STATIC which redirects printk's to
logging macro which creates message during compilation by examining
argument types using _Generic keyword. When this option is enabled
printk format string is not accessed in runtime so it can be removed
(e.g. in dictionary based logging). When this option is enabled printk
is much faster. Option is implied when dictionary based logging is
enabled.
The only condition that must be met to use build time message creation
macros is that format string is a string literal and not a variable.
That is the case for printk because it is using __printf_like gcc
extension to validate that.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Similarly to the existing CONFIG_ZVFS_OPEN_ADD_SIZE_* mechanism used to
size the file descriptor table, allow subsystems to declare their eventfd
count requirements via CONFIG_ZVFS_EVENTFD_ADD_SIZE_* Kconfig options.
These are summed up at build time and compared against
CONFIG_ZVFS_EVENTFD_MAX, with the larger of the two values used to size
the eventfd table, exposed as the ZVFS_EVENTFD_SIZE compile definition.
A new CONFIG_ZVFS_EVENTFD_IGNORE_MIN option allows to override the
calculated requirement and use CONFIG_ZVFS_EVENTFD_MAX as-is.
As each eventfd also consumes a file descriptor, the resulting eventfd
count is now reserved in the file descriptor table as well, replacing the
former CONFIG_ZVFS_OPEN_ADD_SIZE_EVENTFD option which only accounted for
CONFIG_ZVFS_EVENTFD_MAX.
The WPA supplicant requirement is moved from a CONFIG_ZVFS_EVENTFD_MAX
default into a dedicated
CONFIG_ZVFS_EVENTFD_ADD_SIZE_WIFI_NM_WPA_SUPPLICANT option.
Assisted-by: Cursor:Claude Opus 4.8
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Replace z_unpend_first_thread() with z_unpend_first_thread_locked() and
migrate every caller across the kernel. The old function dropped the
scheduler spinlock before returning, exposing a race window between
its caller's "arch_thread_return_value_set + z_ready_thread" pair and
a still-in-flight timeout handler that could ready the thread first --
the woken thread might then run on another CPU and see an uninitialized
swap_retval. Pre-1b8c7a3 the dticks-cancel check made the handler bail;
here we fix it cleanly by requiring the caller to hold _sched_spinlock
across the entire wake, so the handler is blocked for the duration and
runs as a no-op afterwards.
z_unpend_first_thread_locked() requires the caller to be inside a
locked region and must be paired with z_sched_ready_locked() (and
whatever return-value setup is needed) under the same lock acquisition.
Sites migrated:
Simple "set retval [+ swap_data] and ready" callers use the existing
z_sched_wake() convenience wrapper, refactored to use the new
helper internally:
sem (give, reset), mem_slab (free), stack (push),
condvar (signal, broadcast), msgq (purge),
queue (cancel_wait, queue_insert, append_list),
futex (wake).
Sites that need additional setup on the woken thread use
LOCK_SCHED_SPINLOCK + z_unpend_first_thread_locked() + custom wake:
mutex (unlock -- needs the thread reference to track new owner),
msgq put / get (needs memcpy into the receiver's swap_data
buffer before the return value is set).
The dticks-cancel check in z_thread_timeout() is left in place; it is
no longer load-bearing once z_abort_thread_timeout() has no callers,
and is removed in the next commit.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
When CONFIG_POSIX_DEVICE_IO and CONFIG_PICOLIBC are enabled,
stdinout_write_vmeth will return 0, causing the write function to
busy-wait forever on file descriptor 1 (stdout).
This change makes the function work with Picolibc, so we can use
write with file descriptor 1 to output data to the stdout_hook of
picolibc.
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
Since commit 37717b229f ("sys: util: rename Z_MIN Z_MAX Z_CLAMP to min
max and clamp"), <zephyr/sys/util.h> unconditionally defines function-
like macros named `min`, `max`, and `clamp` in the global namespace (in
C mode). util.h gets pulled in transitively by very broad headers,
including the POSIX layer's <pthread.h>, so any third-party C code that
uses these names as ordinary identifiers (e.g. XNNPACK's static `clamp`
helper and its public `clamp` struct field) fails to build as soon as
<pthread.h> is included.
Following the approach used by Linux, move the lowercase `min`, `max`,
`min3`, `max3`, and `clamp` macros (and their helpers) into a new
<zephyr/sys/minmax.h> header that has to be included explicitly by
source files that want them. util.h keeps the uppercase MIN/MAX/CLAMP,
so most code is unaffected; only the (much smaller) set of files that
actually use the lowercase variants needs to pick up the new include.
Fixes#107853.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
the boot banner is printed at the end of
the init process with
``SYS_INIT(boot_banner, APPLICATION, 0);``
we don't need the early console for it.
When CONFIG_EARLY_CONSOLE is enabled,
the console will init with PRE_KERNEL_1, otherwise
with POST_KERNEL. Both are before APPLICATION.
Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
When cbvprintf_package() packages a %s argument, append_string()
eventually calls strlen(str) on the pointer. If the caller passed
NULL to %s, strlen() dereferences address 0. On MMU-less targets
this is undefined behavior; on TF-M targets the SPU fields a read
at address 0 as SECURE_FAULT, which aborts the whole image.
Passing NULL to %s is a caller bug. However, deferred/packaged
logging captures the argument now and dereferences it later,
disconnecting the crash site from the offending call site and
making triage significantly harder. Substitute "(null)" in place
of a NULL string, matching the behavior of glibc's printf family,
so the buggy caller shows up in the log output rather than the
log infrastructure crashing.
Signed-off-by: Diego Solano <diegosolano@gmail.com>
The CONFIG_NET_SOCKETS_POLL_MAX Kconfig option was deprecated in
Zephyr 4.0.0, remove it and any leftover in-tree option use.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Introduces K_MEM_SLAB_DEFINE_TYPE() and K_MEM_SLAB_DEFINE_STATIC_TYPE()
helpers to allow the user to declare slabs for types without having to
manually ensure the alignment is correct.
Manual slab alignment was very error-prone and this change fixes several
instances of misalignment that would be trapped by the undefined
behavior sanitizer when running on 64-bit targets.
Signed-off-by: Egill Sigurdur <egill@egill.xyz>
This moves the atomic_c.c from kernel to lib/os as atomic
functions are not exactly kernel features.
This also moves all the atomic kconfigs from kernel to lib/os
as the atomic headers are already under include/zephyr/sys/.
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This moves boot arguments from kernel into the lib/os.
This is not strictly a kernel function so this change provides
a separation between core kernel functionalities and others.
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
Boot banner is not exactly a kernel feature. It is more like
an OS feature so moving it into lib/os.
Signed-off-by: Daniel Leung <daniel.leung@intel.com>
The cbprintf_cb typedef used an empty parameter list () which in C23
is equivalent to (void), making it incompatible with any callback
function that takes parameters.
Fix by giving cbprintf_cb a proper prototype (int c, void *ctx),
removing the now-redundant cbprintf_cb_local typedef, and adding
explicit (cbprintf_cb) casts at call sites where the callback has a
different signature (fputc, sprintf_out).
Signed-off-by: Shuai Ma <Shuai.MA@cn.bosch.com>
Replace ternary operator with if-else to avoid mixing signed and unsigned
types in the conditional expression. This eliminates the compiler warning
while preserving the original logic.
Fixes#104581
Signed-off-by: Roman Bakshansky <bakshansky@protonmail.com>
Add missing memory barriers after branching on k_is_user_context() to
prevent reordering possible of privileged memory access.
Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
Use the zvfs macros in the code of the module itself, instead of using
the versions from the POSIX API, and remove the header that defined those
as it is not needed anymore.
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
Add option to use default alignment when building a cbprintf package
on riscv (rv32e). It is useful in case when cbprintf packages are not
formatted on rv32e but on another core. There is such case on nrf54h20
where log messages are formatted by the ARM Cortex M33 core (cpuapp)
and without this option 64 bit arguments are incorrectly formatted.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
There is no need to pull in POSIX types in either of the modified files,
so remove the `<sys/types.h>` inclusion.
Signed-off-by: Chris Friedt <chris@fr4.co>
Fixes this define leaking into all application source files when
the feature is not even enabled
Co-authored-by: Chris Friedt <cfriedt@tenstorrent.com>
Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
k_condvar_broadcast does not error. It returns the number of
woken threads on success. We should not assert any value.
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
When eventfd is used through read(2) and write(2), the mutex is
already locked from the fdtable implementation. So we remove the
usage of the mutex from the zvfs_eventfd_*_op functions, as it is
already managed by fdtable.
However, when zvfs_eventfd_{read,write} are used, no fdtable layer
is used and we shuld call the _op function with the mutex locked
(the same behavior as with fdtable), so these functions should
manage the mutex. We add it there.
Fixes#99234
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
C99 § 7.19.6.5 defines `snprintf`. According to ¶ 2:
> If `n` is zero, nothing is written, and `s` may be a null pointer.
And according to § 7.19.6.12 ¶ 2:
> The `vsnprintf` function is equivalent to `snprintf` (...)
However, prior to this change, `vsnprintfcb` (and indirectly, `snprintfcb`)
unconditionally null-terminates the output buffer.
This fixes#48394, which was auto-closed without actually being fixed.
Co-authored-by: Adrien Lessard <adrien.lessard@rbr-global.com>
Signed-off-by: Samuel Coleman <samuel.coleman@rbr-global.com>
Previously, eventfd file descriptors were not being counted against the
required size for the global file descriptor table, which would result
in the function `eventfd()` (and `zvfs_eventfd()`) failing due to
insufficient resources.
Signed-off-by: Chris Friedt <chris@fr4.co>
We currently only disable "normal" IRQs with irq_lock(). This is not
sufficient if ZLIs are enabled, as even though they are supposed to
be "above" the kernel, they must not interrupt the poweroff procedure.
Signed-off-by: Bjarki Arge Andreasen <bjarki.andreasen@nordicsemi.no>