When a thread is terminated via pthread_exit() while blocked in epoll_wait(),
the file reference taken at the beginning of epoll_wait() is not properly
released, leading to resource leaks.
Problem scenario found during libuv test:
1. Echo server thread is blocked in epoll_wait()
2. Main task sends pthread_kill signal to the server thread
3. Signal handler calls pthread_exit() to terminate the thread
4. epoll_wait() is interrupted before reaching the file_put() call
5. The epoll fd reference count remains elevated
6. epoll_do_close() is never called, leaving fds in internal queues
7. File descriptors leak
Solution:
Register a TLS (Thread Local Storage) cleanup handler using tls_cleanup_push()
at the beginning of epoll_wait() blocking section. This ensures that if the
thread exits abnormally (via pthread_exit, pthread_cancel, etc.), the cleanup
handler (epoll_cleanup) will be called automatically to release the file
reference via file_put().
The cleanup handler is properly paired with tls_cleanup_pop() when epoll_wait()
completes normally, ensuring the handler is only invoked on abnormal exit.
This fix is applied to both epoll_wait() code paths (with and without extended
mode) to ensure consistent behavior.
Impact:
- Prevents epoll fd reference count leaks on thread cancellation
- Ensures proper cleanup even when epoll_wait() is interrupted by pthread_exit
- Critical for multi-threaded applications using signals and thread termination
- Works together with previous fix for teardown/oneshot list cleanup
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
When an epoll fd is closed, the file descriptors in the teardown and
oneshot lists were not being properly dereferenced, leading to fd leaks.
This fix ensures that all fds in the teardown and oneshot lists are
properly released via file_put() during epoll_do_close(), matching the
behavior for fds in the setup list.
Impact:
- Prevents fd leaks when epoll fd is closed
- Ensures proper cleanup of all tracked file descriptors
- Critical for applications using EPOLLONESHOT or fd removal operations
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
00086373 00000634 T __aeabi_dsub
00086373 00000634 T __subdf3
00087841 00000724 T __udivmoddi4
and other small symbol, save total flash size 3K
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This moves mtd.rst from special/ directory to its own special/mtd
subdirectory and adds pages for supported devices (NOR/NAND flashes and
EEPROMS) with some basic configuration and initialization description.
Signed-off-by: Michal Lenc <michallenc@seznam.cz>
OpenAMP already change virtqueue_get_available_buffer() to
virtqueue_get_first_avail_buffer(), so update them
Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
new virtio_alloc_buf() return int type, so add virtio_malloc_buf()
for the convenience of use.
And replace all virtio_alloc_buf() to virtio_malloc_buf() in NuttX.
Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
and remove somes libmetal and openamp patches that already merged
in the OpenAMP and Libmetal community.
Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
1. In cfi_write_unalign(): Add additional check to ensure nbytes is
at least bankwidth size before skipping unaligned start handling.
This prevents incorrect behavior when writing small amounts of
data that are less than bankwidth.
2. In cfi_write(): Align down the write size to bankwidth boundary
when the remaining nbytes is less than the buffer write size.
This ensures the buffer write operation always works with properly
aligned data size, preventing write failures.))
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
Bug Description:
The original code always used conn->pollinfo[0] (the first element) to store
new poll setup context, regardless of whether that slot was already in use.
This caused multiple poll operations on the same CAN socket to overwrite each
other's context, leading to:
- Lost poll waiters when multiple threads poll the same socket
- Memory corruption in pollfd structures
- Undefined behavior when poll_teardown tries to clean up
Root Cause:
The code directly assigned `info = conn->pollinfo` without checking if the
slot was available, effectively always using pollinfo[0]. When a second
thread called poll() on the same socket, it would overwrite the first
thread's poll context.
Solution:
1. Initialize info to NULL instead of conn->pollinfo
2. Before setting up poll, iterate through all CONFIG_NET_CAN_NPOLLWAITERS
slots to find the first free slot (where fds == NULL)
3. Return -EBUSY if no free slots are available
4. During teardown, properly mark the slot as free by setting fds = NULL
Additional Changes:
- Added CONFIG_NET_CAN_NPOLLWAITERS Kconfig option (default 4) to make the
maximum number of concurrent poll waiters configurable
- Changed hardcoded array size from 4 to CONFIG_NET_CAN_NPOLLWAITERS
- Fixed lock ordering in teardown to ensure fds is cleared before unlock
Impact:
- Enables multiple threads to safely poll the same CAN socket concurrently
- Prevents poll context corruption in multi-threaded applications
- Provides proper resource management with -EBUSY when all slots are full
- Makes the number of supported concurrent pollers configurable per use case
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit removes unnecessary file duplication and memory allocation when
passing file descriptors through Unix domain sockets, leveraging the new
filep reference counting framework.
Background:
With the new filep framework, file structures (filep) can be safely shared
across processes using reference counting. When passing file descriptors
through SCM_RIGHTS control messages on local sockets, the previous
implementation unnecessarily duplicated the entire file structure.
Changes:
1. In local_sendctl() (sender side):
- Removed allocation of filep2 structure (kmm_zalloc)
- Removed file_dup2() call that copied the file structure
- Now directly stores the original filep with its reference count
- Eliminates memory allocation overhead and potential failure points
2. In local_recvctl() (receiver side):
- Changed from file_close() + kmm_free() to file_put()
- file_put() properly decrements reference count and handles cleanup
- Consistent with the new filep reference counting model
3. In local_freectl() (cleanup on error):
- Changed from file_close() + kmm_free() to file_put()
- Ensures proper reference count management during error paths
Technical Details:
The new filep framework ensures that:
- Multiple file descriptors across different processes can reference the
same underlying filep structure safely
- Reference counting (via file_get/file_put) manages lifetime correctly
- The underlying file object is only released when all references are gone
This change is safe because file_dup() in the receiver already calls
file_get() internally to increment the reference count for the new fd,
so the filep remains valid after the sender calls file_put().
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
The 'created' flag values were incorrectly inverted in file_mq_vopen():
1. When opening an existing message queue (inode_find succeeds):
- Before: incorrectly set *created = 1 (indicating new creation)
- After: correctly set *created = 0 (indicating existing queue)
2. When creating a new message queue (inode_find fails):
- Before: incorrectly set *created = 0 (indicating existing queue)
- After: correctly set *created = 1 (indicating new creation)
This bug could lead to incorrect resource management and cleanup behavior
in the calling function nxmq_vopen() when file_allocate() returns an error,
as it relies on the 'created' flag to determine whether the message queue
was newly created and needs to be cleaned up.
Impact:
- Resource leak when opening existing queues that should not be released
- Missing cleanup when creating new queues that should be released on error
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
Shmem region lives in RAM and should not be load in FLASH.
This fixes the issue with wrong binary size when build AMP
configurations with RPTUN enabled. Before this change shmem
region was exported by objcopy to binary file which caused
the bin size to be huge and impossible to flash.
Signed-off-by: raiden00pl <raiden00@railab.me>
using Desired frequency offset from nominal frequency in
parts per billion(ppb) to adjust frequency
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This patch adds comprehensive documentation for the PTP (Precision Time
Protocol) clock driver framework in NuttX.
The documentation covers:
1. Overview and Architecture:
- IEEE 1588 PTP clock framework introduction
- Upper-half and lower-half driver architecture
- Integration with POSIX clock APIs
2. Configuration Options:
- CONFIG_PTP_CLOCK: Main framework configuration
- CONFIG_PTP_CLOCK_DUMMY: Dummy driver for testing
- CONFIG_CLOCK_ADJTIME: clock_adjtime() system call support
3. Device Interface:
- Character device interface (/dev/ptpN)
- IOCTL commands: PTP_CLOCK_GETTIME, PTP_CLOCK_SETTIME,
PTP_CLOCK_GETRES, PTP_CLOCK_ADJTIME, PTP_CLOCK_GETCAPS,
PTP_SYS_OFFSET, PTP_SYS_OFFSET_PRECISE
4. POSIX Clock API (CLOCKFD):
- Using CLOCKFD() macro to access PTP clocks
- clock_gettime(), clock_settime(), clock_getres() examples
- clock_adjtime() with various adjustment modes
- ADJ_OFFSET, ADJ_FREQUENCY, ADJ_SETOFFSET support
5. Dummy PTP Clock Driver:
- Software-based implementation for testing
- Features and initialization details
6. Example Usage:
- Basic time operations
- Frequency adjustment examples
- Time offset adjustment examples
7. Implementing Lower-Half Drivers:
- Step-by-step guide for hardware driver implementation
- Required operations and structures
- Registration process
8. Integration with PTP Daemons:
- ptp4l, timemaster, ptpd compatibility
- Standard POSIX clock API usage
9. Performance Considerations:
- Hardware timestamping requirements
- Cross-timestamping support
- Frequency adjustment resolution
10. Debugging:
- Debug configuration options
- Debug output examples
The documentation is added to:
- Documentation/components/drivers/special/ptp.rst (new file)
- Documentation/components/drivers/special/index.rst (updated)
This provides developers with complete reference material for using
and implementing PTP clock drivers in NuttX.
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This patch implements clock_adjtime() with CLOCKFD support, enabling
precise time and frequency adjustments for PTP clocks through the
standard POSIX clock API.
Key changes include:
1. New clock_adjtime() system call:
- Added sched/clock/clock_adjtime.c implementation
- Provides POSIX-compliant time adjustment interface
- Supports both standard clocks and CLOCKFD-based dynamic clocks
- Added CONFIG_CLOCK_ADJTIME Kconfig option
2. CLOCKFD support in clock_adjtime():
- Detects CLOCKFD-encoded clockids via CLOCKFD_TO_FD() check
- Extracts file descriptor and validates through fs_getfilep()
- Issues PTP_CLOCK_ADJTIME ioctl to underlying PTP clock device
- Returns clock status and adjustment results via struct timex
3. Enhanced struct timex support:
- Extended include/sys/timex.h with additional ADJ_* flags
- Added ADJ_OFFSET, ADJ_FREQUENCY, ADJ_MAXERROR, ADJ_ESTERROR
- Added ADJ_STATUS, ADJ_TIMECONST, ADJ_TAI, ADJ_SETOFFSET
- Added ADJ_MICRO, ADJ_NANO for time unit selection
- Added STA_* status flags for clock state reporting
4. Clock operations supported:
- ADJ_SETOFFSET: Apply time offset adjustment
- ADJ_FREQUENCY: Adjust clock frequency (PPM)
- ADJ_MAXERROR: Set maximum error estimate
- ADJ_ESTERROR: Set estimated error
- ADJ_STATUS: Modify clock status bits
- ADJ_NANO: Use nanosecond resolution
- ADJ_SETOFFSET: Set absolute time offset
5. API declarations:
- Added clock_adjtime() prototype in include/nuttx/clock.h
- Enabled by CONFIG_CLOCK_ADJTIME configuration
- Compatible with Linux clock_adjtime() interface
Usage example:
int fd = open("/dev/ptp0", O_RDWR);
struct timex tx = {0};
tx.modes = ADJ_FREQUENCY;
tx.freq = 10000000; /* Adjust frequency by 10 PPM */
clock_adjtime(CLOCKFD(fd), &tx);
close(fd);
This completes the PTP clock framework's POSIX clock API integration,
providing comprehensive time control capabilities for precision timing
applications including PTP synchronization daemons (ptp4l, timemaster).
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This patch extends CLOCKFD support to clock_getres(), allowing
applications to query the resolution of PTP clocks through file
descriptors using the standard POSIX clock API.
Key changes include:
1. Move clock_getres() from libc to kernel:
- Relocated from libs/libc/sched/clock_getres.c to sched/clock/
- Enables direct kernel-level file descriptor handling
- Maintains POSIX compliance while adding CLOCKFD support
2. CLOCKFD support in clock_getres():
- Detects CLOCKFD-encoded clockids using CLOCKFD_TO_FD() check
- Extracts file descriptor from clockid parameter
- Validates file descriptor through fs_getfilep()
- Issues PTP_CLOCK_GETRES ioctl to query clock resolution
3. PTP clock resolution query:
- Retrieves resolution from PTP clock device via ioctl
- Returns nanosecond-precision timing resolution
- Enables applications to determine clock accuracy capabilities
- Falls back to standard clock resolution for non-CLOCKFD clockids
4. Error handling:
- Returns EINVAL for invalid CLOCKFD file descriptors
- Properly manages file reference counting with fs_putfilep()
- Maintains backward compatibility with existing clock types
5. Build system updates:
- Updated libs/libc/sched/CMakeLists.txt and Make.defs
- Updated sched/clock/CMakeLists.txt to include clock_getres.c
- Ensures proper compilation in kernel context
Usage example:
int fd = open("/dev/ptp0", O_RDONLY);
struct timespec res;
clock_getres(CLOCKFD(fd), &res); /* Query PTP clock resolution */
printf("Resolution: %ld.%09ld sec\n", res.tv_sec, res.tv_nsec);
close(fd);
This completes the basic POSIX clock API support for dynamic PTP clocks,
providing applications with comprehensive clock information access.
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This patch implements POSIX-compliant CLOCKFD support, enabling user
applications to access dynamic PTP clocks through file descriptors
combined with clock_gettime() and clock_settime() system calls.
Key changes include:
1. CLOCKFD macro support:
- Added CLOCKFD() macro in include/nuttx/clock.h
- Allows encoding file descriptor into clockid_t: CLOCKFD(fd)
- Enables accessing PTP clocks via: clock_gettime(CLOCKFD(fd), &ts)
2. clock_gettime() enhancements:
- Modified sched/clock/clock_gettime.c to detect CLOCKFD clockids
- Extracts file descriptor from clockid using CLOCKFD_TO_FD()
- Validates file descriptor and calls file_ioctl() with PTP_CLOCK_GETTIME
- Falls back to standard clock handling for non-CLOCKFD clockids
3. clock_settime() enhancements:
- Modified sched/clock/clock_settime.c to support CLOCKFD clockids
- Extracts file descriptor and validates accessibility
- Issues PTP_CLOCK_SETTIME ioctl to underlying PTP clock device
- Maintains backward compatibility with standard POSIX clocks
4. File descriptor validation:
- Checks file descriptor validity using fs_getfilep()
- Ensures proper reference counting with fs_putfilep()
- Returns appropriate error codes (EINVAL, EBADF) on failures
5. Integration with PTP clock framework:
- Seamlessly integrates with PTP clock driver's ioctl interface
- Enables standard POSIX clock API usage for dynamic PTP clocks
- No changes required to existing applications using standard clocks
Usage example:
int fd = open("/dev/ptp0", O_RDONLY);
struct timespec ts;
clock_gettime(CLOCKFD(fd), &ts); /* Get PTP clock time */
clock_settime(CLOCKFD(fd), &ts); /* Set PTP clock time */
close(fd);
This implementation follows the Linux kernel's PTP clock model, providing
a familiar interface for developers working with PTP hardware.
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This patch adds a dummy PTP clock driver implementation that provides
a software-based PTP clock for testing and development purposes.
Key changes include:
1. Dummy PTP clock driver implementation:
- Added drivers/timers/ptp_clock_dummy.c
- Provides software-based PTP clock using system monotonic clock
- Implements all required lower-half driver operations
2. Lower-half driver operations:
- adjfine: Frequency adjustment (stores adjustment value)
- adjtime: Time offset adjustment (applies delta to base time)
- gettime: Returns current PTP clock time
- settime: Sets PTP clock time
- getcaps: Reports clock capabilities (1 billion PPB max adjustment)
- getcrosststamp: Provides system/device cross-timestamp
3. Driver initialization:
- Added ptp_clock_dummy_init() in drivers/drivers_initialize.c
- Auto-registration under CONFIG_PTP_CLOCK_DUMMY configuration
- Creates /dev/ptp0 character device node
4. Build system integration:
- Added CONFIG_PTP_CLOCK_DUMMY Kconfig option (depends on PTP_CLOCK)
- Updated CMakeLists.txt and Make.defs
- Added include/nuttx/timers/ptp_clock_dummy.h header
5. Implementation details:
- Uses clock_gettime(CLOCK_MONOTONIC) as time base
- Tracks time offset and frequency adjustment internally
- Suitable for testing PTP clock applications without hardware
This dummy driver enables development and testing of PTP clock applications
on platforms without dedicated PTP hardware support.
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This patch introduces the foundational PTP (Precision Time Protocol) clock
driver framework for NuttX, enabling precise time synchronization support
based on IEEE 1588 standard.
Key changes include:
1. New PTP clock driver infrastructure:
- Added drivers/timers/ptp_clock.c implementing upper-half driver
- Created include/nuttx/timers/ptp_clock.h with PTP clock interfaces
- Implemented upper/lower half driver architecture for hardware abstraction
2. Core functionality:
- Clock time get/set operations (gettime, settime)
- Frequency adjustment support (adjtime, adjfine)
- Phase adjustment capabilities
- System-device cross-timestamping for precise synchronization
3. IOCTL commands:
- PTP_CLOCK_SETTIME/GETTIME for time manipulation
- PTP_CLOCK_GETRES for resolution queries
- PTP_CLOCK_ADJTIME for time adjustment
- PTP_CLOCK_GETCAPS for capability queries
- PTP_SYS_OFFSET* for system offset measurements
4. Supporting structures:
- struct ptp_lowerhalf_s: lower-half driver interface
- struct ptp_clock_caps: clock capabilities descriptor
- struct ptp_sys_offset: system time offset measurement
- Added timex structures in include/sys/timex.h for ADJ_* operations
5. Build system integration:
- Added CONFIG_PTP_CLOCK Kconfig option
- Updated CMakeLists.txt and Make.defs
- Added PTPCLK debug macros in include/debug.h
This framework provides the base for PTP clock implementations, allowing
hardware-specific drivers to register and provide precise time services
through a standardized interface.
Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
Most of the peripheral support matches litex vexriscv-smp.
* arch/risc-v/Kconfig: Defer RV32 selection to core as litex board can do RV64.
* arch/risc-v/src/litex/Make.defs
arch/risc-v/src/litex/hardware/litex_clint.h
arch/risc-v/src/litex/hardware/litex_memorymap.h
arch/risc-v/src/litex/hardware/litex_plic.h
arch/risc-v/src/litex/litex_irq.c
arch/risc-v/src/litex/litex_irq_dispatch.c: Add CONFIG_LITEX_CORE_VEXIIRISCV
conditional where vexriscv_smp conditionals are.
* boards/risc-v/litex/arty_a7/configs/nsh-vexii/defconfig: New config.
* boards/risc-v/litex/arty_a7/include/vexii_irq.h: vexiiriscv irq defintion.
* boards/risc-v/litex/arty_a7/include/vexii_memorymap.h: vexiiriscv memory map.
* boards/risc-v/litex/arty_a7/scripts/ld.script: Define __global_pointer for
toolchain happiness matching other RISC-V linker scripts.
(This commit was written with assistance from Claude Code.)
Signed-off-by: Justin Erenkrantz <justin@erenkrantz.com>
According rfc793 p69, from state SYN-RECEIVED to state TIME-WAIT, if the incoming segment is not acceptable, an acknowledgment should be sent in reply (unless the RST bit is set):
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
According rfc793 p69, In SYN-RCVD state, if the incoming segment is not acceptable, an acknowledgment should be sent in reply (unless the RST bit is set):
<SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
According to RFC793, the flags of TCP reply packet should be as follows:
1. `RST` if flags of request packet has `ACK`
2. `RST|ACK` if flags of request packet has no `ACK`, at the same time, the sequence should be set to zero.
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
if update is called after tx, in an environment with very low
latency (such as a simulator), the received arp_response will
be overwritten by update (NULL), resulting in arp learning success,
but the packets are always not sent correctly and are converted
into arp packets.
Signed-off-by: zhanghongyu <zhanghongyu@xiaomi.com>
Wait a fixed number of milliseconds before sending a retry ARP request for the same destination if the IP address mapping is not exist to prevent ARP flooding
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>
when a arp response reached, it should notify all tasks waiting the address. if the address is unreachable, do not send arp request to prevent arp flooding.
Signed-off-by: wenquan1 <wenquan1@xiaomi.com>