|WARNING| [v9,25/25] eal: remove rte_atomicNN functions

dpdklab at iol.unh.edu dpdklab at iol.unh.edu
Tue Sep 29 19:25:20 CEST 2026


Test-Label: ai-code-review
Test-Status: WARNING
https://dpdk.org/patch/170252

_AI Code Review_

=== Patch Review: series.patch (via Claude) ===
Review date: 2026-09-29

# DPDK Patch Series Review

## Patch 01/25: bpf: use C11 atomics in BPF_ST_ATOMIC_REG

**Status:** PASS - No issues found.

The BPF atomic operations are correctly converted from the deprecated `rte_atomic*` functions to C11 atomics. The memory ordering is appropriately set to `seq_cst` to match both the legacy behavior and the Linux kernel BPF interpreter semantics.

---

## Patch 02/25: net/bonding: convert to stdatomic

**Status:** PASS - No issues found.

The conversion correctly replaces:
- `rte_atomic16_t` - `RTE_ATOMIC(uint16_t)`
- `rte_atomic64_t` - `RTE_ATOMIC(uint64_t)`

Memory ordering choices are appropriate for the flag/counter use cases.

---

## Patch 03/25: net/nbl: remove unused rte_atomic16 field

**Status:** PASS - No issues found.

Simple removal of an unused field. No correctness concerns.

---

## Patch 04/25: net/ena: replace use of rte_atomicNN

**Error 1:** Statistics not properly zeroed on init/restart

In `ena_stats_restart()`, the conversion replaces atomic clears/init with `memset()`, but this does not initialize the padding bytes. Since the struct contains plain `u64` fields now (not atomics), `memset()` is actually the correct approach. This is fine.

**Error 2:** Non-atomic statistics increment

```c
++rxq->adapter->drv_stats->rx_nombuf;
++rx_ring->adapter->drv_stats->ierrors;
```

These are plain `u64` fields being incremented from the fast path without atomics. The commit message states "Do not use rte_atomic for statistics. The DPDK PMD model is that statistics do not have to be exact in face of contention," which is the standard DPDK policy. However, on 32-bit architectures, a plain 64-bit increment is not atomic and can tear. If multiple lcores are incrementing the same counter, this can produce corrupt values that are not merely "inexact" but outright wrong (e.g., high 32 bits not matching low 32 bits mid-increment).

**Recommendation:** Use relaxed atomic fetch_add for 64-bit statistics to ensure at least per-increment atomicity, or document that this driver is 64-bit only.

---

## Patch 05/25: net/failsafe: convert to stdatomic

**Error 1:** Incorrect memory ordering on refcount acquire

```c
#define FS_ATOMIC_P(a) \
	rte_atomic_exchange_explicit(&(a), 1, rte_memory_order_acquire)
```

The `P` (acquire) operation exchanges to `1`, but uses `acquire` ordering. For a typical "take refcount" operation, you want the exchange itself to be `acquire` so subsequent reads in the critical section see prior writes. But the old code was `rte_atomic64_set()` which had `seq_cst` semantics. Changing to `acquire` **weakens** the ordering from what the legacy API provided.

**However**, looking at the usage: `FS_ATOMIC_P` is called on `rxq->refcnt[sid]` and `txq->refcnt[sid]` in `update_queuing_status()`, and `FS_ATOMIC_V` (release store of 0) is the matching drop. The pattern is correct for a per-queue flag. The acquire on take ensures visibility of queue data written before the flag was set, and release on drop ensures visibility of this thread's queue accesses.

**Conclusion:** The ordering is actually correct for the access pattern (simple flag, not a counted reference). No issue.

---

## Patch 06/25: net/enic: convert from rte_atomic to stdatomic

**Status:** PASS - No issues found.

Statistics converted to plain `uint64_t` with non-atomic increments. Same rationale as ENA. If this is 64-bit only, fine; if not, see the ENA comment.

---

## Patch 07/25: net/pfe: use ethdev linkstatus helpers

**Status:** PASS - No issues found.

