The delete flag is not synchronized with the life cycle of the group,
if the flag set before waitpid(), the tcb will be mistakenly deleted
by group_del_waiter(), use-after-free will happen.
Regression by:
| commit 29e50ffa73 (origin/master, origin/HEAD)
| Author: chao an <anchao@lixiang.com>
| Date: Mon Mar 4 09:19:27 2024 +0800
|
| sched/group: move task group into task_tcb_s to improve performance
|
| move task group into task_tcb_s to avoid access allocator to improve performance
|
| for Task Termination, the time consumption will be reduced ~2us (Tricore TC397 300MHZ):
| 15.97(us) -> 13.55(us)
|
| Signed-off-by: chao an <anchao@lixiang.com>
Signed-off-by: chao an <anchao@lixiang.com>
move task group into task_tcb_s to avoid access allocator to improve performance
for Task Termination, the time consumption will be reduced ~2us (Tricore TC397 300MHZ):
15.97(us) -> 13.55(us)
Signed-off-by: chao an <anchao@lixiang.com>
Skip the child wait if here is only self in member list,
since the members of the task group should be 1 if task exit.
Fix Regression issue that the task could not terminate normally.
Signed-off-by: chao an <anchao@lixiang.com>
Change the type of task group member to single list chain to
avoid accessing the memory allocator to improve the performance
Signed-off-by: chao an <anchao@lixiang.com>
The maximum startup parameters have been checked accordingly in nxtask_setup_stackargs(),
let us save argument counter to avoid limit check.
Signed-off-by: chao an <anchao@lixiang.com>
Task group could find from process id, replace group_findbypid to
task_getgroup to simplify the search logic
Signed-off-by: chao an <anchao@lixiang.com>
Current `CONFIG_PAGING` refers to an experimental implementation
to enable embedded MCUs with some limited RAM space to execute
large programs from some non-random access media.
On-demand paging should be implemented for the kernel mode with
address environment implementation enabled.
Add support for static tcb, applications in some special case can
initialize system resources in advance through static tcb.
| static struct task_tcb_s g_tcb;
|
| memset(&g_tcb, 0, sizeof(struct task_tcb_s));
| g_tcb.cmn.flags = TCB_FLAG_TTYPE_KERNEL;
| nxtask_init(&g_tcb, "PTCB", 101, NULL, 1024, ptcb_task, NULL, NULL, NULL);
|
| ...
| nxtask_activate(&g_tcb.cmn);
Signed-off-by: chao an <anchao@lixiang.com>
Recursive:
25 0x44000e5a in up_cpu_paused (cpu=cpu@entry=1) at armv7-a/arm_cpupause.c:120
26 0x440032f2 in enter_critical_section () at irq/irq_csection.c:275
27 0x44006f24 in nxsched_process_taskload_ticks (tcb=tcb@entry=0x442ba638 <g_idletcb+256>, ticks=0) at sched/sched_cpuload.c:104
28 0x44007310 in nxsched_suspend_critmon (tcb=tcb@entry=0x442ba638 <g_idletcb+256>) at sched/sched_critmonitor.c:303
29 0x44006ef0 in nxsched_suspend_scheduler (tcb=tcb@entry=0x442ba638 <g_idletcb+256>) at sched/sched_suspendscheduler.c:78
30 0x44000e5a in up_cpu_paused (cpu=cpu@entry=1) at armv7-a/arm_cpupause.c:120
31 0x440032f2 in enter_critical_section () at irq/irq_csection.c:275
32 0x44000f1a in arm_pause_handler (irq=<optimized out>, context=<optimized out>, arg=<optimized out>) at armv7-a/arm_cpupause.c:216
33 0x44002ffe in irq_dispatch (irq=irq@entry=2, context=context@entry=0x4449f6b8 <g_cpu1_idlestack+1720>) at irq/irq_dispatch.c:146
34 0x44001612 in arm_doirq (irq=2, irq@entry=0, regs=0x4449f6b8 <g_cpu1_idlestack+1720>) at armv7-a/arm_doirq.c:72
35 0x44000940 in arm_decodeirq (regs=<optimized out>) at armv7-a/arm_gicv2.c:403
36 0x440000b4 in arm_vectorirq () at armv7-a/arm_vectors.S:236
Signed-off-by: ligd <liguiding1@xiaomi.com>
cpu0 thread0: cpu1:
sched_yield()
nxsched_set_priority()
nxsched_running_setpriority()
nxsched_reprioritize_rtr()
nxsched_add_readytorun()
up_cpu_pause()
IRQ enter
arm64_pause_handler()
enter_critical_section() begin
up_cpu_paused() pick thread0
arm64_restorestate() set thread0 tcb->xcp.regs to CURRENT_REGS
up_switch_context()
thread0 -> thread1
arm64_syscall()
case SYS_switch_context
change thread0 tcb->xcp.regs
restore_critical_section()
enter_critical_section() done
leave_critical_section()
IRQ leave with restore CURRENT_REGS
ERROR !!!
Reason:
As descript above, cpu0 swith task: thread0 -> thread1, and the
syscall() execute slowly, this time cpu1 pick thread0 to run at
up_cpu_paused(). Then cpu0 syscall execute, cpu1 IRQ leave error.
Resolve:
Move arm64_restorestate() after enter_critical_section() done
This is a continued fix with:
https://github.com/apache/nuttx/pull/6833
Signed-off-by: ligd <liguiding1@xiaomi.com>
These variables will trigger variable 'ret' set but not used warnings due to different configurations.
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
Task activation/exit logs are helpful for device bringup,
especially when user space nsh prompt doesn't show up.
Putting them here will allow cleaning of logs in multiple
up_exit() functions later.
Signed-off-by: Yanfeng Liu <yfliu2008@qq.com>
Usually the startup script is placed under /etc. The contents of the etc directory
are compiled and linked with Nuttx binary in the form of romfs. After startup,
it will be mounted by Nsh.
etc is generated by the different boards, that use genromfs and xxd tools to generate
and compile it into the Nuttx, for example: boards/arm/at32/at32f437-mini/tool/mkromfs.sh
The more common method is etc image generated from the content in the corresponding
board/arch/board/board/src/etc directory, and added by Makefile for example:
boards/sim/sim/sim/src/etc.
But in kernel/protected mode, Nuttx kernel and apps are run in different privileged/
non-privileged mode or the isolated binarys, so as that nsh should use syscall to
access Nuttx kernel by exported API. In this scenario, nsh can not mount the etc image
content, because that is generated in board and as a part of Nuttx kernel.
changes:
- move etc romfs mount from nsh to Nuttx, but keep the script to parse and execute.
- move and rename the related CONFIG, move customized nsh_romfsimg.h to etc_romfs.c
in boards, and no need declaration for romfs_img/romfs_img_len.
This commit changes and updates all configurations in Nuttx arch/board as much as possible,
but if any missing, please refer to the following simple guide:
- rename CONFIG_NSH_ROMFSETC to CONFIG_ETC_ROMFS, and delete CONFIG_NSH_ARCHROMFS in defconfig
- rename the etc romfs mount configs, for example CONFIG_NSH_FATDEVNO to CONFIG_ETC_FATDEVNO
- move customized nsh_romfsimg.h to etc_romfs.c in board/arch/board/board/src and no need
declaration for romfs_img/romfs_img_len.
- delete default nsh_romfsimg.h, if ROMFSETC is enabled, should generate and compile etc_romfs.c
in board/arch/board/board/src.
Signed-off-by: fangxinyong <fangxinyong@xiaomi.com>
Remove KEEP_ALIVE_HACK to avoid waking up the device periodly.
The workaround it's added by:
commit 6546fa39c7
Author: Gregory Nutt <gnutt@nuttx.org>
Date: Tue Aug 12 11:12:00 2014 -0600
Tickless Stuff: Back out the risky timer operations when the ready-to-run
list is modified. That is unsafe. An ugly workaround is just to keep an
interval timer going all of the time with a minimum duration equal to the
timeslice interval.
But look like it doesn't needed anymore.
Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
Usage:
1. CONFIG_FS_PROCFS_MAX_STACK_RECORD > 0, such as 32,
2. add '-finstrument-functions' to CFLAGS for What you want to check
stack.
3. mount porcfs
4. cat /proc/<pid>/stack will print backtace & size
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
If the gap between sp and stack_top is too small,
then the stack will not be output,
modify the conditional loop condition, and fix this problem
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
A new locking mechanism: read/write locks
When there is a writer it is not possible to put on a read lock or a write lock; when there is a reader it is possible to reenter the read lock but not the write lock.
Writers are exclusive locks, readers are shared locks.
At the same time through the waiter count to determine whether there is currently a blocked task, if there is then in the unlock time to wake up all the waiter, through the priority of the competition to complete the blocked lock execution.
For example:
When we have a reader blocking two waiter writers, when the reader is unlocked it wakes up both writers. The writer with higher priority wakes up and checks for a successful condition and locks the lock, the second writer wakes up and fails to check for a condition and continues to block the lock.
Signed-off-by: chenrun1 <chenrun1@xiaomi.com>
This moves all the public POSIX semaphore functions into libc and with
this most of the user-space logic is also moved; namely cancel point and
errno handling.
This also removes the need for the _SEM_XX macros used to differentiate
which API is used per user-/kernel mode. Such macros are henceforth
unnecessary.
PR #11165 causes an unnecessary regression; task_delete no longer works,
if the deleted task is from another group.
The logic that prevents this comes from:
nxnotify_cancellation() ->
tls_get_info_pid() ->
nxsched_get_stackinfo()
Which checks for permissions, which does not make sense in this case since
it is the kernel asking for the stack information.
Fix this by partially reverting 11165 and implementing a direct path for
the kernel to query for any tasks TLS.
Commit 9244b5a737 added support
for non-standard field si_user that is useful for passing context
pointers to signal handlers.
This commits makes it work for all signals, not just SA_KERNELHAND.
Previously si_user for normal signals was uninitialized garbage.
The task files should consult the "spawn action" and "O_CLOEXEC flags"
to determine further whether the file should be duplicated.
This PR will further optimize file list duplicating to avoid the performance
regression caused by additional file operations.
Signed-off-by: chao an <anchao@xiaomi.com>
This moves task / thread cancel point logic from the NuttX kernel into
libc, while the data needed by the cancel point logic is moved to TLS.
The change is an enabler to move user-space APIs to libc as well, for
a coherent user/kernel separation.
Some assertions in extreme cases will cause syslog to be unable to
output logs normally, so this PR will restore the input registers
into the array of last registers to ensure that we can also obtain
some important informations.
Signed-off-by: chao an <anchao@xiaomi.com>
If the semaphore is shared, the holder has put its own mmapped address
to pholder->sem. This means we must switch to the holder's address
environment when going through the held semaphores list.
A better option would be to get the kernel mapped address for the
semaphore's physical page, but that mechanism is not functional yet.
This fixes a full system crash when CONFIG_PRIORITY_INHERITANCE=y and
CONFIG_BUILD_KERNEL=y and user makes shared semaphore via:
int semfd = shm_open("sem", O_CREAT | O_RDWR, 0666);
sem_t *sem = mmap(0, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, semfd, 0);
Previous adjtime() implementation was limited to adjusting system
timer tick period. This commit reimplements the internals to use
a kernel watchdog timer. Platform-independent part of the code now
works also for adjusting hires RTC and tickless timer rate.
User code facing API is unchanged. Architecture code API has changed:
up_adj_timer_period() is replaced by up_adjtime().
Other improvements:
- Support query of remaining adjustment by passing NULL to first
argument of adjtime(). This matches Linux behavior.
- Improve resolution available for architecture driver, previously
limited to 1 microsecond per tick. Now 1 nanosecond per second.
Set the newly spawned process's signal mask, if the caller has instructed
to do so by setting POSIX_SPAWN_SETSIGMASK.
This is called after the task has been created but has NOT been started
yet.
Like the name implies, it is supposed to set the spawn attributes for
the NuttX specific "spawn proxy task" which was historically used as
a proxy to spawn new tasks. The proxy handled file actions and the signal
mask which are inherited from the parent.
The proxy task does not exist anymore, thus the proxy task attributes
do not need to be set anymore either.
Also, the function is currently still used, but the signal mask is set
for the spawning process, not the proxy process, and this is most
DEFINITELY an error (as the spawning process's signal mask changes
unexpectedly).
Setting the signal mask for the newly spawned process is simple, just
set it directly, if instructed to do so. This will be done in a later
patch!
VELAPLATFO-18473
refs:
https://man7.org/linux/man-pages/man2/fcntl.2.html
If the FD_CLOEXEC bit is set, the file descriptor will automatically
be closed during a successful execve(2).
(If the execve(2) fails, the file descriptor is left open.)
modify:
1. Ensure that the child task copies all fds of the parent task,
including those with O_CLOEXE.
2. Make sure spawn_file_action is executed under fd with O_CLOEXEC,
otherwise it will fail.
3. When a new task is activated or exec is called, close all fds
with O_CLOEXEC flags.
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
modlib/modlib_symbols.c: In function ‘modlib_symcallback’:
modlib/modlib_symbols.c:215:13: warning: implicit declaration of function ‘modlib_depend’; did you mean ‘modlib_read’? [-Wimplicit-function-declaration]
215 | ret = modlib_depend(exportinfo->modp, modp);
| ^~~~~~~~~~~~~
| modlib_read
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>