|WARNING| [3/3] net/ice: fix Rx queue count reporting after TM commit
dpdklab at iol.unh.edu
dpdklab at iol.unh.edu
Fri Sep 4 13:51:26 CEST 2026
Test-Label: ai-code-review
Test-Status: WARNING
https://dpdk.org/patch/169094
_AI Code Review_
=== Patch Review: series.patch (via Claude) ===
Review date: 2026-09-04
# DPDK Patch Review
## Patch 1/3: net/ice: fix Tx queue capacity sizing after TM commit
### Correctness
**Error: Index conversion may be incorrect**
The patch adds `pf->tm_conf.hidden_layers` to convert a relative layer index to an absolute one:
```c
uint8_t q_lvl = ice_get_leaf_level(pf) + pf->tm_conf.hidden_layers;
```
However, the subsequent line:
```c
uint8_t qg_lvl = q_lvl - 1;
```
is used to index `nodes_created_per_level[]` and `hw->layer_info[]` arrays. The patch does not verify that `q_lvl >= 1` before the subtraction, which could cause `qg_lvl` to underflow if `ice_get_leaf_level(pf) + pf->tm_conf.hidden_layers` equals 0.
While this may be prevented by design constraints elsewhere in the code, the lack of a bounds check on a value used as an array index is a potential out-of-bounds access.
**Suggested fix:**
Add a validation check:
```c
uint8_t q_lvl = ice_get_leaf_level(pf) + pf->tm_conf.hidden_layers;
if (q_lvl == 0) {
PMD_DRV_LOG(ERR, "Invalid queue level calculation");
return -EINVAL;
}
uint8_t qg_lvl = q_lvl - 1;
```
### Style
No style issues identified.
---
## Patch 2/3: net/ice: skip TC validation if hierarchy committed
### Correctness
**Error: Missing rte_free on new error path**
The patch adds a new error case in `ice_tx_queue_start()`:
```c
} else if (pf->dcb_num_tcs > 1) {
/* TM only manages the TC0 scheduler subtree. */
PMD_DRV_LOG(ERR, "TM hierarchy is not supported together with multi-TC DCB");
rte_free(txq_elem);
return -EINVAL;
}
```
This correctly frees `txq_elem` on the error path, matching the existing pattern. No leak here.
**Warning: Initialization of dcb_num_tcs**
The patch initializes `pf->dcb_num_tcs = 1` in `ice_dev_configure()` before the DCB configuration block. However, `ice_dev_configure()` can be called multiple times during device reconfiguration. If DCB was previously configured with multiple TCs and then reconfigured without DCB, the initial assignment to 1 is correct. But if the DCB configuration block (`if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_DCB_FLAG)`) fails after updating `pf->dcb_num_tcs`, the field could be left in an inconsistent state.
The existing code does not show what happens on reconfiguration errors, so this may be acceptable if `ice_dev_configure()` always returns to a consistent state on failure. However, the pattern of setting `pf->dcb_num_tcs = 1` unconditionally at the start of configure suggests it's safe.
### Style
**Info: Comment formatting**
The comment "/* TM only manages the TC0 scheduler subtree. */" is formatted correctly but could be more specific about the consequence:
```c
/* TM hierarchy only supports TC0. Multi-TC DCB requires a different scheduler layout. */
```
This is a minor clarity improvement, not an error.
---
## Patch 3/3: net/ice: fix Rx queue count reporting after TM commit
### Correctness
**Error: nb_tm_qps uninitialized in existing VSI setup paths**
The patch introduces `vsi->nb_tm_qps` and initializes it in `ice_setup_vsi()` for the `ICE_VSI_PF` case:
```c
vsi->nb_tm_qps = vsi->nb_qps;
```
However, `ice_setup_vsi()` handles multiple VSI types (`ICE_VSI_PF`, `ICE_VSI_CTRL`, `ICE_VSI_VF`). The `ICE_VSI_CTRL` and `ICE_VSI_VF` cases do not initialize `nb_tm_qps`, leaving it uninitialized (zero) for those VSI types.
Later, `ice_dev_info_get()` reads `vsi->nb_tm_qps`:
```c
dev_info->max_tx_queues = vsi->nb_tm_qps;
```
If `ice_dev_info_get()` is called on a control or VF VSI, this would report `max_tx_queues = 0`, which is incorrect.
**Suggested fix:**
Initialize `nb_tm_qps` for all VSI types in `ice_setup_vsi()`:
```c
case ICE_VSI_CTRL:
vsi->nb_qps = ...;
vsi->nb_tm_qps = vsi->nb_qps; /* add this */
...
break;
case ICE_VSI_VF:
vsi->nb_qps = ...;
vsi->nb_tm_qps = vsi->nb_qps; /* add this */
...
break;
```
Or, if only PF VSIs use TM, guard the access in `ice_dev_info_get()`:
```c
dev_info->max_tx_queues = (vsi->type == ICE_VSI_PF) ? vsi->nb_tm_qps : vsi->nb_qps;
```
**Warning: nb_used_qps may not reflect actual queue count in all cases**
The patch changes `ice_vsi_disable_queues_intr()` to iterate over `nb_used_qps` instead of `nb_qps`:
```c
for (i = 0; i < vsi->nb_used_qps; i++) {
```
`nb_used_qps` tracks the number of queues actually configured by the application. If queues are stopped individually (not all at once), `nb_used_qps` may not match the number of queues that have interrupt state to clear. However, examining the code context, `ice_vsi_disable_queues_intr()` is called during port stop, when all queues are being torn down, so `nb_used_qps` should be correct at that point.
This is acceptable but worth noting in case queue lifecycle assumptions change.
### Style
**Info: Comment phrasing**
In `ice_tm.c`, the existing comment style uses concise phrases. The new code is consistent with this style. No issues.
---
## Summary
### Errors (must fix)
1. **Patch 1/3**: Potential underflow of `qg_lvl` if `q_lvl` equals 0, used as array index without bounds check.
2. **Patch 3/3**: `vsi->nb_tm_qps` uninitialized for `ICE_VSI_CTRL` and `ICE_VSI_VF` types, read in `ice_dev_info_get()`.
### Warnings (should fix)
1. **Patch 2/3**: `pf->dcb_num_tcs` initialization pattern may leave inconsistent state on configure failure (existing code may already handle this correctly; verify error paths).
2. **Patch 3/3**: `nb_used_qps` assumption in `ice_vsi_disable_queues_intr()` depends on queue lifecycle; verify correctness if queue stop sequence changes.
### Info (consider)
1. **Patch 2/3**: Comment clarity on TM/DCB conflict could be improved.
More information about the test-report
mailing list