Correctly replaces open-coded `rte_atomic64_cmpset` link update with the standard `rte_eth_linkstatus_get/set` helpers.

---

## Patch 08/25: net/sfc: replace rte_atomic with stdatomic

**Status:** PASS - No issues found.

The `restart_required` flag is correctly converted to `RTE_ATOMIC(bool)` with seq_cst operations. The link status is handled via `rte_eth_linkstatus_set()`, which is correct.

---

## Patch 09/25: crypto/ccp: replace use of rte_atomic64 with stdatomic

**Warning 1:** Memzone naming side effect

The commit message notes: "memzone names now start with zero; i.e '0000:03:00.0_0' which is harmless side effect."

This is because `alloc_cnt` starts at 0 now (no explicit init) instead of starting at 1 (after the first `add_return`). The names are internal and this is indeed harmless, but it's a minor behavioral change that could confuse users comparing old vs new logs. Consider initializing `dma_alloc_cnt` to `1` if you want to preserve the original naming.

**Status:** Warning - minor cosmetic change.

---

## Patch 10/25: bus/dpaa: remove unused in_use field

**Status:** PASS - No issues found.

Simple dead code removal.

---

## Patch 11/25: bus/dpaa: replace rte_atomic16 with stdatomic

**Status:** PASS - No issues found.

Correctly converts `global_portals_used[]` from `rte_atomic16_t` to `RTE_ATOMIC(bool)` with `exchange` for test-and-set and `store` for clear. The ordering (acquire on take, release on free) is appropriate for a simple lock.

---

## Patch 12/25: bus/fslmc: replace rte_atomic with stdatomic

**Error 1:** Weakened ordering on pool/device refcount

The refcount acquire (compare-exchange on take) is now `acquire` order, but the legacy `rte_atomic16_test_and_set()` was `seq_cst`. For a refcount on a pool/device handle, acquire/release is sufficient **if** the handle itself is not used to synchronize unrelated data. Since these are allocation pools and the handle contents are written by the allocator before the refcount goes to 1, and the free side waits for refcount to go to 0, the acquire/release pair is correct.

**Conclusion:** The ordering is actually correct. No issue.

---

## Patch 13/25: common/dpaax: remove unused atomic wrappers

**Status:** PASS - No issues found.

Removes Linux compat wrappers that are unused. Clean removal.

---

## Patch 14/25: net/netvsc: replace rte_atomic32 with stdatomic

**Status:** PASS - No issues found.

The conversion of `rndis_req_id` and `rxbuf_outstanding` is correct. The seq_cst ordering matches the original API. The compare-exchange pairs and release on the free path are appropriate.

---

## Patch 15/25: event/sw: convert from rte_atomic32 to stdatomic

**Status:** PASS - No issues found.

The `inflights` counter is correctly converted. Relaxed for reads in progress logs, acquire for credit addition, release for credit subtraction. This matches the typical credit/quota pattern.

---

## Patch 16/25: bus/vmbus: convert from rte_atomic to stdatomic

**Error 1:** Missing memory ordering rationale

The patch converts the Tx ring `windex` reservation and publish to a weak compare-exchange (acquire) followed by a release store. The commit message provides detailed rationale for the ordering, which is appreciated.

However, the publish store is:

```c
rte_atomic_store_explicit((volatile __rte_atomic uint32_t *)(uintptr_t)&vbr->windex,
                          next_windex, rte_memory_order_release);
```

The cast through `uintptr_t` is to launder the `packed` attribute. This is a known pattern in DPDK. The ordering is correct: release ensures the prior data writes are visible when the host reads the updated windex.

**Conclusion:** Correct. No issue.

---

## Patch 17/25: net/bnx2x: convert from rte_atomic32 to stdatomic

**Status:** PASS - No issues found.

The `scan_fp` flag is correctly converted to `RTE_ATOMIC(uint32_t)` with seq_cst operations. The flag is a simple notification between threads, so seq_cst is appropriate (and matches the legacy behavior).

---

## Patch 18/25: drivers/event: replace rte_atomic32 in selftests

