|WARNING| [13/13] examples/eventdev_pipeline: make signal handler safe
dpdklab at iol.unh.edu
dpdklab at iol.unh.edu
Mon Sep 7 01:43:02 CEST 2026
Test-Label: ai-code-review
Test-Status: WARNING
https://dpdk.org/patch/169134
_AI Code Review_
=== Patch Review: series.patch (via Claude) ===
Review date: 2026-09-06
# DPDK Patch Review
## Patch 01/13: graph: do not call printf in signal
**Correctness:** No issues found.
**Style:** No issues found.
---
## Patch 02/13: examples: remove printf from signal handler
**Correctness:** No issues found.
In `examples/distributor/main.c`, the parameter is now unused so `__rte_unused` is correctly added.
**Style:** No issues found.
---
## Patch 03/13: examples/vmdq: do not print from signal handler
**Correctness:**
**Warning:** `stats_requested` is written from signal context and read from the main lcore, but is declared as `volatile sig_atomic_t`, which is correct. The check `if (stats_requested && lcore_id == rte_get_main_lcore())` then `stats_requested = 0` has a TOCTOU issue if the signal arrives between the check and the clear. However, the consequence is benign (an extra stats print on the next iteration). This is acceptable for a stats-on-demand feature.
**Style:** No issues found.
---
## Patch 04/13: examples/symmetric_mp: do not print or exit in handler
**Correctness:** No issues found.
The patch correctly changes the flow to set a flag in the handler, return 0 from `lcore_main()`, wait for lcores in `main()`, then print stats. The `print_stats()` signature change (removing `signum`) matches the new call site.
**Style:** No issues found.
---
## Patch 05/13: examples/vdpa: make signal handler safe
**Correctness:** No issues found.
The teardown now happens in `main()` after the input loop exits, and also when exiting interactive mode via 'q', which was missing before as noted in the commit message.
**Style:** No issues found.
---
## Patch 06/13: examples/vhost: make signal handler safe
**Correctness:** No issues found.
`quit` is `volatile sig_atomic_t`, written in the handler, checked in `switch_worker()`. The unregister call moves to `main()` after joining lcores.
**Style:** No issues found.
---
## Patch 07/13: examples/vhost_blk: do not tear down from signal handler
**Correctness:** No issues found.
The teardown moves to `main()` after the `sleep(1)` loop exits. The loop checks `quit`, which is `volatile sig_atomic_t`.
**Style:** No issues found.
---
## Patch 08/13: examples/ntb: do not print and re-raise from signal handler
**Correctness:** No issues found.
The previous code called `kill(getpid(), signum)` to re-raise the signal after restoring `SIG_DFL`, which is async-signal-safe but still complex. The new code sets `conf->stopped = 1` for each lcore, and the main loop in `ntb_fwd.c` already checks `conf->stopped`. This is cleaner and safer.
The commit message notes that `SIGINT` now stops forwarding and returns to the `ntb>` prompt instead of terminating, which is a behavior change but arguably an improvement (allows `quit` to do teardown).
**Style:**
`conf->stopped` is now written from signal context. It should be `volatile sig_atomic_t`, but the patch changed it to `volatile uint8_t`. On POSIX systems `uint8_t` is atomic, so this is acceptable. No flag needed.
---
## Patch 09/13: examples/ipsecgw: do not print from signal handler
**Correctness:** No issues found.
**Style:** No issues found.
---
## Patch 10/13: examples/l2fwd-macsec: remove print in signal handler
**Correctness:** No issues found.
**Style:** No issues found.
---
## Patch 11/13: examples/ethtool: fix exit flag and unchecked cmdline
**Correctness:**
**Error:** The call to `rte_panic()` in `ethapp.c` should not be in a signal-safe context check (it's in `ethapp_main()`, not a signal handler), so the addition of the NULL check and `rte_panic()` is fine. However, `rte_panic()` is a forbidden token per the guidelines (it's equivalent to `rte_exit()` which should not be introduced in new code). In this case it's being added to handle a NULL return from `cmdline_stdin_new()`.
**Suggested fix:** Use a different error handling approach:
```c
ctx_cmdline = cmdline_stdin_new(list_prompt_commands, "EthApp> ");
if (ctx_cmdline == NULL) {
fprintf(stderr, "Cannot create cmdline instance\n");
return; /* or return an error code if ethapp_main's signature changes */
}
```
**Style:**
The change to `main.c` making `exit_now` volatile is correct, as it's written from one lcore and read from another.
---
## Patch 12/13: examples/vmdq_dcb: allow exit on signal
**Correctness:**
**Warning:** The loop in `lcore_main()` checks `quit`, which is `volatile sig_atomic_t` written from signal context and read from worker lcores. This is correct. However, the loop also calls `sighup_handler(int signum)` indirectly (via `signal(SIGHUP, sighup_handler)`), and `sighup_handler()` still calls `printf()` which is not async-signal-safe. This patch does not address that. The commit message says "add a SIGINT and SIGTERM handler", which it does, but the SIGHUP handler remains unsafe.
The original patch 03/13 (vmdq) addressed SIGHUP by deferring the stats print to the main lcore. This patch (vmdq_dcb) should do the same for SIGHUP.
**Suggested additional change:** Apply the same pattern to `sighup_handler` as was done in patch 03/13.
**Style:** No issues found.
---
## Patch 13/13: examples/eventdev_pipeline: make signal handler safe
**Correctness:**
**Warning:** The change from `rte_exit(1, ...)` to `_exit(1)` when `fdata->done` is already set is correct for signal safety (the commit message notes this is the "second-signal escape hatch"). However, the exit code is hardcoded to `1`. If the intent is "give up on clean shutdown", an exit code of 130 (128 + SIGINT) or similar would be more conventional. This is a minor style/convention issue, not a correctness bug, but worth noting.
**Style:**
`cdata.dump_dev_signal` is correctly changed to `volatile sig_atomic_t` since it's written from signal context.
The comment in the commit message about SIGTSTP depending on a scheduler lcore is accurate and documents existing behavior, so no flag needed there.
---
## Summary of Findings
### Errors
**Patch 11/13 - examples/ethtool: fix exit flag and unchecked cmdline**
- Use of `rte_panic()` for a non-critical error (failed to create cmdline instance). While the NULL check is good, `rte_panic()` is a forbidden function in new code (equivalent to `rte_exit()`, which calls exit() and is only for unrecoverable EAL failures). Use `fprintf(stderr, ...)` and return an error code instead.
### Warnings
**Patch 12/13 - examples/vmdq_dcb: allow exit on signal**
- The SIGHUP handler still calls `printf()`, which is not async-signal-safe. This patch addresses SIGINT/SIGTERM but leaves SIGHUP unsafe. Apply the same deferred-print pattern used in patch 03/13 (vmdq) to the SIGHUP handler here.
**Patch 13/13 - examples/eventdev_pipeline: make signal handler safe**
- The second-signal `_exit(1)` uses exit code 1. Conventionally, when giving up on clean shutdown after a second signal, the exit code should reflect the signal (e.g., 128 + SIGINT = 130). This is a minor process convention issue, not a correctness bug.
### Info
All other patches (01-10) are correct and follow the guidelines. The series significantly improves signal safety across the examples.
More information about the test-report
mailing list