|WARNING| drivers: improve DPAA crypto fq resource handling
dpdklab at iol.unh.edu
dpdklab at iol.unh.edu
Wed Oct 28 10:16:23 CET 2026
Test-Label: ai-code-review
Test-Status: WARNING
https://dpdk.org/patch/172199
_AI Code Review_
=== Patch Review: series.patch (via Claude) ===
Review date: 2026-10-28
# DPDK Patch Review
## ERRORS
### 1. Memory leak on probe failure - `security_instance` not freed
**File:** `drivers/crypto/dpaa_sec/dpaa_sec.c`
**Line:** `goto init_error;` at line 3808
The `security_instance` allocated at line 3790 (`rte_zmalloc_socket(...)`) is not freed in any of the error paths (`init_error3`, `init_error2`, `init_error1`, `init_error`). After `goto init_error;` at line 3808, the code jumps to line 3905 which only frees `dev->security_ctx` (line 3663) in `dpaa_sec_uninit()`, but in the probe path `cryptodev->security_ctx` is assigned to `security_instance` at line 3795, so `init_error:` should free it explicitly.
**Suggested fix:**
```c
init_error:
DPAA_SEC_ERR("driver %s: create failed", cryptodev->data->name);
rte_free(security_instance);
return -1;
```
---
### 2. Missing `close(map_fd)` on all error paths
**File:** `drivers/crypto/dpaa_sec/dpaa_sec.c`
**Lines:** Error paths at 3808, 3830, 3847, 3868
The `map_fd` opened at line 3779 (`open()`) is not closed on any error path. The `close(map_fd)` at line 3812 is only executed if `cmd_map` initialization succeeds. If any `goto init_errorN;` is taken before the normal cleanup, `map_fd` leaks.
**Suggested fix:**
Add `if (map_fd >= 0) close(map_fd);` to the `init_error:` label:
```c
init_error:
DPAA_SEC_ERR("driver %s: create failed", cryptodev->data->name);
rte_free(security_instance);
if (map_fd >= 0)
close(map_fd);
return -1;
```
---
### 3. `security_instance` not freed on later error paths
**File:** `drivers/crypto/dpaa_sec/dpaa_sec.c`
**Lines:** Labels `init_error1`, `init_error2`, `init_error3`
After `security_instance` is allocated (line 3790) and assigned to `cryptodev->security_ctx` (line 3795), all later error paths (`init_error1`, `init_error2`, `init_error3`) fall through to `init_error:` without freeing it. Only `dpaa_sec_uninit()` frees `dev->security_ctx`, but that is called from the normal teardown path, not from probe failure.
**Suggested fix:**
All error labels should eventually reach a cleanup that frees `security_instance`. The fix for Error #1 handles this if all labels fall through to `init_error:`.
---
### 4. `munmap(cmd_map)` not called on error paths after successful `mmap()`
**File:** `drivers/crypto/dpaa_sec/dpaa_sec.c`
**Lines:** After line 3802 (`mmap()` succeeds), error paths `init_error1/2/3`
If `mmap()` succeeds (line 3802) but a later error occurs (`goto init_error1/2/3;`), `cmd_map` is not unmapped. The normal cleanup path calls `munmap(dpaa_ioctl_portal)` at line 3814, but error paths bypass this.
**Suggested fix:**
Track whether `mmap()` succeeded and unmap on error:
```c
init_error:
DPAA_SEC_ERR("driver %s: create failed", cryptodev->data->name);
rte_free(security_instance);
if (cmd_map != MAP_FAILED && cmd_map != NULL)
munmap(cmd_map, DPAA_SEC_IOCTL_PORTAL_SIZE);
if (map_fd >= 0)
close(map_fd);
return -1;
```
---
## WARNINGS
### 1. Variable `num` type inconsistency
**File:** `drivers/crypto/dpaa_sec/dpaa_sec.c`
**Line:** 3731
`num` is declared `int` but `qman_alloc_fqid_range()` returns `int` and is checked `< 0` for error. However, it is also used to store positive counts up to `RTE_DPAA_MAX_RX_QUEUE` (64). While `int` suffices for the values involved, using `int` for a count that is compared against unsigned queue limits creates mixed signedness comparisons. Consider `unsigned int` for clarity, or keep `int` with explicit casts in comparisons.
**Suggested fix (optional):**
Declare `num` as `unsigned int` and check `(int)num < 0` for the error case, or leave as-is if all comparisons are intentionally signed.
---
### 2. Release notes required for exported symbols and API changes
**Files:** `drivers/bus/dpaa/dpaa_bus_base_symbols.c`, `drivers/bus/dpaa/include/fsl_qman.h`
**Lines:** Exports `qman_release_fqid_range`, `qman_destroy_fq`, changes `qman_shutdown_fq()` signature
This patch exports two previously internal symbols (`qman_release_fqid_range`, `qman_destroy_fq`) and changes the signature of `qman_shutdown_fq()` from `int qman_shutdown_fq(u32 fqid)` to `int qman_shutdown_fq(struct qman_fq *fq)`. These are ABI and API changes that require release notes. A compatibility wrapper `qman_shutdown_fq_by_fqid()` is added, but the original function's signature change is still an ABI break for any external code calling the old signature.
**Suggested fix:**
Add a section to `doc/guides/rel_notes/release_26_11.rst` (or current release notes) documenting:
- New exported symbols: `qman_release_fqid_range`, `qman_destroy_fq`
- Changed function signature: `qman_shutdown_fq()` now takes `struct qman_fq *` instead of `u32 fqid`
- Availability of compatibility wrapper `qman_shutdown_fq_by_fqid()`
---
### 3. Exported symbols should use `RTE_EXPORT_INTERNAL_SYMBOL` in declaration order
**File:** `drivers/bus/dpaa/base/qbman/qman.c`
**Line:** 1591
`RTE_EXPORT_INTERNAL_SYMBOL(qman_destroy_fq)` is placed immediately before the function definition. While this is acceptable, the DPDK convention is to place export macros in the corresponding `*_base_symbols.c` file (as done for most symbols). This one is added both in `qman.c` (line 1591) and in `dpaa_bus_base_symbols.c` (line 81). Having it in both places is redundant -- the build system only needs it in one.
**Suggested fix:**
Remove the `RTE_EXPORT_INTERNAL_SYMBOL(qman_destroy_fq)` from line 1591 in `qman.c`, since it is already listed in `dpaa_bus_base_symbols.c` at line 81. Keep only the entry in `dpaa_bus_base_symbols.c`.
---
## INFO
### 1. Error message formatting inconsistency (pre-existing pattern, not introduced)
**File:** `drivers/crypto/dpaa_sec/dpaa_sec.c`
**Lines:** Multiple new error messages (3646, 3649, 3731, etc.)
The new error messages use mixed formats: some prefix with `%s:` (device name), others do not. For example:
- Line 3646: `"%s: Failed(%d) to shutdown TXQ(0x%08x), fqid not released"`
- Line 3801: `"Failed(%d) to alloc %d fqids"` (no `%s:`)
This inconsistency is minor but reduces log clarity. Consider prefixing all error messages with `cryptodev->data->name` for uniform context.
---
### 2. Variable shadowing: `ret` reused in nested error-path cleanup loops
**File:** `drivers/crypto/dpaa_sec/dpaa_sec.c`
**Lines:** 3852, 3878, etc.
In `init_error3:` and `init_error1:` cleanup loops, the loop variable `ret` is reused from the outer function scope (`int ret` declared at line 3731). While this is not a bug (the outer `ret` is already in an error state and will not be used again), reusing the same name for a loop-local error check reduces clarity. Consider using a distinct name like `ret2` or `shutdown_ret` for the cleanup loop.
**Example:**
```c
int shutdown_ret;
for (j = 0; j < i; j++) {
shutdown_ret = qman_shutdown_fq(&internals->inq[j]);
if (shutdown_ret) {
DPAA_SEC_ERR("...", shutdown_ret, ...);
}
}
```
---
### 3. Pre-existing: `dpaa_sec_uninit()` could return early on `dev->data == NULL`
**File:** `drivers/crypto/dpaa_sec/dpaa_sec.c`
**Line:** 3621
The check `if (!dev) return -ENODEV;` does not verify `dev->data`. While the caller (rte_cryptodev layer) should ensure `dev->data` is valid, defensive programming would add:
```c
if (!dev || !dev->data)
return -ENODEV;
```
This is a hardening suggestion, not a bug in this patch.
---
Review-Result: ERROR
More information about the test-report
mailing list