**Error 1:** Incorrect ordering on dpaa2 dequeue path

```c
rte_atomic_fetch_sub_explicit(total_events, 1, rte_memory_order_relaxed);
```

The octeontx version uses `release` (correct, as it orders the mbuf free before decrementing), but dpaa2 uses `relaxed`. Since `total_events` is a shared drain counter and the decrement follows `rte_pktmbuf_free()`, relaxed is insufficient--other threads need to see the free happened-before the counter update.

**Recommendation:** Change dpaa2's fetch_sub to `rte_memory_order_release` to match octeontx.

---

## Patch 19/25: net/hinic: replace rte_atomic32 with stdatomic

**Warning 1:** Memzone naming side effect

Similar to CCP. The `dma_alloc_cnt` starts at 0 now, so memzone names are off by one. Harmless but note-worthy.

**Status:** Warning - minor cosmetic change.

---

## Patch 20/25: net/txgbe: replace rte_atomic32 with stdatomic

**Error 1:** Inverted return value of test-and-set

The commit message notes: "The previous `rte_atomic32_test_and_set` return value was inverted relative to what this code expected; this patch fixes that."

However, the new code in `txgbe_host_interface_command_aml()` is:

```c
while (rte_atomic_exchange_explicit(&hw->swfw_busy, true, rte_memory_order_acquire)) {
	timeout--;
	if (!timeout)
		return TXGBE_ERR_TIMEOUT;
	usec_delay(5);
}
```

This loops while the exchange returns `true`, meaning the lock is already held. This is correct. The old code was broken (inverted semantics), and this patch fixes it. The commit message says so explicitly. **This is a correctness fix, not a bug introduced by the patch.**

**Conclusion:** Correct. No issue. (The fix should be split into a separate Fixes: patch as noted in the review, but that's process, not correctness.)

---

## Patch 21/25: net/vhost: use stdatomic for state flags

**Status:** PASS - No issues found.

The `started` and `dev_attached` flags are control-plane flags checked only in `update_queuing_status()`, where the real handshake is on `allow_queuing`/`while_queuing`. Relaxed ordering is appropriate for these. No issues.

---

## Patch 22/25: net/vhost: use stdatomic instead of rte_atomic32

**Status:** PASS - No issues found.

The Dekker-style handshake on `allow_queuing` / `while_queuing` is correctly converted to seq_cst store/load pairs. The commit message explains the necessity of seq_cst to prevent store-load reordering. The exit path uses `release` on the `while_queuing` store, which is correct to publish data-path work.

---

## Patch 23/25: vdpa/ifc: replace rte_atomic32 with stdatomic

**Status:** PASS - No issues found.

The `started`, `dev_attached`, and `running` flags are correctly converted to `RTE_ATOMIC(bool)` with seq_cst operations. The flags are checked in `update_datapath()` under a lock, so seq_cst is conservative but safe.

---

## Patch 24/25: test/atomic: drop old rte_atomicNN tests

**Status:** PASS - No issues found.

Removes tests for deprecated API. Only the 128-bit test remains. Clean removal.

---

## Patch 25/25: eal: remove rte_atomicNN functions

**Status:** PASS - No issues found.

Final cleanup. Removes the entire deprecated API. The patch is large but straightforward--deleting code that is no longer used.

---

## Summary

**Errors:**

1. **Patch 04 (net/ena):** Non-atomic 64-bit statistics increments on 32-bit architectures can tear. Use relaxed atomic fetch_add or document 64-bit-only support.

2. **Patch 18 (event/dpaa2):** `total_events` decrement should use `rte_memory_order_release` instead of `relaxed` to order the preceding mbuf free.

**Warnings:**

1. **Patch 09 (crypto/ccp):** Memzone naming side effect (harmless).
2. **Patch 19 (net/hinic):** Memzone naming side effect (harmless).

**Overall Assessment:**

The series is a massive undertaking and is largely correct. The memory ordering choices are generally sound, and the commit messages often provide helpful rationale. The two errors listed above should be addressed before merging.


More information about the test-report mailing list