CV-Bowen opened a new pull request, #21547:
URL: https://github.com/apache/nuttx/pull/21547

   ## Summary
   
   Make libmetal's `metal_mutex` a recursive spinlock on NuttX, so
   `rdev->lock` can be taken from interrupt context. This is what
   apache/nuttx#21381 review asked for before the rpmsg_virtio rx path can
   be dispatched in the interrupt (follow-up PR).
   
   - `drivers/rpmsg`: `rpmsg_device_destroy()` no longer holds
     `rdev->lock` around the endpoint release loop. `rpmsg_destroy_ept()`
     sends NS_DESTROY there, which may sleep waiting for a tx buffer.
   - `drivers/rptun`: `g_rptun_lock` becomes a plain `rmutex_t`; it is held
     across ioctls that may block.
   - `openamp/libmetal`: replace patch 0003 (rmutex) with a recursive
     spinlock (irqsave + nopreempt) by default and an `is_mutex` flag to
     switch one instance to an rmutex. `rptun_init()` sets it on
     `rproc->lock`, which is held across the remoteproc ops. The nesting
     depth is kept in `metal_mutex` because `rspinlock_t` does not count
     without `CONFIG_SPINLOCK`. `metal_mutex_try_acquire()` now returns
     non-zero on success as libmetal documents; the old patch passed
     `nxrmutex_trylock()`'s 0 through.
   - `drivers/rpmsg`: rpmsg_port/rpmsg_virtio `dump()` always take
     `rdev->lock` now, also from interrupt and idle context.
   
   ## Impact
   
   - `rdev->lock` (every rpmsg transport) now disables interrupts and
     preemption while held. All regions under it on master are short list
     and refcount updates; callbacks and sends already run outside it.
   - `rproc->lock` stays a sleeping rmutex.
   - Out-of-tree code that sleeps while holding a `metal_mutex` must set
     `is_mutex` before first use.
   - No Kconfig change.
   
   ## Testing
   
   Host: Ubuntu 22.04.5 LTS x86_64, QEMU version 10.2.1, sim: cc (Ubuntu 
13.1.0-8ubuntu1~22.04) 13.1.0, qemu-armv8a: aarch64-none-elf-gcc (Arm GNU 
Toolchain 12.2.Rel1 (Build arm-12.24)) 12.2.1 20221205
   
   **metal_mutex semantics** (`sim:rpserver` with a test-only replacement
   of `examples/hello`, not part of this PR): nested acquire/release,
   `try_acquire` return value, irq state after the inner and outermost
   release, `is_mutex` (rmutex) mode, and two threads doing 200000 nested
   lock/inc/unlock each.
   
   | build | extra Kconfig | result |
   | --- | --- | --- |
   | sim:rpserver | `CONFIG_EXAMPLES_HELLO=y` | `count=400000 fail=0 PASSED` |
   | sim:rpserver | + `CONFIG_SMP=y CONFIG_SMP_NCPUS=4 CONFIG_SPINLOCK=y` | 
`count=400000 fail=0 PASSED` |
   
   The first row is the case the depth counter is for: without
   `CONFIG_SPINLOCK`, `rspin_lock_irqsave()` is plain `up_irq_save()`,
   so a count-based check would treat every release as the outermost one
   and turn interrupts back on inside the outer critical section.
   
   **rpmsg/rptun over the new lock** (baseline, `rdev->lock` is now a
   spinlock on both cores):
   
   <details><summary>results.md</summary>
   
   Baseline (`test.sh`, cases: baseline.yaml):
   
   - host: Ubuntu 22.04.5 LTS x86_64, QEMU version 10.2.1, sim: cc (Ubuntu 
13.1.0-8ubuntu1~22.04) 13.1.0, qemu-armv8a: aarch64-none-elf-gcc (Arm GNU 
Toolchain 12.2.Rel1 (Build arm-12.24)) 12.2.1 20221205
   - tested: nuttx 8558e9be001 apps f8bd442c2
   - qemu-armv8a:rpserver qemu-armv8a:rpproxy built with test-only overlay: 
disabled LIBC_ENVPATH BINFMT_CHECKEXEC
   - sim:rpserver + sim:rpproxy: PASS
     - [x] `uname -a` (server)
     - [x] `rpmsg dump all` (server)
     - [x] `rpmsg ping all 10 1024 3 0` (server)
     - [x] `uname -a` (proxy)
     - [x] `rpmsg ping all 10 1024 3 0` (proxy)
     - [x] `mount -t rpmsgfs -o cpu=server,fs=/proc /sp` (proxy)
     - [x] `cat /sp/version` (proxy)
     - [x] `rpmsg dump all` (proxy)
   - qemu-armv8a:rpserver + qemu-armv8a:rpproxy: PASS
     - [x] `uname -a` (server)
     - [x] `uname -a` (proxy)
     - [x] `rpmsg dump all` (server)
     - [x] `rpmsg ping all 10 1024 3 0` (server)
     - [x] `rpmsg ping all 10 1024 3 0` (proxy)
     - [x] `mount -t rpmsgfs -o cpu=server,fs=/proc /sp` (proxy)
     - [x] `cat /sp/version` (proxy)
   
   </details>
   
   qemu-armv8a:rpserver/rpproxy also enable `CONFIG_RPMSG_PORT_UART`, so
   the rpmsg_port rx/ns paths run under the new lock there as well.
   
   Not run: rpmsg_port_spi (no QEMU environment), SMP rptun.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to