-
Notifications
You must be signed in to change notification settings - Fork 4
[PWCI] "[v3,1/1] net/mlx5: fix port down in link detection error branch" #493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Enhance the documentation by adding information about limitations specific to the synchronous API when used with hardware steering. This update provides users with a more comprehensive understanding of the constraints in this configuration. Signed-off-by: Maayan Kashani <mkashani@nvidia.com> Signed-off-by: Bing Zhao <bingz@nvidia.com>
Add tested, and hence recommended, firmware and other versions for i40e and ice drivers. In the process remove version inform for obsolete DPDK releases. Signed-off-by: Hailin Xu <hailinx.xu@intel.com> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
There is the updated firmware providing the new capability bit "header_length_field_offset_mode". If this bit is set the length field offset in flex parser configuration should not be adjusted by the supported field mask left margin, and the bit "header_length_field_offset_mode" should be set in configuration command on the flex parser creation firmware call. Fixes: b04b06f ("net/mlx5: fix flex item header length field translation") Cc: stable@dpdk.org Signed-off-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
The update of flow engine devargs introduced a regression with untrusted VFs/SFs. Using HWS engine caused a degradation in probing 1K SFs, because memzone segments exceeds maximum 2560. Fixes: 53fdc23 ("common/mlx5: read SW steering capability bits") Fixes: d1ac7b6 ("net/mlx5: update flow devargs handling for future HW") Signed-off-by: Raslan Darawsheh <rasland@nvidia.com>
Count flow action is supported on root table with HW Steering flow engine with upstream drivers/libraries and drivers/libraries packaged with recently released DOCA. This patch updates relevant docs with minimum DOCA version. Signed-off-by: Dariusz Sosnowski <dsosnowski@nvidia.com> Acked-by: Bing Zhao <bingz@nvidia.com>
Previously, the Tx burst size in l3fwd was fixed at 256, which could lead to suboptimal performance in certain scenarios. This patch introduces separate --rx-burst and --tx-burst options to explicitly configure Rx and Tx burst sizes. By default, the Tx burst size now matches the Rx burst size for better efficiency and pipeline balance. Fixes: d5c4897 ("examples/l3fwd: add option to set Rx burst size") Signed-off-by: Sivaprasad Tummala <sivaprasad.tummala@amd.com> Tested-by: Venkat Kumar Ande <venkatkumar.ande@amd.com> Tested-by: Dengdui Huang <huangdengdui@huawei.com> Tested-by: Pavan Nikhilesh <pbhagavatula@marvell.com> Acked-by: Chengwen Feng <fengchengwen@huawei.com>
Currently, l3fwd starts in auto-negotiation mode, but it may fail to link up when auto-negotiation is not supported. Therefore, it is necessary to support starting with a specified speed for port. Additionally, this patch does not support changing the duplex mode. So speeds like 10M, 100M are not configurable using this method. Signed-off-by: Dengdui Huang <huangdengdui@huawei.com> Reviewed-by: Chengwen Feng <fengchengwen@huawei.com>
Currently, l3fwd-power starts in auto-negotiation mode, but it may fail to link up when auto-negotiation is not supported. Therefore, it is necessary to support starting with a specified speed for port. Additionally, this patch does not support changing the duplex mode. So speeds like 10M, 100M are not configurable using this method. Signed-off-by: Dengdui Huang <huangdengdui@huawei.com> Reviewed-by: Chengwen Feng <fengchengwen@huawei.com>
If format-truncation is enabled, the compiler detects a string overflow
since the snprintf() is putting ethernet address and new line
in buffer only sized for the address.
Since get_rx_queue_name() is used to create a ring name.
The buffer should be sized to be a valid ring name.
This fixes some format-overflow warnings and also corrects
for future errors.
In file included from ../examples/server_node_efd/efd_server/main.c:31:
In function ‘get_printable_mac_addr’,
inlined from ‘do_stats_display’ at ../examples/server_node_efd/efd_server/main.c:136:3:
../lib/net/rte_ether.h:248:36: warning: ‘snprintf’ output truncated before the last format character [-Wformat-truncation=]
248 | #define RTE_ETHER_ADDR_PRT_FMT "%02X:%02X:%02X:%02X:%02X:%02X"
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../examples/server_node_efd/efd_server/main.c:86:33: note: in expansion of macro ‘RTE_ETHER_ADDR_PRT_FMT’
86 | RTE_ETHER_ADDR_PRT_FMT "\n",
| ^~~~~~~~~~~~~~~~~~~~~~
../examples/server_node_efd/efd_server/main.c: In function ‘do_stats_display’:
../examples/server_node_efd/efd_server/main.c:86:59: note: format string is defined here
86 | RTE_ETHER_ADDR_PRT_FMT "\n",
|
Fixes: 39aad0e ("examples/flow_distributor: new example to demonstrate EFD")
Cc: stable@dpdk.org
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
The ifname is limited to 128 characters, but it would allow up
to 128 characters as prefix then could overflow creating ifname.
Change to limit path prefix (iface) to 123 (128 - sizeof("1024"))
to avoid possible format overflow
../examples/vdpa/main.c:501:76: warning: ‘snprintf’ output may be truncated before the last format character [-Wformat-truncation=]
501 | snprintf(vports[devcnt].ifname, MAX_PATH_LEN, "%s%d",
| ^
../examples/vdpa/main.c:501:25: note: ‘snprintf’ output between 2 and 139 bytes into a destination of size 128
501 | snprintf(vports[devcnt].ifname, MAX_PATH_LEN, "%s%d",
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
502 | iface, devcnt);
|
Fixes: 38f8ab0 ("vhost: make vDPA framework bus agnostic")
Cc: stable@dpdk.org
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
In theory, lcore and queue could be so large that mbuf pool name could overflow. But that can never happen since lcore and queue will be in range. Add a check so that static tools know that. Format overflow warnings seen on older versions of Gcc only. Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> Acked-by: Konstantin Ananyev <konstantin.ananyev@huawei.com> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
There were several hidden bugs in examples because format truncation warning was disabled. Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
After removing callback checks from ethdev fast path, some drivers crashed because tx_pkt_prepare was set to NULL. Some drivers (hns3, ngbe, txgbe) need to use rte_eth_tx_pkt_prepare_dummy when configuring queues. Other drivers (ntnic, softnic) does not need to set tx_pkt_prepare as it was set by eth_dev_set_dummy_fops() called by rte_eth_dev_allocate(). Bugzilla ID: 1834 Fixes: 066f3d9 ("ethdev: remove callback checks from fast path") Reported-by: Jiawen Wu <jiawenwu@trustnetic.com> Signed-off-by: Thomas Monjalon <thomas@monjalon.net> Reviewed-by: Morten Brørup <mb@smartsharesystems.com> Tested-by: Jiawen Wu <jiawenwu@trustnetic.com>
The Pollara 400 AI NIC is supported without any PMD changes. Add a link to the product brief. Cc: stable@dpdk.org Signed-off-by: Andrew Boyer <andrew.boyer@amd.com>
changes: 1. fix spelling from `SIENNA` to `SIENA` 2. add tuning guide for zen5 AMD Epyc 9005 3. add uncore power details 4. update on using AMD Solarflare X4 and X2 Signed-off-by: Vipin Varghese <vipin.varghese@amd.com> Tested-by: Thiyagarajan P <thiyagarajan.p@amd.com>
Updated some external links and removed a note which does not apply to MSVC builds anymore. Also reworded a sentence clarifying how to open a Visual Studio Developer Command Prompt from CMD and Powershell, as the original text could induce people to run VsDevCmd.bat from a Powershell prompt, which does not work. Signed-off-by: Andre Muezerie <andremue@linux.microsoft.com>
The note about the prefix of the package pyelftools was not showed in the documentation output because the syntax was missing a colon, so it was considered as a simple comment in the source file. Fixes: 9e6f75e ("doc: update build section of FreeBSD guide") Cc: stable@dpdk.org Signed-off-by: Thomas Monjalon <thomas@monjalon.net> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
The version python used in current FreeBSD stable release 14.3 is now 3.11. Update documentation accordingly. Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
KNI was removed from DPDK but the diagrams in the documentation were left behind. Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> Acked-by: Chengwen Feng <fengchengwen@huawei.com> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
This allows building and installing only the documentation, without recompiling the whole project, using: meson build -Denable_docs=true meson compile -C build doc meson install -C build --no-rebuild --tags doc In Debian/Ubuntu the documentation is built separately from the binaries, in a separate architecture-independent build job, so that it has to be done only once, instead of once per supported architecture. Signed-off-by: Luca Boccassi <bluca@debian.org> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
Add tested platforms with NVIDIA NICs to the 25.11 release notes. Signed-off-by: Raslan Darawsheh <rasland@nvidia.com>
Add tested Intel platforms with Intel NICs to v25.11 release note. Signed-off-by: Yu Jiang <yux.jiang@intel.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
The port down state was not initialized in the error branch of link detection when MLX NIC link status update failed (ret < 0). This resulted in incorrect link state reporting, as the device retained stale link status instead of reflecting the actual down state under error conditions. Fixes: 1256805 ("net/mlx5: move Linux-specific functions") Cc: stable@dpdk.org Signed-off-by: Yang Xu <xu.yang3@zte.com.cn> Signed-off-by: 0-day Robot <robot@bytheb.org>
Reviewer's GuideRefines DPDK sample app configuration and MLX5 driver behavior: separates RX/TX burst sizing and adds CLI link-speed options, tightens buffer name sizing and logging, adjusts Meson doc install tags, and updates MLX5 flex parser and link handling along with several NIC drivers’ tx_pkt_prepare defaults, while dropping unused steering/HWS capability plumbing. Class diagram for separated RX/TX burst configuration in l3fwdclassDiagram
class Globals {
+uint16_t nb_rxd
+uint16_t nb_txd
+uint32_t rx_burst_size
+uint32_t tx_burst_size
+uint32_t mb_mempool_cache_size
}
class parse_args {
+int parse_args(int argc, char** argv)
}
class parse_pkt_burst_fn {
+void parse_pkt_burst(const char* optarg, bool is_rx_burst, uint32_t* burst_sz)
}
class rte_eth_dev_info {
+struct rte_eth_rxconf default_rxportconf
}
class rte_eth_rxconf {
+uint16_t burst_size
}
class send_single_packet_fn {
+void send_single_packet(struct lcore_conf* qconf, struct rte_mbuf* m, uint16_t port)
}
class send_packetsx4_fn {
+void send_packetsx4(struct lcore_conf* qconf, uint16_t port, struct rte_mbuf** m, uint32_t num)
}
class acl_main_loop_fn {
+int acl_main_loop(void* dummy)
}
class em_main_loop_fn {
+int em_main_loop(void* dummy)
}
class fib_main_loop_fn {
+int fib_main_loop(void* dummy)
}
class lpm_main_loop_fn {
+int lpm_main_loop(void* dummy)
}
class main_fn_l3fwd {
+int main(int argc, char** argv)
}
Globals <.. parse_args : writes
Globals <.. parse_pkt_burst_fn : updates
Globals <.. send_single_packet_fn : reads_rx_burst_size
Globals <.. send_packetsx4_fn : reads_tx_burst_size
Globals <.. acl_main_loop_fn : reads_rx_burst_size
Globals <.. em_main_loop_fn : reads_rx_burst_size
Globals <.. fib_main_loop_fn : reads_rx_burst_size
Globals <.. lpm_main_loop_fn : reads_rx_burst_size
parse_args --> parse_pkt_burst_fn : calls
parse_pkt_burst_fn --> rte_eth_dev_info : queries
rte_eth_dev_info --> rte_eth_rxconf : uses
main_fn_l3fwd --> parse_args : calls
main_fn_l3fwd --> Globals : logs_rx_burst_size_tx_burst_size
class l3fwd_common_h {
+extern uint32_t rx_burst_size
+extern uint32_t tx_burst_size
}
l3fwd_common_h <.. send_packetsx4_fn
class l3fwd_h {
+extern uint32_t rx_burst_size
+extern uint32_t mb_mempool_cache_size
}
l3fwd_h <.. send_single_packet_fn
l3fwd_h <.. acl_main_loop_fn
l3fwd_h <.. em_main_loop_fn
l3fwd_h <.. fib_main_loop_fn
l3fwd_h <.. lpm_main_loop_fn
Class diagram for MLX5 flex parser and HCA capability changesclassDiagram
class mlx5_hca_flex_attr {
+uint8_t sample_outer:1
+uint8_t sample_inner:1
+uint8_t sample_tunnel_inner2:1
+uint8_t zero_size_supported:1
+uint8_t sample_id_in_out:1
+uint8_t header_length_field_mode_wa:1
+uint16_t max_base_header_length
+uint8_t max_sample_base_offset
+uint16_t max_next_header_offset
+uint8_t header_length_mask_width
}
class mlx5_devx_graph_node_attr {
+uint32_t header_length_base_value:16
+uint32_t header_length_field_shift:4
+uint32_t header_length_field_offset:16
+uint32_t header_length_field_offset_mode:1
+uint32_t header_length_field_mask
+uint32_t next_header_field_offset:16
}
class mlx5_ifc_parse_graph_node_cap_bits {
+u8 max_base_header_length[0x10]
+u8 header_length_mask_width[0x8]
+u8 header_length_field_offset_mode[0x1]
+u8 parse_graph_anchor[0x1]
}
class mlx5_ifc_parse_graph_flex_bits {
+u8 header_length_mode[0x4]
+u8 header_length_base_value[0x10]
+u8 header_length_field_shift[0x4]
+u8 header_length_field_offset[0x10]
+u8 header_length_field_offset_mode[0x1]
+u8 header_length_field_mask[0x20]
+u8 next_header_field_offset[0x10]
}
class mlx5_devx_cmd_query_hca_parse_graph_node_cap {
+int mlx5_devx_cmd_query_hca_parse_graph_node_cap(void* ctx, struct mlx5_hca_flex_attr* attr)
}
class mlx5_devx_cmd_create_flex_parser {
+void* mlx5_devx_cmd_create_flex_parser(void* ctx, struct mlx5_devx_graph_node_attr* data)
}
class mlx5_alloc_srh_flex_parser_fn {
+int mlx5_alloc_srh_flex_parser(struct rte_eth_dev* dev)
}
class mlx5_flex_translate_length_fn {
+int mlx5_flex_translate_length(struct mlx5_hca_flex_attr* attr, struct mlx5_flex_pattern_field* field, struct mlx5_devx_graph_node_attr* node, struct rte_flow_error* error)
}
mlx5_ifc_parse_graph_node_cap_bits --> mlx5_hca_flex_attr : populates
mlx5_ifc_parse_graph_flex_bits <-- mlx5_devx_graph_node_attr : encoded_from
mlx5_devx_cmd_query_hca_parse_graph_node_cap --> mlx5_ifc_parse_graph_node_cap_bits : reads_device_cap
mlx5_devx_cmd_query_hca_parse_graph_node_cap --> mlx5_hca_flex_attr : sets_header_length_mask_width_header_length_field_mode_wa
mlx5_devx_cmd_create_flex_parser --> mlx5_ifc_parse_graph_flex_bits : writes_header_length_field_offset_mode
mlx5_devx_cmd_create_flex_parser --> mlx5_devx_graph_node_attr : reads_header_length_field_offset_mode
mlx5_flex_translate_length_fn --> mlx5_hca_flex_attr : reads_header_length_field_mode_wa_header_length_mask_width
mlx5_flex_translate_length_fn --> mlx5_devx_graph_node_attr : sets_header_length_field_offset_header_length_field_offset_mode
mlx5_alloc_srh_flex_parser_fn --> mlx5_devx_graph_node_attr : sets_header_length_field_offset_header_length_field_shift_header_length_field_mask
mlx5_alloc_srh_flex_parser_fn --> mlx5_hca_flex_attr : reads_header_length_field_mode_wa_header_length_mask_width
class mlx5_hca_attr {
+uint64_t general_caps
+uint8_t reserved_fields
}
class mlx5_dev_ctx_shared {
+struct mlx5_common_device* cdev
+struct mlx5_dev_cap dev_cap
}
class mlx5_dev_cap {
+uint8_t dv_flow_en
+uint8_t dv_esw_en
}
class mlx5_dev_config {
+uint8_t dv_flow_en
+uint8_t dv_esw_en
+uint8_t allow_duplicate_pattern
}
class mlx5_shared_dev_ctx_args_config_fn {
+int mlx5_shared_dev_ctx_args_config(struct mlx5_dev_ctx_shared* sh, struct mlx5_dev_config* config, struct mlx5_kvargs_ctrl* mkvlist)
}
mlx5_shared_dev_ctx_args_config_fn --> mlx5_dev_ctx_shared : reads_dev_cap
mlx5_shared_dev_ctx_args_config_fn --> mlx5_dev_config : sets_dv_flow_en_allow_duplicate_pattern
%% Note: rx_sw_owner_tx_sw_owner_esw_sw_owner fields and HWS/SWS helpers
%% were removed from mlx5_hca_attr and configuration logic, simplifying
%% dv_flow_en and allow_duplicate_pattern handling.
Class diagram for mlx5 link update error-handling changeclassDiagram
class rte_eth_dev_data {
+struct rte_eth_link dev_link
}
class rte_eth_link {
+uint32_t link_speed
+uint8_t link_duplex
+uint8_t link_status
+uint8_t link_autoneg
}
class rte_eth_dev {
+struct rte_eth_dev_data* data
}
class mlx5_link_update_fn {
+int mlx5_link_update(struct rte_eth_dev* dev, int wait_to_complete)
}
class mlx5_os_link_ops {
+int mlx5_os_read_link_status(struct rte_eth_dev* dev, struct rte_eth_link* link)
}
rte_eth_dev --> rte_eth_dev_data : has
rte_eth_dev_data --> rte_eth_link : contains
mlx5_link_update_fn --> rte_eth_dev : updates_link_state
mlx5_link_update_fn --> mlx5_os_link_ops : calls
class ErrorPathBehavior {
+void on_negative_ret(struct rte_eth_dev* dev, int ret)
}
note for ErrorPathBehavior "on_negative_ret: memset(&dev->data->dev_link, 0, sizeof(dev->data->dev_link)); return ret"
mlx5_link_update_fn --> ErrorPathBehavior : uses_on_error
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
WalkthroughThis pull request introduces version 25.11-rc4 with comprehensive updates spanning documentation, build system configuration, driver modifications, and sample application enhancements. Key changes include MLX5 driver struct field reorganization, standardization of packet prepare function pointers across multiple NIC drivers, refactored burst size parameter handling in the l3fwd example, and expanded documentation for platform support matrices and hardware compatibility. Changes
Sequence Diagram(s)sequenceDiagram
participant mlx5_alloc_srh as mlx5_alloc_srh_flex_parser
participant offset_calc as Offset Calculation
mlx5_alloc_srh->>offset_calc: Check header_length_field_mode_wa flag
alt WA flag is set
offset_calc->>offset_calc: Initialize offset = 8
offset_calc->>offset_calc: Adjust by (8 - mask_width) if mask_width < 8
else WA flag not set
offset_calc->>offset_calc: Set offset = 12 (fixed)
end
offset_calc-->>mlx5_alloc_srh: Return calculated offset
sequenceDiagram
participant main as l3fwd main()
participant parse_rx as parse_pkt_burst (RX)
participant parse_tx as parse_pkt_burst (TX)
participant pmd as PMD
main->>main: Detect --rx-burst argument
main->>parse_rx: Call with is_rx_burst=true
parse_rx->>pmd: Query PMD recommended burst
pmd-->>parse_rx: Return recommended size
parse_rx-->>main: Set rx_burst_size
main->>main: Detect --tx-burst argument
main->>parse_tx: Call with is_rx_burst=false
parse_tx-->>main: Set tx_burst_size
main->>main: Log "Using Rx burst X Tx burst Y"
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey there - I've reviewed your changes - here's some feedback:
- In l3fwd’s send_single_packet() the flush threshold was changed from MAX_TX_BURST to rx_burst_size; this should likely use tx_burst_size to match the TX burst configuration rather than the RX burst size.
- In the l3fwd eth-link-speed handling, atoi() is used without validation; consider using strtol() with error checking so invalid input (e.g., non-numeric or out-of-range values) is detected and reported.
- For consistency with the other PMDs updated in this patch, consider explicitly setting tx_pkt_prepare to rte_eth_tx_pkt_prepare_dummy as well in the ntnic and softnic drivers instead of leaving it unset.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In l3fwd’s send_single_packet() the flush threshold was changed from MAX_TX_BURST to rx_burst_size; this should likely use tx_burst_size to match the TX burst configuration rather than the RX burst size.
- In the l3fwd eth-link-speed handling, atoi() is used without validation; consider using strtol() with error checking so invalid input (e.g., non-numeric or out-of-range values) is detected and reported.
- For consistency with the other PMDs updated in this patch, consider explicitly setting tx_pkt_prepare to rte_eth_tx_pkt_prepare_dummy as well in the ntnic and softnic drivers instead of leaving it unset.
## Individual Comments
### Comment 1
<location> `examples/l3fwd/l3fwd.h:115` </location>
<code_context>
extern uint32_t max_pkt_len;
-extern uint32_t nb_pkt_per_burst;
+extern uint32_t rx_burst_size;
extern uint32_t mb_mempool_cache_size;
</code_context>
<issue_to_address>
**issue (bug_risk):** TX path still uses RX burst size when flushing the TX buffer
In `send_single_packet()`, both the flush condition and the argument to `send_burst()` were switched to `rx_burst_size`, even though a separate `tx_burst_size` now exists. This keeps the TX flush threshold coupled to RX settings, which seems unintended given independent RX/TX configuration. Please use `tx_burst_size` for the TX buffering threshold and as the `send_burst()` parameter so `--tx-burst` correctly controls TX behavior.
</issue_to_address>
### Comment 2
<location> `examples/ip_reassembly/main.c:887-888` </location>
<code_context>
nb_mbuf = RTE_MAX(nb_mbuf, (uint32_t)NB_MBUF);
+ /* Should never happen but check so that pool name won't be too long. */
+ if (lcore > RTE_MAX_LCORE || queue > RTE_MAX_QUEUES_PER_PORT) {
+ RTE_LOG(ERR, IP_RSMBL, "invalid lcore %u or queue %u",
+ lcore, queue);
</code_context>
<issue_to_address>
**issue (bug_risk):** Off-by-one risk in lcore/queue bounds check
The guard currently uses `lcore > RTE_MAX_LCORE` and `queue > RTE_MAX_QUEUES_PER_PORT`. If these macros are max counts (common pattern), valid indices are `[0, max)` and values equal to the macros are out of range but not rejected. That would let invalid values reach the `snprintf()` pool name and pool creation. Please change the checks to `>=` for both `lcore` and `queue` to correctly reject out-of-range inputs.
</issue_to_address>
### Comment 3
<location> `doc/guides/rel_notes/release_25_11.rst:376` </location>
<code_context>
+ * Red Hat Enterprise Linux Server release 9.6
+ * Ubuntu 24.04 LTS
+ * Ubuntu 24.04.3 LTS
+ * Vmware ESXi 8.0.3
+
+ * NICs:
</code_context>
<issue_to_address>
**suggestion (typo):** Use the correct vendor capitalization for VMware.
Please change "Vmware" to "VMware" to match the vendor’s official capitalization.
```suggestion
* VMware ESXi 8.0.3
```
</issue_to_address>
### Comment 4
<location> `doc/guides/nics/mlx5.rst:1440-1443` </location>
<code_context>
+ If more significant bits are present in the `spec` than in the `mask`,
+ the rule will be created without any error
+ but the packets will not hit as expected.
+ Such limitation will be removed in future.
+
</code_context>
<issue_to_address>
**suggestion (typo):** Grammar tweak: "in the future" rather than "in future".
You could phrase this as: `Such limitation will be removed in the future.`
```suggestion
If more significant bits are present in the `spec` than in the `mask`,
the rule will be created without any error
but the packets will not hit as expected.
Such limitation will be removed in the future.
```
</issue_to_address>
### Comment 5
<location> `doc/guides/freebsd_gsg/build_dpdk.rst:21-24` </location>
<code_context>
-.. note:
+.. note::
- The specific package for pyelftools is dependent on the version of python in use,
- Python 3.8 being the version at type of writing, hence the ``py38`` prefix.
+ The specific package for pyelftools is dependent on the version of python in use,
+ Python 3.11 being the version at type of writing, hence the ``py311`` prefix.
These can be installed using (as root)::
</code_context>
<issue_to_address>
**issue (typo):** Fix "python" capitalization and "type of writing" typo.
Updated wording suggestion:
- `version of Python in use`
- `Python 3.11 being the version at time of writing, hence the ``py311`` prefix.`
```suggestion
.. note::
The specific package for pyelftools is dependent on the version of Python in use,
Python 3.11 being the version at time of writing, hence the ``py311`` prefix.
```
</issue_to_address>
### Comment 6
<location> `doc/guides/linux_gsg/amd_platform.rst:102` </location>
<code_context>
+Uncore
+~~~~~~
+
+AMD EPYC SoC support UNCORE power functions via ``rte_power_uncore`` from `25.03` onwards.
+These are tested and validated on GENOA, SIENA and TURIN.
+Please refer the tuning guides to enable ``HSMP`` and DPDK power management guide.
</code_context>
<issue_to_address>
**issue (typo):** Fix subject-verb agreement in "AMD EPYC SoC support".
Use singular "supports" to match the singular subject, e.g.: `AMD EPYC SoC supports UNCORE power functions via ``rte_power_uncore`` from �25.03� onwards.`
```suggestion
AMD EPYC SoC supports UNCORE power functions via ``rte_power_uncore`` from `25.03` onwards.
```
</issue_to_address>
### Comment 7
<location> `doc/guides/linux_gsg/amd_platform.rst:104` </location>
<code_context>
+
+AMD EPYC SoC support UNCORE power functions via ``rte_power_uncore`` from `25.03` onwards.
+These are tested and validated on GENOA, SIENA and TURIN.
+Please refer the tuning guides to enable ``HSMP`` and DPDK power management guide.
+
+
</code_context>
<issue_to_address>
**suggestion (typo):** Improve wording of "refer the tuning guides".
Consider adding "to" and clarifying the second reference, for example:
`Please refer to the tuning guides and the DPDK power management guide to enable ``HSMP``.`
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| extern uint32_t max_pkt_len; | ||
|
|
||
| extern uint32_t nb_pkt_per_burst; | ||
| extern uint32_t rx_burst_size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (bug_risk): TX path still uses RX burst size when flushing the TX buffer
In send_single_packet(), both the flush condition and the argument to send_burst() were switched to rx_burst_size, even though a separate tx_burst_size now exists. This keeps the TX flush threshold coupled to RX settings, which seems unintended given independent RX/TX configuration. Please use tx_burst_size for the TX buffering threshold and as the send_burst() parameter so --tx-burst correctly controls TX behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
examples/server_node_efd/efd_server/main.c (2)
1-1: PR title and description do not match the file changes.The PR title references "net/mlx5: fix port down in link detection error branch," but the changed file is
examples/server_node_efd/efd_server/main.c, which is unrelated to the MLX5 driver. This appears to be a PR metadata or auto-submission configuration issue.
85-87: Pre-existing issue: Newline in MAC address format breaks display formatting.The explicit newline in the format string on line 86 causes a line break when this function is called from line 137, disrupting the port statistics table layout. The
err_addressconstant on line 70 also lacks this newline, creating inconsistent return values.Apply this diff to remove the unwanted newline:
snprintf(addresses[port], sizeof(addresses[port]), - RTE_ETHER_ADDR_PRT_FMT "\n", + RTE_ETHER_ADDR_PRT_FMT, RTE_ETHER_ADDR_BYTES(&mac));With this fix, the buffer size on line 71 should be adjusted to:
- static char addresses[RTE_MAX_ETHPORTS][RTE_ETHER_ADDR_FMT_SIZE + 1]; + static char addresses[RTE_MAX_ETHPORTS][RTE_ETHER_ADDR_FMT_SIZE];
🧹 Nitpick comments (9)
examples/vdpa/main.c (2)
23-41: Prefix length reservation forifacelooks correct and fixes suffix overflow riskUsing
MAX_VDPA_STR_LEN = sizeof(RTE_STR(MAX_VDPA_SAMPLE_PORTS))and shrinkingifacetoMAX_PATH_LEN - MAX_VDPA_STR_LENcorrectly reserves enough room for the decimal index plus NUL when building%s%dintoifname. This avoids silent truncation of the numeric suffix while keeping everything withinMAX_PATH_LEN.No issues from a correctness/safety perspective.
If you want to make the intent clearer for future maintainers, a short comment near the
ifacedefinition explaining that the reduction reserves space for the device index digits and terminator would help readability.
69-81:--ifacelong-option handling and bounded copy are sound; consider handling truncation explicitlyThe switch
case 0using!strcmp(long_option[idx].name, "iface")plusrte_strscpy(iface, optarg, sizeof(iface));is straightforward and correctly bounds the copy to the actualifacearray size, aligning with the new prefix-capacity calculation.One small improvement:
rte_strscpywill return a negative value on truncation. Givenifaceis now smaller thanMAX_PATH_LEN, truncation becomes more likely for long prefixes. Logging a warning or error when the return value is negative would make misconfigurations easier to diagnose, though it’s not strictly required for correctness.examples/ip_reassembly/main.c (1)
887-892: Tighten bounds check and fix log formatting in new guardThe defensive guard is good, but there are two small issues:
- With arrays sized using these macros (e.g.,
lcore_queue_conf[RTE_MAX_LCORE]), valid indices are0..RTE_MAX_LCORE-1and0..RTE_MAX_QUEUES_PER_PORT-1. Using>instead of>=would treatlcore == RTE_MAX_LCOREorqueue == RTE_MAX_QUEUES_PER_PORTas valid here, even though they are out of range for such arrays.- The new
RTE_LOGcall doesn’t end with a newline, unlike the other logs in this file.You can address both with:
- /* Should never happen but check so that pool name won't be too long. */ - if (lcore > RTE_MAX_LCORE || queue > RTE_MAX_QUEUES_PER_PORT) { - RTE_LOG(ERR, IP_RSMBL, "invalid lcore %u or queue %u", - lcore, queue); + /* Should never happen but check so that pool name won't be too long. */ + if (lcore >= RTE_MAX_LCORE || queue >= RTE_MAX_QUEUES_PER_PORT) { + RTE_LOG(ERR, IP_RSMBL, "invalid lcore %u or queue %u\n", + lcore, queue); return -1; }examples/l3fwd-power/main.c (1)
1504-1504: Enhance the help text with valid values and format.The help text should specify the expected format (e.g., speed in Mbps) and potentially list valid values or provide examples.
Apply this diff to improve the help text:
- " --eth-link-speed: force link speed\n" + " --eth-link-speed SPEED: force link speed in Mbps (e.g., 1000, 10000, 25000)\n"doc/guides/sample_app_ug/l3_forward.rst (1)
428-428: Unrelated feature: eth-link-speed option.This line adds documentation for
--eth-link-speedoption, which appears unrelated to the RX/TX burst refactoring. Consider whether this should be in a separate commit for clearer change tracking.examples/l3fwd/main.c (1)
762-762: Unrelated feature: eth-link-speed option.The addition of
--eth-link-speedoption and its parsing logic (lines 930-940) appears unrelated to the RX/TX burst refactoring that is the main focus of this PR.Consider separating this into a different commit for:
- Clearer change tracking and git history
- Easier review and potential revert if needed
- Better alignment with single-responsibility principle
The implementation itself looks reasonable with validation against unsupported fixed speeds (10M, 100M).
Also applies to: 784-785, 795-795, 817-818, 824-824, 847-848, 930-940
drivers/net/mlx5/mlx5_flow_flex.c (1)
557-570: OFFSET-mode header length WA math looks sound and capability-gated correctlyThe workaround branch cleanly guards the extra offset/mask constraints behind
attr->header_length_field_mode_wa, prevents underflow before the(offset - header_length_mask_width)adjustment, and normalizes the offset back into the current dword. Settingnode->header_length_field_offset_mode = !attr->header_length_field_mode_waaligns the node config with the HCA capability (old chips use the WA path with offset mode cleared; newer ones use native offset mode).If you want, a brief comment tying
header_length_field_mode_wato the PRMheader_length_field_offset_modebit here would make the intent easier to follow for future readers, but the current logic is functionally consistent.Also applies to: 575-575
drivers/common/mlx5/mlx5_devx_cmds.c (1)
916-917: Derivingheader_length_field_mode_wafrom HCA cap is consistent with usageSetting
attr->header_length_field_mode_wa = !header_length_field_offset_modematches the intent inmlx5_flow_flex.c: older HCAs without offset-mode support take the WA path; newer ones rely on native offset semantics. Since this flag is only used to drive that choice, not exposed externally, the inversion here looks appropriate.You could optionally also cache the raw
header_length_field_offset_modecapability inmlx5_hca_flex_attrfor future debugging/telemetry, but it's not required for current logic.drivers/net/mlx5/mlx5.c (1)
1083-1091: SRv6 flex parser WA: consider validatingheader_length_mask_widthrangeThe WA path for legacy firmware assumes
attr->header_length_mask_widthis in a sane[1, 8]range; if firmware ever reports0or> 8, the computed offset will silently be wrong. A simpleMLX5_ASSERT(attr->header_length_mask_width > 0 && attr->header_length_mask_width <= 8);(or at least a warning) inside theheader_length_field_mode_wabranch would make this assumption explicit and easier to debug if it’s violated.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
doc/guides/prog_guide/img/kni_traffic_flow.pngis excluded by!**/*.pngdoc/guides/prog_guide/img/pkt_flow_kni.pngis excluded by!**/*.png
📒 Files selected for processing (38)
.mailmap(1 hunks)VERSION(1 hunks)doc/api/meson.build(3 hunks)doc/guides/cryptodevs/ionic.rst(2 hunks)doc/guides/freebsd_gsg/build_dpdk.rst(1 hunks)doc/guides/linux_gsg/amd_platform.rst(2 hunks)doc/guides/meson.build(1 hunks)doc/guides/nics/i40e.rst(2 hunks)doc/guides/nics/ice.rst(2 hunks)doc/guides/nics/ionic.rst(2 hunks)doc/guides/nics/mlx5.rst(11 hunks)doc/guides/rel_notes/release_25_11.rst(1 hunks)doc/guides/sample_app_ug/l3_forward.rst(2 hunks)doc/guides/windows_gsg/build_dpdk.rst(4 hunks)drivers/common/mlx5/mlx5_devx_cmds.c(2 hunks)drivers/common/mlx5/mlx5_devx_cmds.h(2 hunks)drivers/common/mlx5/mlx5_prm.h(4 hunks)drivers/net/hns3/hns3_rxtx.c(2 hunks)drivers/net/mlx5/linux/mlx5_ethdev_os.c(1 hunks)drivers/net/mlx5/mlx5.c(2 hunks)drivers/net/mlx5/mlx5_flow_flex.c(2 hunks)drivers/net/ngbe/ngbe_rxtx.c(1 hunks)drivers/net/ntnic/ntnic_ethdev.c(0 hunks)drivers/net/softnic/rte_eth_softnic.c(0 hunks)drivers/net/txgbe/txgbe_rxtx.c(1 hunks)examples/ip_reassembly/main.c(1 hunks)examples/l3fwd-power/main.c(4 hunks)examples/l3fwd/l3fwd.h(2 hunks)examples/l3fwd/l3fwd_acl.c(1 hunks)examples/l3fwd/l3fwd_common.h(2 hunks)examples/l3fwd/l3fwd_em.c(1 hunks)examples/l3fwd/l3fwd_fib.c(1 hunks)examples/l3fwd/l3fwd_lpm.c(1 hunks)examples/l3fwd/main.c(15 hunks)examples/meson.build(1 hunks)examples/server_node_efd/efd_server/main.c(1 hunks)examples/server_node_efd/shared/common.h(1 hunks)examples/vdpa/main.c(3 hunks)
💤 Files with no reviewable changes (2)
- drivers/net/ntnic/ntnic_ethdev.c
- drivers/net/softnic/rte_eth_softnic.c
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Sourcery review
🔇 Additional comments (54)
drivers/net/hns3/hns3_rxtx.c (2)
4547-4565: Non-started path now exposes a safe, non-NULL tx_pkt_prepareSetting
eth_dev->tx_pkt_prepare = rte_eth_tx_pkt_prepare_dummy;in the non-started/resetting branch keeps the API surface consistent (no NULL callbacks) while TX is disabled viarte_eth_pkt_burst_dummy. This avoids potential NULL dereferences in callers that unconditionally invoketx_pkt_prepareeven when the port is down.
4917-4921: Stopping TX datapath correctly pairs dummy burst and dummy prepareAligning
dev->tx_pkt_preparewithrte_eth_tx_pkt_prepare_dummywhendev->tx_pkt_burstis set torte_eth_pkt_burst_dummyensures the fastpath pointers are always valid and mutually consistent during TX-stop, which is important for any in-flight threads still using the fp ops table.drivers/net/txgbe/txgbe_rxtx.c (1)
2337-2348: Explicit dummy prepare in simple TX path is appropriateUsing
rte_eth_tx_pkt_prepare_dummyfor the simple/no-offload TX path makes the contract clear (no special preparation required) and guaranteestx_pkt_prepareis always a valid function pointer, while the full-featured path still usestxgbe_prep_pktsas before.drivers/net/ngbe/ngbe_rxtx.c (1)
1924-1924: All verifications passed. The change is safe and follows established DPDK patterns.The function
rte_eth_tx_pkt_prepare_dummyis properly declared inlib/ethdev/ethdev_driver.h:1923and implemented as an exported internal symbol inlib/ethdev/ethdev_driver.c. The assignment at line 1924 in ngbe_rxtx.c is consistent with its usage across multiple drivers (hns3, txgbe, ntnic, softnic, ixgbe, ice, fm10k), confirming this is a standard defensive programming pattern in DPDK to prevent null pointer dereferences.examples/l3fwd-power/main.c (3)
1746-1746: LGTM!The macro definition follows the established naming convention and pattern used for other command-line options in this file.
1753-1753: LGTM!The variable declaration is appropriate for storing the parsed speed value.
1773-1773: LGTM!The option is correctly added to the long options array with
has_arg=1to indicate it requires an argument.examples/server_node_efd/efd_server/main.c (1)
71-71: Buffer size is correctly calculated and adequate.The macro
RTE_ETHER_ADDR_FMT_SIZEis defined as 18, which represents 17 characters for the MAC address format"XX:XX:XX:XX:XX:XX"plus 1 for the null terminator. The buffer allocation ofRTE_ETHER_ADDR_FMT_SIZE + 1equals 19 bytes, which correctly accommodates the formatted MAC address (17 chars) + newline (1 char) + null terminator (1 byte). The format stringRTE_ETHER_ADDR_PRT_FMT "\n"produces exactly 18 characters of output, fitting safely within the allocated buffer.examples/l3fwd/l3fwd_common.h (2)
28-30: LGTM! Clean separation of RX and TX burst configuration.The introduction of separate
rx_burst_sizeandtx_burst_sizevariables provides better control over RX and TX paths independently.
77-77: Correct usage oftx_burst_sizefor TX fast-path decision.The change from
MAX_TX_BURSTtotx_burst_sizeallows runtime configuration of the TX bypass threshold, which is appropriate for this transmit optimization path.examples/l3fwd/l3fwd_acl.c (1)
1138-1139: Consistent RX burst size migration.The update from
nb_pkt_per_bursttorx_burst_sizecorrectly applies the new RX-specific burst configuration to the packet receive path.examples/l3fwd/l3fwd_fib.c (1)
241-242: Aligned with RX burst size refactoring.The migration to
rx_burst_sizeis consistent with the broader refactoring effort to provide independent RX and TX burst configuration.examples/l3fwd/l3fwd_em.c (1)
646-647: Consistent RX burst configuration.The change maintains consistency with the RX/TX burst size separation implemented across all L3fwd lookup modes.
doc/guides/sample_app_ug/l3_forward.rst (1)
80-81: Documentation correctly reflects new burst options.The documentation accurately describes the new
--rx-burstand--tx-burstcommand-line options with their default values.Also applies to: 118-121
examples/l3fwd/l3fwd_lpm.c (1)
207-208: Completes RX burst size migration across all lookup modes.This change ensures all L3fwd lookup modes (LPM, EM, FIB, ACL) consistently use
rx_burst_sizefor receive operations.examples/l3fwd/l3fwd.h (1)
115-115: Correct public declaration update.The extern declaration properly reflects the new
rx_burst_sizevariable that replaces the previousnb_pkt_per_burst.examples/l3fwd/main.c (5)
60-62: Clean initialization of burst size variables.The global variables
rx_burst_sizeandtx_burst_sizeare properly initialized toDEFAULT_PKT_BURST(32).
949-955: Correct argument passing to refactored function.The calls to
parse_pkt_burstcorrectly pass:
trueand&rx_burst_sizefor RX burst optionfalseand&tx_burst_sizefor TX burst optionThis properly wires the command-line options to their respective variables.
1690-1690: Helpful runtime feedback.The log message provides clear visibility into the burst sizes being used at runtime, which aids in debugging and configuration verification.
404-406: Documentation updates match code changes.The help text correctly documents:
--rx-burst NPKTSand--tx-burst NPKTSoptions- Default value of 32 for both
- Removal of the old generic
--burstoptionAlso applies to: 433-436, 468-469
703-750: I'll verify the concerns raised in the review comment about theparse_pkt_burstfunction. Let me start by examining how this function is called and whether port 0 validation happens before it's invoked.
<function_calls>
#!/bin/bashSearch for parse_pkt_burst function calls and context
rg -n "parse_pkt_burst" examples/l3fwd/main.c -A 3 -B 3
</function_calls>
<function_calls>
#!/bin/bashSearch for port initialization and validation patterns before parse_pkt_burst is used
Check where rx_burst_size and tx_burst_size are set in main
rg -n "rx_burst_size|tx_burst_size" examples/l3fwd/main.c | head -30
</function_calls>
<function_calls>
#!/bin/bashLook at the overall context around line 703-750 to see the function signature and how it's used
sed -n '680,760p' examples/l3fwd/main.c | cat -n
</function_calls>VERSION (1)
1-1: LGTM: Version bump to RC4.Standard release candidate version progression from rc3 to rc4.
.mailmap (1)
1927-1927: LGTM: New author entry added.Proper addition of Yang Xu's email mapping following the established format.
doc/guides/cryptodevs/ionic.rst (2)
2-2: LGTM: Copyright year updated.Standard copyright year update to 2025.
19-20: LGTM: New hardware model documented.Proper addition of Pollara 400 single-port 400G AI NIC to the supported models list, consistent with the format of existing entries.
doc/guides/nics/ionic.rst (2)
2-2: LGTM: Copyright year updated.Standard copyright year update to 2025, consistent with the corresponding cryptodev documentation.
18-19: LGTM: New hardware model documented.Proper addition of Pollara 400 single-port 400G AI NIC, consistent with the corresponding entry in doc/guides/cryptodevs/ionic.rst.
drivers/net/mlx5/linux/mlx5_ethdev_os.c (1)
536-536: LGTM: Ensures clean link state on error.Zeroing the link state when link detection fails ensures the port is properly marked as down rather than retaining stale state. This fix aligns with the PR objective to handle the error branch correctly.
doc/guides/meson.build (1)
25-25: LGTM: Documentation install tagging added.Adding
install_tag: 'doc'enables selective installation of documentation artifacts, improving package management flexibility.doc/guides/freebsd_gsg/build_dpdk.rst (3)
19-19: LGTM: Python version updated.Updated from Python 3.8 to 3.11, reflecting current FreeBSD package availability. Python 3.8 reached end-of-life in October 2024.
23-24: LGTM: Note updated for Python 3.11.Correctly updated the explanatory note to reference Python 3.11 and the py311 prefix.
28-28: LGTM: Installation command updated.Consistent update to use py311-pyelftools in the installation example.
doc/guides/nics/ice.rst (2)
90-91: LGTM: E810 compatibility table updated.Proper addition of 25.11 release compatibility information for E810 adapters, following the established table format.
100-101: LGTM: E830 compatibility table updated.Proper addition of 25.11 release compatibility information for E830 adapters, consistent with the E810 table updates.
doc/guides/linux_gsg/amd_platform.rst (2)
25-27: Documentation updates look correct.The typo fix from "SIENNA" to "SIENA" and the addition of the TURIN tuning guide entry are appropriate updates to the AMD platform documentation.
112-113: Verified: Linux kernel 6.13 exists and is released.Linux kernel 6.13 was officially released on January 19, 2025, and is available in upstream repositories. The documentation reference to Linux 6.13 or higher is accurate and does not require correction. No issues found.
examples/meson.build (1)
81-87: Build configuration simplification looks good.The changes simplify
default_cflagsassignment and properly initializedefault_ldflagswithdpdk_extra_ldflagsbefore conditionally appending the export-dynamic flag for static builds.doc/api/meson.build (1)
30-31: Consistent documentation install tagging.Adding
install_tag: 'doc'to all documentation custom_target invocations enables selective installation viameson install --tags doc. This is a good improvement for build system organization.Also applies to: 80-81, 95-96
doc/guides/windows_gsg/build_dpdk.rst (2)
29-32: Updated LLVM download links.The update to use HTTPS and the newer GitHub releases URL for LLVM 19.1.0 is appropriate for keeping documentation current and secure.
141-147: Helpful Developer Command Prompt guidance.The added note about opening Developer Command Prompt from PowerShell with a link to the official Microsoft documentation provides valuable guidance for Windows developers.
doc/guides/nics/i40e.rst (1)
107-108: Driver compatibility table updated correctly.The addition of DPDK 25.11 entries with kernel driver version 2.28.13 and appropriate firmware versions follows the established table format and maintains documentation consistency.
Also applies to: 140-141
drivers/common/mlx5/mlx5_prm.h (4)
2118-2120: Capability structure bit field update.The addition of
header_length_field_offset_modefield and adjustment of reserved bits maintains the overall structure size. This aligns with the AI summary indicating this field is used in related parsing/offset logic.
4990-4992: Parse graph flex structure updated consistently.The addition of
header_length_field_offset_modefield inmlx5_ifc_parse_graph_flex_bitsmirrors the change inmlx5_ifc_parse_graph_node_cap_bits, maintaining consistency between capability and operational structures.
1600-1602: No code breaks from the enum-to-define conversion; the removed values have no usages.The steering format representation change from enum to preprocessor defines is fully compatible with existing code. All usages of the retained constants (
MLX5_STEERING_LOGIC_FORMAT_CONNECTX_5andMLX5_STEERING_LOGIC_FORMAT_CONNECTX_6DX) are straightforward equality comparisons that work identically with preprocessor defines. The removed enum values (CONNECTX_7andCONNECTX_8) have zero usages in the codebase.
2351-2351: Based on my verification, the review comment is analyzing a file that was not modified in this pull request.The actual changes in this PR are focused on fixing a port down state initialization issue in the MLX5 link detection error branch, as stated in the commit message: "The port down state was not initialized in the error branch of link detection when MLX NIC link status update failed."
The file
drivers/common/mlx5/mlx5_prm.hdoes not appear in the list of modified files in this commit. The structuremlx5_ifc_flow_table_esw_cap_bitswithreserved_at_0[0x800]exists in the codebase, but there is no change to this structure in the current PR. Therefore, the concern about a size change from0x200to0x800cannot be verified as part of this commit.The review comment should be dismissed or removed.
Likely an incorrect or invalid review comment.
drivers/common/mlx5/mlx5_devx_cmds.c (1)
786-788: Flex parser create now correctly propagates offset-mode bitPlumbing
data->header_length_field_offset_modeinto theparse_graph_flex.header_length_field_offset_modefield is consistent with howmlx5_flex_translate_length()now fills the node attribute. Zero-init ofdataensures this bit is well-defined even for non-OFFSET modes.drivers/common/mlx5/mlx5_devx_cmds.h (2)
122-127: Newheader_length_field_mode_waflag is well-scoped in flex capsAdding
header_length_field_mode_waas a 1-bit field inmlx5_hca_flex_attrmatches how it’s queried and used (pure internal capability hint for the FLEX offset workaround). No other struct users in this file rely on its previous padding, so this extension is safe within the PMD.
647-655: Graph node gains explicitheader_length_field_offset_modebit consistent with DevX usageIntroducing
header_length_field_offset_mode:1intomlx5_devx_graph_node_attraligns with the new MLX5 PRM field and is wired up in both the translator andmlx5_devx_cmd_create_flex_parser(). Given the struct is purely driver-internal, this addition is low risk and improves fidelity with hardware capabilities.drivers/net/mlx5/mlx5.c (1)
1494-1497: Default DV flow steering and duplicate-pattern policy look consistentSetting
config->dv_flow_en = 1andconfig->allow_duplicate_pattern = 1as defaults, then downgradingdv_flow_enif!sh->dev_cap.dv_flow_enor whendv_esw_enrequires it, matches the documented behavior (DV enabled by default when supported, legacy Verbs otherwise) and keeps the existing capability gating logic intact. No functional issues spotted here.Also applies to: 1512-1524
doc/guides/nics/mlx5.rst (5)
650-652: Docs for DV/HWS defaults and duplicate-pattern behavior align with implementationThe new notes that (a) tunnel offload in
dv_xmeta_en=3is not supported with the synchronous API when using HWS, (b)dv_flow_ennow defaults to1(DV) when supported and falls back to0(Verbs), and (c)allow_duplicate_patterndefaults to1, all match the updated initialization inmlx5_shared_dev_ctx_args_config(). Wording is clear and matches current behavior.Also applies to: 689-701, 824-837
1366-1444: HWS flow configuration and sync-API limitations are clearly documentedThe new note requiring
rte_flow_configure()before using the async flow API (and recommending it for the sync API), plus the detailed list of synchronous-on-HWS limitations (match-size constraints, rule-update semantics, defaultrte_flow_port_attr, and partial-mask caveat) give users a realistic picture of current constraints. The caveat aboutspecneeding to be ANDed with the mask is particularly useful. No issues from a docs/behavior perspective.
2396-2403: Port-representor semantics with sync API + HWS are described preciselyThe additional limitations for synchronous flow API with HWS (
PORT_REPRESENTORitem unsupported, no transfer rules on representor ports, proxy-port rules matching all ports unless a represented port is explicitly matched) are specific and actionable, and they match the expected behavior of the current HWS implementation. The section reads clearly.
2593-2596: Sync HWS limitation for MARK vs META is well capturedStating that
RTE_FLOW_ITEM_TYPE_MARKis unsupported with synchronous HWS, and recommendingRTE_FLOW_ITEM_TYPE_METAas the 32‑bit alternative, is consistent with how the matching hardware resources are carved up and prevents users from relying on a path that won’t work. No changes needed.
2947-2949: Additional HWS-specific limitations (meter vs meter_mark, GRE root-table match) look correctClarifying that only
RTE_FLOW_ACTION_TYPE_METER_MARKis supported (notRTE_FLOW_ACTION_TYPE_METER) when using HWS, and that matching GRE’sc_rsvd0_verfield is not supported on group 0 with synchronous HWS, matches known HWS constraints and avoids over‑promising capabilities in the docs. The wording is concise and unambiguous.Also applies to: 3819-3821
| * DOCA: | ||
|
|
||
| * DOCA 3.2.0-125000 and above |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix indentation for DOCA entry.
The DOCA entry under IBM Power 9 platforms has inconsistent indentation (3 spaces) compared to the sibling entries (2 spaces). This may cause RST rendering issues.
- * DOCA:
+ * DOCA:
- * DOCA 3.2.0-125000 and above
+ * DOCA 3.2.0-125000 and above📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| * DOCA: | |
| * DOCA 3.2.0-125000 and above | |
| * DOCA: | |
| * DOCA 3.2.0-125000 and above |
🤖 Prompt for AI Agents
In doc/guides/rel_notes/release_25_11.rst around lines 598 to 600, the DOCA
bullet is indented with 3 spaces causing inconsistent RST structure; change the
DOCA entry indentation to 2 spaces to match sibling list items under the "IBM
Power 9 platforms" section so the list levels align and RST renders correctly.
| if (!strncmp(lgopts[option_index].name, | ||
| CMD_LINK_OPT_ETH_LINK_SPEED, | ||
| sizeof(CMD_LINK_OPT_ETH_LINK_SPEED))) { | ||
| speed_num = atoi(optarg); | ||
| if ((speed_num == RTE_ETH_SPEED_NUM_10M) || | ||
| (speed_num == RTE_ETH_SPEED_NUM_100M)) { | ||
| fprintf(stderr, "Unsupported fixed speed\n"); | ||
| print_usage(prgname); | ||
| return -1; | ||
| } | ||
| if (speed_num >= 0 && rte_eth_speed_bitflag(speed_num, 0) > 0) | ||
| port_conf.link_speeds = rte_eth_speed_bitflag(speed_num, 0); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace atoi with parse_uint and improve error handling.
The current implementation has several issues:
- Line 1961:
atoilacks error handling and returns 0 for invalid input without indicating an error. This file consistently usesparse_uintfor command-line argument parsing. - Line 1968: The condition
speed_num >= 0is always true foratoioutput and doesn't provide meaningful validation. - Line 1968:
rte_eth_speed_bitflagis called twice (once for validation, once for assignment), which is inefficient. - Lines 1968-1970: No error message is displayed when an invalid speed is provided, causing silent failure.
Apply this diff to improve input validation and error handling:
- if (!strncmp(lgopts[option_index].name,
- CMD_LINK_OPT_ETH_LINK_SPEED,
- sizeof(CMD_LINK_OPT_ETH_LINK_SPEED))) {
- speed_num = atoi(optarg);
- if ((speed_num == RTE_ETH_SPEED_NUM_10M) ||
- (speed_num == RTE_ETH_SPEED_NUM_100M)) {
- fprintf(stderr, "Unsupported fixed speed\n");
- print_usage(prgname);
- return -1;
- }
- if (speed_num >= 0 && rte_eth_speed_bitflag(speed_num, 0) > 0)
- port_conf.link_speeds = rte_eth_speed_bitflag(speed_num, 0);
- }
+ if (!strncmp(lgopts[option_index].name,
+ CMD_LINK_OPT_ETH_LINK_SPEED,
+ sizeof(CMD_LINK_OPT_ETH_LINK_SPEED))) {
+ uint32_t speed_val;
+ uint32_t bitflag;
+
+ if (parse_uint(optarg, UINT32_MAX, &speed_val) != 0) {
+ fprintf(stderr, "Invalid link speed value: %s\n", optarg);
+ print_usage(prgname);
+ return -1;
+ }
+
+ if ((speed_val == RTE_ETH_SPEED_NUM_10M) ||
+ (speed_val == RTE_ETH_SPEED_NUM_100M)) {
+ fprintf(stderr, "Unsupported fixed speed: %u Mbps\n", speed_val);
+ print_usage(prgname);
+ return -1;
+ }
+
+ bitflag = rte_eth_speed_bitflag(speed_val, 0);
+ if (bitflag == 0) {
+ fprintf(stderr, "Invalid link speed: %u Mbps\n", speed_val);
+ print_usage(prgname);
+ return -1;
+ }
+
+ port_conf.link_speeds = bitflag;
+ printf("Link speed configured to %u Mbps\n", speed_val);
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (!strncmp(lgopts[option_index].name, | |
| CMD_LINK_OPT_ETH_LINK_SPEED, | |
| sizeof(CMD_LINK_OPT_ETH_LINK_SPEED))) { | |
| speed_num = atoi(optarg); | |
| if ((speed_num == RTE_ETH_SPEED_NUM_10M) || | |
| (speed_num == RTE_ETH_SPEED_NUM_100M)) { | |
| fprintf(stderr, "Unsupported fixed speed\n"); | |
| print_usage(prgname); | |
| return -1; | |
| } | |
| if (speed_num >= 0 && rte_eth_speed_bitflag(speed_num, 0) > 0) | |
| port_conf.link_speeds = rte_eth_speed_bitflag(speed_num, 0); | |
| } | |
| if (!strncmp(lgopts[option_index].name, | |
| CMD_LINK_OPT_ETH_LINK_SPEED, | |
| sizeof(CMD_LINK_OPT_ETH_LINK_SPEED))) { | |
| uint32_t speed_val; | |
| uint32_t bitflag; | |
| if (parse_uint(optarg, UINT32_MAX, &speed_val) != 0) { | |
| fprintf(stderr, "Invalid link speed value: %s\n", optarg); | |
| print_usage(prgname); | |
| return -1; | |
| } | |
| if ((speed_val == RTE_ETH_SPEED_NUM_10M) || | |
| (speed_val == RTE_ETH_SPEED_NUM_100M)) { | |
| fprintf(stderr, "Unsupported fixed speed: %u Mbps\n", speed_val); | |
| print_usage(prgname); | |
| return -1; | |
| } | |
| bitflag = rte_eth_speed_bitflag(speed_val, 0); | |
| if (bitflag == 0) { | |
| fprintf(stderr, "Invalid link speed: %u Mbps\n", speed_val); | |
| print_usage(prgname); | |
| return -1; | |
| } | |
| port_conf.link_speeds = bitflag; | |
| printf("Link speed configured to %u Mbps\n", speed_val); | |
| } |
🤖 Prompt for AI Agents
In examples/l3fwd-power/main.c around lines 1958 to 1970, replace the use of
atoi with parse_uint and add proper validation and error handling: call
parse_uint(optarg, 10, &speed_num) and check its return value, if it fails print
an error and call print_usage(prgname) then return -1; compute bitflag once by
calling rte_eth_speed_bitflag(speed_num, 0) into a local variable, reject
unsupported fixed speeds (RTE_ETH_SPEED_NUM_10M and RTE_ETH_SPEED_NUM_100M) as
before, and if the bitflag is zero treat that as invalid input (print an error,
call print_usage and return -1), otherwise assign port_conf.link_speeds =
bitflag.
| if (unlikely(len == rx_burst_size)) { | ||
| send_burst(qconf, rx_burst_size, port); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Script executed:
#!/bin/bash
# Search for MAX_PKT_BURST, rx_burst_size, and tx_burst_size in l3fwd files
echo "=== Searching for MAX_PKT_BURST usage ==="
rg -n "MAX_PKT_BURST" --type c -g "examples/l3fwd/**" -A 3 -B 3
echo ""
echo "=== Searching for rx_burst_size ==="
rg -n "rx_burst_size" --type c -g "examples/l3fwd/**" -C 2
echo ""
echo "=== Searching for tx_burst_size ==="
rg -n "tx_burst_size" --type c -g "examples/l3fwd/**" -C 2Repository: ovsrobot/dpdk
<shell_result>
Repository: ovsrobot/dpdk
Exit code: 0
stdout:
=== Searching for MAX_PKT_BURST usage ===
examples/l3fwd/l3fwd_lpm_neon.h-171-l3fwd_lpm_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, uint16_t portid,
examples/l3fwd/l3fwd_lpm_neon.h-172- struct lcore_conf *qconf)
examples/l3fwd/l3fwd_lpm_neon.h-173-{
examples/l3fwd/l3fwd_lpm_neon.h:174: uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)];
examples/l3fwd/l3fwd_lpm_neon.h-175-
examples/l3fwd/l3fwd_lpm_neon.h-176- l3fwd_lpm_process_packets(nb_rx, pkts_burst, portid, dst_port, qconf,
examples/l3fwd/l3fwd_lpm_neon.h-177- 0);
--
examples/l3fwd/l3fwd_lpm.c-144-int
examples/l3fwd/l3fwd_lpm.c-145-lpm_main_loop(__rte_unused void *dummy)
examples/l3fwd/l3fwd_lpm.c-146-{
examples/l3fwd/l3fwd_lpm.c:147: struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
examples/l3fwd/l3fwd_lpm.c-148- unsigned lcore_id;
examples/l3fwd/l3fwd_lpm.c-149- uint64_t prev_tsc, diff_tsc, cur_tsc;
examples/l3fwd/l3fwd_lpm.c-150- int i, nb_rx;
--
examples/l3fwd/l3fwd_lpm.c-314- evt_rsrc->evq.nb_queues - 1];
examples/l3fwd/l3fwd_lpm.c-315- const uint8_t event_d_id = evt_rsrc->event_d_id;
examples/l3fwd/l3fwd_lpm.c-316- const uint16_t deq_len = evt_rsrc->deq_depth;
examples/l3fwd/l3fwd_lpm.c:317: struct rte_event events[MAX_PKT_BURST];
examples/l3fwd/l3fwd_lpm.c-318- int i, nb_enq = 0, nb_deq = 0;
examples/l3fwd/l3fwd_lpm.c-319- struct lcore_conf *lconf;
examples/l3fwd/l3fwd_lpm.c-320- unsigned int lcore_id;
--
examples/l3fwd/l3fwd_lpm.c-458- evt_rsrc->evq.event_q_id[evt_rsrc->evq.nb_queues - 1];
examples/l3fwd/l3fwd_lpm.c-459- const uint8_t event_d_id = evt_rsrc->event_d_id;
examples/l3fwd/l3fwd_lpm.c-460- const uint16_t deq_len = evt_rsrc->deq_depth;
examples/l3fwd/l3fwd_lpm.c:461: struct rte_event events[MAX_PKT_BURST];
examples/l3fwd/l3fwd_lpm.c-462- int i, nb_enq = 0, nb_deq = 0;
examples/l3fwd/l3fwd_lpm.c-463- struct lcore_conf *lconf;
examples/l3fwd/l3fwd_lpm.c-464- uint16_t *dst_port_list;
--
examples/l3fwd/main.c-54-
examples/l3fwd/main.c-55-#define MAX_LCORE_PARAMS 1024
examples/l3fwd/main.c-56-
examples/l3fwd/main.c:57:static_assert(MEMPOOL_CACHE_SIZE >= MAX_PKT_BURST, "MAX_PKT_BURST should be at most MEMPOOL_CACHE_SIZE");
examples/l3fwd/main.c-58-uint16_t nb_rxd = RX_DESC_DEFAULT;
examples/l3fwd/main.c-59-uint16_t nb_txd = TX_DESC_DEFAULT;
examples/l3fwd/main.c-60-uint32_t rx_burst_size = DEFAULT_PKT_BURST;
--
examples/l3fwd/main.c-713- if ((optarg[0] == '\0') || (end == NULL) || (*end != '\0'))
examples/l3fwd/main.c-714- return;
examples/l3fwd/main.c-715-
examples/l3fwd/main.c:716: if (pkt_burst > MAX_PKT_BURST) {
examples/l3fwd/main.c-717- RTE_LOG(INFO, L3FWD, "User provided burst must be <= %d. Using default value %d\n",
examples/l3fwd/main.c:718: MAX_PKT_BURST, *burst_sz);
examples/l3fwd/main.c-719- return;
examples/l3fwd/main.c-720- } else if (pkt_burst > 0) {
examples/l3fwd/main.c-721- *burst_sz = (uint32_t)pkt_burst;
--
examples/l3fwd/main.c-733- if (burst_size == 0) {
examples/l3fwd/main.c-734- RTE_LOG(INFO, L3FWD, "PMD does not recommend a burst size. Using default value %d. "
examples/l3fwd/main.c-735- "User provided value must be in [1, %d]\n",
examples/l3fwd/main.c:736: rx_burst_size, MAX_PKT_BURST);
examples/l3fwd/main.c-737- return;
examples/l3fwd/main.c:738: } else if (burst_size > MAX_PKT_BURST) {
examples/l3fwd/main.c-739- RTE_LOG(INFO, L3FWD, "PMD recommended burst size %d exceeds maximum value %d. "
examples/l3fwd/main.c-740- "Using default value %d\n",
examples/l3fwd/main.c:741: burst_size, MAX_PKT_BURST, rx_burst_size);
examples/l3fwd/main.c-742- return;
examples/l3fwd/main.c-743- }
examples/l3fwd/main.c-744- *burst_sz = burst_size;
--
examples/l3fwd/main.c-859- */
examples/l3fwd/main.c-860-#define NB_MBUF(nports) RTE_MAX( \
examples/l3fwd/main.c-861- (nports*nb_rx_queue*nb_rxd + \
examples/l3fwd/main.c:862: nports*nb_lcores*MAX_PKT_BURST + \
examples/l3fwd/main.c-863- nports*n_tx_queue*nb_txd + \
examples/l3fwd/main.c-864- nb_lcores*MEMPOOL_CACHE_SIZE), \
examples/l3fwd/main.c-865- (unsigned)8192)
--
examples/l3fwd/l3fwd_em.c-582-int
examples/l3fwd/l3fwd_em.c-583-em_main_loop(__rte_unused void *dummy)
examples/l3fwd/l3fwd_em.c-584-{
examples/l3fwd/l3fwd_em.c:585: struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
examples/l3fwd/l3fwd_em.c-586- unsigned lcore_id;
examples/l3fwd/l3fwd_em.c-587- uint64_t prev_tsc, diff_tsc, cur_tsc;
examples/l3fwd/l3fwd_em.c-588- int i, nb_rx;
--
examples/l3fwd/l3fwd_em.c-733- evt_rsrc->evq.nb_queues - 1];
examples/l3fwd/l3fwd_em.c-734- const uint8_t event_d_id = evt_rsrc->event_d_id;
examples/l3fwd/l3fwd_em.c-735- const uint16_t deq_len = evt_rsrc->deq_depth;
examples/l3fwd/l3fwd_em.c:736: struct rte_event events[MAX_PKT_BURST];
examples/l3fwd/l3fwd_em.c-737- int i, nb_enq = 0, nb_deq = 0;
examples/l3fwd/l3fwd_em.c-738- struct lcore_conf *lconf;
examples/l3fwd/l3fwd_em.c-739- unsigned int lcore_id;
--
examples/l3fwd/l3fwd_em.c-859- evt_rsrc->evq.event_q_id[evt_rsrc->evq.nb_queues - 1];
examples/l3fwd/l3fwd_em.c-860- const uint8_t event_d_id = evt_rsrc->event_d_id;
examples/l3fwd/l3fwd_em.c-861- const uint16_t deq_len = evt_rsrc->deq_depth;
examples/l3fwd/l3fwd_em.c:862: struct rte_event events[MAX_PKT_BURST];
examples/l3fwd/l3fwd_em.c-863- int i, nb_enq = 0, nb_deq = 0;
examples/l3fwd/l3fwd_em.c-864- struct lcore_conf *lconf;
examples/l3fwd/l3fwd_em.c-865- unsigned int lcore_id;
--
examples/l3fwd/l3fwd.h-24-#define TX_DESC_DEFAULT 1024
examples/l3fwd/l3fwd.h-25-
examples/l3fwd/l3fwd.h-26-#define DEFAULT_PKT_BURST 32
examples/l3fwd/l3fwd.h:27:#define MAX_PKT_BURST 512
examples/l3fwd/l3fwd.h-28-#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
examples/l3fwd/l3fwd.h-29-
examples/l3fwd/l3fwd.h-30-#define MEMPOOL_CACHE_SIZE RTE_MEMPOOL_CACHE_MAX_SIZE
examples/l3fwd/l3fwd.h-31-#define MAX_RX_QUEUE_PER_LCORE 16
examples/l3fwd/l3fwd.h-32-
examples/l3fwd/l3fwd.h:33:#define VECTOR_SIZE_DEFAULT MAX_PKT_BURST
examples/l3fwd/l3fwd.h-34-#define VECTOR_TMO_NS_DEFAULT 1E6 /* 1ms */
examples/l3fwd/l3fwd.h-35-
examples/l3fwd/l3fwd.h-36-#define NB_SOCKETS 8
--
examples/l3fwd/l3fwd.h-66-
examples/l3fwd/l3fwd.h-67-struct mbuf_table {
examples/l3fwd/l3fwd.h-68- uint16_t len;
examples/l3fwd/l3fwd.h:69: struct rte_mbuf *m_table[MAX_PKT_BURST];
examples/l3fwd/l3fwd.h-70-};
examples/l3fwd/l3fwd.h-71-
examples/l3fwd/l3fwd.h-72-struct __rte_cache_aligned lcore_rx_queue {
--
examples/l3fwd/l3fwd_fib.c-181-int
examples/l3fwd/l3fwd_fib.c-182-fib_main_loop(__rte_unused void *dummy)
examples/l3fwd/l3fwd_fib.c-183-{
examples/l3fwd/l3fwd_fib.c:184: struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
examples/l3fwd/l3fwd_fib.c-185- unsigned int lcore_id;
examples/l3fwd/l3fwd_fib.c-186- uint64_t prev_tsc, diff_tsc, cur_tsc;
examples/l3fwd/l3fwd_fib.c-187- int i, nb_rx;
--
examples/l3fwd/l3fwd_fib.c-264- evt_rsrc->evq.nb_queues - 1];
examples/l3fwd/l3fwd_fib.c-265- const uint8_t event_d_id = evt_rsrc->event_d_id;
examples/l3fwd/l3fwd_fib.c-266- const uint16_t deq_len = evt_rsrc->deq_depth;
examples/l3fwd/l3fwd_fib.c:267: struct rte_event events[MAX_PKT_BURST];
examples/l3fwd/l3fwd_fib.c-268- int i, nb_enq = 0, nb_deq = 0;
examples/l3fwd/l3fwd_fib.c-269- struct lcore_conf *lconf;
examples/l3fwd/l3fwd_fib.c-270- unsigned int lcore_id;
examples/l3fwd/l3fwd_fib.c-271-
examples/l3fwd/l3fwd_fib.c:272: uint32_t ipv4_arr[MAX_PKT_BURST];
examples/l3fwd/l3fwd_fib.c:273: struct rte_ipv6_addr ipv6_arr[MAX_PKT_BURST];
examples/l3fwd/l3fwd_fib.c:274: uint64_t hopsv4[MAX_PKT_BURST], hopsv6[MAX_PKT_BURST];
examples/l3fwd/l3fwd_fib.c:275: uint16_t nh, hops[MAX_PKT_BURST];
examples/l3fwd/l3fwd_fib.c:276: uint8_t type_arr[MAX_PKT_BURST];
examples/l3fwd/l3fwd_fib.c-277- uint32_t ipv4_cnt, ipv6_cnt;
examples/l3fwd/l3fwd_fib.c-278- uint32_t ipv4_arr_assem, ipv6_arr_assem;
examples/l3fwd/l3fwd_fib.c-279-
--
examples/l3fwd/l3fwd_fib.c-521- evt_rsrc->evq.event_q_id[evt_rsrc->evq.nb_queues - 1];
examples/l3fwd/l3fwd_fib.c-522- const uint8_t event_d_id = evt_rsrc->event_d_id;
examples/l3fwd/l3fwd_fib.c-523- const uint16_t deq_len = evt_rsrc->deq_depth;
examples/l3fwd/l3fwd_fib.c:524: struct rte_event events[MAX_PKT_BURST];
examples/l3fwd/l3fwd_fib.c-525- uint8_t *type_arr;
examples/l3fwd/l3fwd_fib.c-526- struct rte_ipv6_addr *ipv6_arr;
examples/l3fwd/l3fwd_fib.c-527- int nb_enq = 0, nb_deq = 0, i;
--
examples/l3fwd/l3fwd_acl.c-998- * returns number of packets to be dropped (hops[i] == BAD_PORT)
examples/l3fwd/l3fwd_acl.c-999- */
examples/l3fwd/l3fwd_acl.c-1000-static inline uint32_t
examples/l3fwd/l3fwd_acl.c:1001:acl_process_pkts(struct rte_mbuf *pkts[MAX_PKT_BURST],
examples/l3fwd/l3fwd_acl.c:1002: uint16_t hops[MAX_PKT_BURST], uint32_t num, int32_t socketid)
examples/l3fwd/l3fwd_acl.c-1003-{
examples/l3fwd/l3fwd_acl.c-1004- uint32_t i, k, n4, n6, res;
examples/l3fwd/l3fwd_acl.c-1005- struct acl_search_t acl_search;
--
examples/l3fwd/l3fwd_acl.c-1072-int
examples/l3fwd/l3fwd_acl.c-1073-acl_main_loop(__rte_unused void *dummy)
examples/l3fwd/l3fwd_acl.c-1074-{
examples/l3fwd/l3fwd_acl.c:1075: struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
examples/l3fwd/l3fwd_acl.c:1076: uint16_t hops[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)];
examples/l3fwd/l3fwd_acl.c-1077- unsigned int lcore_id;
examples/l3fwd/l3fwd_acl.c-1078- uint64_t prev_tsc, diff_tsc, cur_tsc;
examples/l3fwd/l3fwd_acl.c-1079- int i, nb_drop, nb_rx;
--
examples/l3fwd/l3fwd_neon.h-95- */
examples/l3fwd/l3fwd_neon.h-96-static __rte_always_inline void
examples/l3fwd/l3fwd_neon.h-97-send_packets_multi(struct lcore_conf *qconf, struct rte_mbuf **pkts_burst,
examples/l3fwd/l3fwd_neon.h:98: uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)],
examples/l3fwd/l3fwd_neon.h-99- int nb_rx)
examples/l3fwd/l3fwd_neon.h-100-{
examples/l3fwd/l3fwd_neon.h-101- int32_t k;
examples/l3fwd/l3fwd_neon.h-102- int j = 0;
examples/l3fwd/l3fwd_neon.h-103- uint16_t dlp;
examples/l3fwd/l3fwd_neon.h-104- uint16_t *lp;
examples/l3fwd/l3fwd_neon.h:105: uint16_t pnum[MAX_PKT_BURST + 1];
examples/l3fwd/l3fwd_neon.h-106-
examples/l3fwd/l3fwd_neon.h-107- /*
examples/l3fwd/l3fwd_neon.h-108- * Finish packet processing and group consecutive
--
examples/l3fwd/l3fwd_neon.h-153- } else {
examples/l3fwd/l3fwd_neon.h-154- /* set dlp and lp to the never used values. */
examples/l3fwd/l3fwd_neon.h-155- dlp = BAD_PORT - 1;
examples/l3fwd/l3fwd_neon.h:156: lp = pnum + MAX_PKT_BURST;
examples/l3fwd/l3fwd_neon.h-157- }
examples/l3fwd/l3fwd_neon.h-158-
examples/l3fwd/l3fwd_neon.h-159- /* Process up to last 3 packets one by one. */
--
examples/l3fwd/l3fwd_lpm_sse.h-87- struct lcore_conf *qconf, const uint8_t do_step3)
examples/l3fwd/l3fwd_lpm_sse.h-88-{
examples/l3fwd/l3fwd_lpm_sse.h-89- int32_t j;
examples/l3fwd/l3fwd_lpm_sse.h:90: __m128i dip[MAX_PKT_BURST / FWDSTEP];
examples/l3fwd/l3fwd_lpm_sse.h:91: uint32_t ipv4_flag[MAX_PKT_BURST / FWDSTEP];
examples/l3fwd/l3fwd_lpm_sse.h-92- const int32_t k = RTE_ALIGN_FLOOR(nb_rx, FWDSTEP);
examples/l3fwd/l3fwd_lpm_sse.h-93-
examples/l3fwd/l3fwd_lpm_sse.h-94- for (j = 0; j != k; j += FWDSTEP)
--
examples/l3fwd/l3fwd_lpm_sse.h-129-l3fwd_lpm_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, uint16_t portid,
examples/l3fwd/l3fwd_lpm_sse.h-130- struct lcore_conf *qconf)
examples/l3fwd/l3fwd_lpm_sse.h-131-{
examples/l3fwd/l3fwd_lpm_sse.h:132: uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)];
examples/l3fwd/l3fwd_lpm_sse.h-133-
examples/l3fwd/l3fwd_lpm_sse.h-134- l3fwd_lpm_process_packets(nb_rx, pkts_burst, portid, dst_port, qconf,
examples/l3fwd/l3fwd_lpm_sse.h-135- 0);
--
examples/l3fwd/l3fwd_lpm_altivec.h-101- struct lcore_conf *qconf, const uint8_t do_step3)
examples/l3fwd/l3fwd_lpm_altivec.h-102-{
examples/l3fwd/l3fwd_lpm_altivec.h-103- int32_t j;
examples/l3fwd/l3fwd_lpm_altivec.h:104: __vector unsigned int dip[MAX_PKT_BURST / FWDSTEP];
examples/l3fwd/l3fwd_lpm_altivec.h:105: uint32_t ipv4_flag[MAX_PKT_BURST / FWDSTEP];
examples/l3fwd/l3fwd_lpm_altivec.h-106- const int32_t k = RTE_ALIGN_FLOOR(nb_rx, FWDSTEP);
examples/l3fwd/l3fwd_lpm_altivec.h-107-
examples/l3fwd/l3fwd_lpm_altivec.h-108- for (j = 0; j != k; j += FWDSTEP)
--
examples/l3fwd/l3fwd_lpm_altivec.h-145-l3fwd_lpm_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, uint8_t portid,
examples/l3fwd/l3fwd_lpm_altivec.h-146- struct lcore_conf *qconf)
examples/l3fwd/l3fwd_lpm_altivec.h-147-{
examples/l3fwd/l3fwd_lpm_altivec.h:148: uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)];
examples/l3fwd/l3fwd_lpm_altivec.h-149-
examples/l3fwd/l3fwd_lpm_altivec.h-150- l3fwd_lpm_process_packets(nb_rx, pkts_burst, portid, dst_port, qconf,
examples/l3fwd/l3fwd_lpm_altivec.h-151- 0);
--
examples/l3fwd/l3fwd_sse.h-94- */
examples/l3fwd/l3fwd_sse.h-95-static __rte_always_inline void
examples/l3fwd/l3fwd_sse.h-96-send_packets_multi(struct lcore_conf *qconf, struct rte_mbuf **pkts_burst,
examples/l3fwd/l3fwd_sse.h:97: uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)],
examples/l3fwd/l3fwd_sse.h-98- int nb_rx)
examples/l3fwd/l3fwd_sse.h-99-{
examples/l3fwd/l3fwd_sse.h-100- int32_t k;
examples/l3fwd/l3fwd_sse.h-101- int j = 0;
examples/l3fwd/l3fwd_sse.h-102- uint16_t dlp;
examples/l3fwd/l3fwd_sse.h-103- uint16_t *lp;
examples/l3fwd/l3fwd_sse.h:104: uint16_t pnum[MAX_PKT_BURST + 1];
examples/l3fwd/l3fwd_sse.h-105-
examples/l3fwd/l3fwd_sse.h-106- /*
examples/l3fwd/l3fwd_sse.h-107- * Finish packet processing and group consecutive
--
examples/l3fwd/l3fwd_sse.h-153- } else {
examples/l3fwd/l3fwd_sse.h-154- /* set dlp and lp to the never used values. */
examples/l3fwd/l3fwd_sse.h-155- dlp = BAD_PORT - 1;
examples/l3fwd/l3fwd_sse.h:156: lp = pnum + MAX_PKT_BURST;
examples/l3fwd/l3fwd_sse.h-157- }
examples/l3fwd/l3fwd_sse.h-158-
examples/l3fwd/l3fwd_sse.h-159- /* Process up to last 3 packets one by one. */
--
examples/l3fwd/l3fwd_em_sequential.h-79- uint16_t portid, struct lcore_conf *qconf)
examples/l3fwd/l3fwd_em_sequential.h-80-{
examples/l3fwd/l3fwd_em_sequential.h-81- int32_t i, j;
examples/l3fwd/l3fwd_em_sequential.h:82: uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)];
examples/l3fwd/l3fwd_em_sequential.h-83-
examples/l3fwd/l3fwd_em_sequential.h-84- if (nb_rx > 0) {
examples/l3fwd/l3fwd_em_sequential.h-85- rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[0],
--
examples/l3fwd/l3fwd_event.c-129- nb_mbuf = RTE_MAX(nb_ports * nb_rxd +
examples/l3fwd/l3fwd_event.c-130- nb_ports * nb_txd +
examples/l3fwd/l3fwd_event.c-131- nb_ports * nb_lcores *
examples/l3fwd/l3fwd_event.c:132: MAX_PKT_BURST +
examples/l3fwd/l3fwd_event.c-133- nb_lcores * MEMPOOL_CACHE_SIZE,
examples/l3fwd/l3fwd_event.c-134- 8192u);
examples/l3fwd/l3fwd_event.c-135- ret = init_mem(0, nb_mbuf);
examples/l3fwd/l3fwd_event.c-136- } else {
examples/l3fwd/l3fwd_event.c-137- nb_mbuf = RTE_MAX(nb_rxd + nb_rxd +
examples/l3fwd/l3fwd_event.c:138: nb_lcores * MAX_PKT_BURST +
examples/l3fwd/l3fwd_event.c-139- nb_lcores * MEMPOOL_CACHE_SIZE,
examples/l3fwd/l3fwd_event.c-140- 8192u);
examples/l3fwd/l3fwd_event.c-141- ret = init_mem(port_id, nb_mbuf);
--
examples/l3fwd/l3fwd_altivec.h-120- */
examples/l3fwd/l3fwd_altivec.h-121-static __rte_always_inline void
examples/l3fwd/l3fwd_altivec.h-122-send_packets_multi(struct lcore_conf *qconf, struct rte_mbuf **pkts_burst,
examples/l3fwd/l3fwd_altivec.h:123: uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)],
examples/l3fwd/l3fwd_altivec.h-124- int nb_rx)
examples/l3fwd/l3fwd_altivec.h-125-{
examples/l3fwd/l3fwd_altivec.h-126- int32_t k;
examples/l3fwd/l3fwd_altivec.h-127- int j = 0;
examples/l3fwd/l3fwd_altivec.h-128- uint16_t dlp;
examples/l3fwd/l3fwd_altivec.h-129- uint16_t *lp;
examples/l3fwd/l3fwd_altivec.h:130: uint16_t pnum[MAX_PKT_BURST + 1];
examples/l3fwd/l3fwd_altivec.h-131-
examples/l3fwd/l3fwd_altivec.h-132- /*
examples/l3fwd/l3fwd_altivec.h-133- * Finish packet processing and group consecutive
--
examples/l3fwd/l3fwd_altivec.h-181- } else {
examples/l3fwd/l3fwd_altivec.h-182- /* set dlp and lp to the never used values. */
examples/l3fwd/l3fwd_altivec.h-183- dlp = BAD_PORT - 1;
examples/l3fwd/l3fwd_altivec.h:184: lp = pnum + MAX_PKT_BURST;
examples/l3fwd/l3fwd_altivec.h-185- }
examples/l3fwd/l3fwd_altivec.h-186-
examples/l3fwd/l3fwd_altivec.h-187- /* Process up to last 3 packets one by one. */
--
examples/l3fwd/l3fwd_acl_scalar.h-32- uint32_t num_ipv4;
examples/l3fwd/l3fwd_acl_scalar.h-33- uint32_t num_ipv6;
examples/l3fwd/l3fwd_acl_scalar.h-34-
examples/l3fwd/l3fwd_acl_scalar.h:35: uint8_t types[MAX_PKT_BURST];
examples/l3fwd/l3fwd_acl_scalar.h-36-
examples/l3fwd/l3fwd_acl_scalar.h:37: const uint8_t *data_ipv4[MAX_PKT_BURST];
examples/l3fwd/l3fwd_acl_scalar.h:38: uint32_t res_ipv4[MAX_PKT_BURST];
examples/l3fwd/l3fwd_acl_scalar.h-39-
examples/l3fwd/l3fwd_acl_scalar.h:40: const uint8_t *data_ipv6[MAX_PKT_BURST];
examples/l3fwd/l3fwd_acl_scalar.h:41: uint32_t res_ipv6[MAX_PKT_BURST];
examples/l3fwd/l3fwd_acl_scalar.h-42-};
examples/l3fwd/l3fwd_acl_scalar.h-43-
examples/l3fwd/l3fwd_acl_scalar.h-44-static inline void
--
examples/l3fwd/l3fwd_em_hlm.h-249-l3fwd_em_send_packets(int nb_rx, struct rte_mbuf **pkts_burst, uint16_t portid,
examples/l3fwd/l3fwd_em_hlm.h-250- struct lcore_conf *qconf)
examples/l3fwd/l3fwd_em_hlm.h-251-{
examples/l3fwd/l3fwd_em_hlm.h:252: uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)];
examples/l3fwd/l3fwd_em_hlm.h-253-
examples/l3fwd/l3fwd_em_hlm.h-254- l3fwd_em_process_packets(nb_rx, pkts_burst, dst_port, portid, qconf, 0);
examples/l3fwd/l3fwd_em_hlm.h-255- send_packets_multi(qconf, pkts_burst, dst_port, nb_rx);
--
examples/l3fwd/l3fwd_em_hlm.h-265- struct lcore_conf *qconf)
examples/l3fwd/l3fwd_em_hlm.h-266-{
examples/l3fwd/l3fwd_em_hlm.h-267- int32_t i, j, pos;
examples/l3fwd/l3fwd_em_hlm.h:268: uint16_t dst_port[MAX_PKT_BURST];
examples/l3fwd/l3fwd_em_hlm.h:269: struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
examples/l3fwd/l3fwd_em_hlm.h-270-
examples/l3fwd/l3fwd_em_hlm.h-271- /*
examples/l3fwd/l3fwd_em_hlm.h-272- * Send nb_rx - nb_rx % EM_HASH_LOOKUP_COUNT packets
--
examples/l3fwd/l3fwd_common.h-89- */
examples/l3fwd/l3fwd_common.h-90-
examples/l3fwd/l3fwd_common.h-91- n = len + num;
examples/l3fwd/l3fwd_common.h:92: n = (n > MAX_PKT_BURST) ? MAX_PKT_BURST - len : num;
examples/l3fwd/l3fwd_common.h-93-
examples/l3fwd/l3fwd_common.h-94- j = 0;
examples/l3fwd/l3fwd_common.h-95- switch (n % FWDSTEP) {
--
examples/l3fwd/l3fwd_common.h-115- len += n;
examples/l3fwd/l3fwd_common.h-116-
examples/l3fwd/l3fwd_common.h-117- /* enough pkts to be sent */
examples/l3fwd/l3fwd_common.h:118: if (unlikely(len == MAX_PKT_BURST)) {
examples/l3fwd/l3fwd_common.h-119-
examples/l3fwd/l3fwd_common.h:120: send_burst(qconf, MAX_PKT_BURST, port);
examples/l3fwd/l3fwd_common.h-121-
examples/l3fwd/l3fwd_common.h-122- /* copy rest of the packets into the TX buffer. */
examples/l3fwd/l3fwd_common.h-123- len = num - n;
=== Searching for rx_burst_size ===
examples/l3fwd/l3fwd_common.h-26-#define SENDM_PORT_OVERHEAD(x) (x)
examples/l3fwd/l3fwd_common.h-27-
examples/l3fwd/l3fwd_common.h:28:extern uint32_t rx_burst_size;
examples/l3fwd/l3fwd_common.h-29-extern uint32_t tx_burst_size;
examples/l3fwd/l3fwd_common.h-30-
--
examples/l3fwd/l3fwd_em.c-645- queueid = qconf->rx_queue_list[i].queue_id;
examples/l3fwd/l3fwd_em.c-646- nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst,
examples/l3fwd/l3fwd_em.c:647: rx_burst_size);
examples/l3fwd/l3fwd_em.c-648- if (nb_rx == 0)
examples/l3fwd/l3fwd_em.c-649- continue;
--
examples/l3fwd/l3fwd.h-113-extern uint32_t max_pkt_len;
examples/l3fwd/l3fwd.h-114-
examples/l3fwd/l3fwd.h:115:extern uint32_t rx_burst_size;
examples/l3fwd/l3fwd.h-116-extern uint32_t mb_mempool_cache_size;
examples/l3fwd/l3fwd.h-117-
--
examples/l3fwd/l3fwd.h-149-
examples/l3fwd/l3fwd.h-150- /* enough pkts to be sent */
examples/l3fwd/l3fwd.h:151: if (unlikely(len == rx_burst_size)) {
examples/l3fwd/l3fwd.h:152: send_burst(qconf, rx_burst_size, port);
examples/l3fwd/l3fwd.h-153- len = 0;
examples/l3fwd/l3fwd.h-154- }
--
examples/l3fwd/l3fwd_lpm.c-206- queueid = qconf->rx_queue_list[i].queue_id;
examples/l3fwd/l3fwd_lpm.c-207- nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst,
examples/l3fwd/l3fwd_lpm.c:208: rx_burst_size);
examples/l3fwd/l3fwd_lpm.c-209- if (nb_rx == 0)
examples/l3fwd/l3fwd_lpm.c-210- continue;
--
examples/l3fwd/l3fwd_fib.c-240- queueid = qconf->rx_queue_list[i].queue_id;
examples/l3fwd/l3fwd_fib.c-241- nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst,
examples/l3fwd/l3fwd_fib.c:242: rx_burst_size);
examples/l3fwd/l3fwd_fib.c-243- if (nb_rx == 0)
examples/l3fwd/l3fwd_fib.c-244- continue;
--
examples/l3fwd/main.c-58-uint16_t nb_rxd = RX_DESC_DEFAULT;
examples/l3fwd/main.c-59-uint16_t nb_txd = TX_DESC_DEFAULT;
examples/l3fwd/main.c:60:uint32_t rx_burst_size = DEFAULT_PKT_BURST;
examples/l3fwd/main.c-61-uint32_t mb_mempool_cache_size = MEMPOOL_CACHE_SIZE;
examples/l3fwd/main.c-62-uint32_t tx_burst_size = DEFAULT_PKT_BURST;
--
examples/l3fwd/main.c-734- RTE_LOG(INFO, L3FWD, "PMD does not recommend a burst size. Using default value %d. "
examples/l3fwd/main.c-735- "User provided value must be in [1, %d]\n",
examples/l3fwd/main.c:736: rx_burst_size, MAX_PKT_BURST);
examples/l3fwd/main.c-737- return;
examples/l3fwd/main.c-738- } else if (burst_size > MAX_PKT_BURST) {
examples/l3fwd/main.c-739- RTE_LOG(INFO, L3FWD, "PMD recommended burst size %d exceeds maximum value %d. "
examples/l3fwd/main.c-740- "Using default value %d\n",
examples/l3fwd/main.c:741: burst_size, MAX_PKT_BURST, rx_burst_size);
examples/l3fwd/main.c-742- return;
examples/l3fwd/main.c-743- }
--
examples/l3fwd/main.c-948-
examples/l3fwd/main.c-949- case CMD_LINE_OPT_PKT_RX_BURST_NUM:
examples/l3fwd/main.c:950: parse_pkt_burst(optarg, true, &rx_burst_size);
examples/l3fwd/main.c-951- break;
examples/l3fwd/main.c-952-
--
examples/l3fwd/main.c-1688- rte_exit(EXIT_FAILURE, "Invalid L3FWD parameters\n");
examples/l3fwd/main.c-1689-
examples/l3fwd/main.c:1690: RTE_LOG(INFO, L3FWD, "Using Rx burst %u Tx burst %u\n", rx_burst_size, tx_burst_size);
examples/l3fwd/main.c-1691-
examples/l3fwd/main.c-1692- /* Setup function pointers for lookup method. */
--
examples/l3fwd/l3fwd_acl.c-1137- queueid = qconf->rx_queue_list[i].queue_id;
examples/l3fwd/l3fwd_acl.c-1138- nb_rx = rte_eth_rx_burst(portid, queueid,
examples/l3fwd/l3fwd_acl.c:1139: pkts_burst, rx_burst_size);
examples/l3fwd/l3fwd_acl.c-1140-
examples/l3fwd/l3fwd_acl.c-1141- if (nb_rx > 0) {
=== Searching for tx_burst_size ===
examples/l3fwd/l3fwd_common.h-27-
examples/l3fwd/l3fwd_common.h-28-extern uint32_t rx_burst_size;
examples/l3fwd/l3fwd_common.h:29:extern uint32_t tx_burst_size;
examples/l3fwd/l3fwd_common.h-30-
examples/l3fwd/l3fwd_common.h-31-/*
--
examples/l3fwd/l3fwd_common.h-75- * then send them straightway.
examples/l3fwd/l3fwd_common.h-76- */
examples/l3fwd/l3fwd_common.h:77: if (num >= tx_burst_size && len == 0) {
examples/l3fwd/l3fwd_common.h-78- n = rte_eth_tx_burst(port, qconf->tx_queue_id[port], m, num);
examples/l3fwd/l3fwd_common.h-79- if (unlikely(n < num)) {
--
examples/l3fwd/main.c-60-uint32_t rx_burst_size = DEFAULT_PKT_BURST;
examples/l3fwd/main.c-61-uint32_t mb_mempool_cache_size = MEMPOOL_CACHE_SIZE;
examples/l3fwd/main.c:62:uint32_t tx_burst_size = DEFAULT_PKT_BURST;
examples/l3fwd/main.c-63-
examples/l3fwd/main.c-64-/**< Ports set in promiscuous mode off by default. */
--
examples/l3fwd/main.c-952-
examples/l3fwd/main.c-953- case CMD_LINE_OPT_PKT_TX_BURST_NUM:
examples/l3fwd/main.c:954: parse_pkt_burst(optarg, false, &tx_burst_size);
examples/l3fwd/main.c-955- break;
examples/l3fwd/main.c-956-
--
examples/l3fwd/main.c-1688- rte_exit(EXIT_FAILURE, "Invalid L3FWD parameters\n");
examples/l3fwd/main.c-1689-
examples/l3fwd/main.c:1690: RTE_LOG(INFO, L3FWD, "Using Rx burst %u Tx burst %u\n", rx_burst_size, tx_burst_size);
examples/l3fwd/main.c-1691-
examples/l3fwd/main.c-1692- /* Setup function pointers for lookup method. */
</shell_result>
Script executed:
#!/bin/bash
# Get the full context of send_single_packet function around lines 140-160
sed -n '130,165p' examples/l3fwd/l3fwd.hRepository: ovsrobot/dpdk
<shell_result>
Repository: ovsrobot/dpdk
Exit code: 0
stdout:
if (unlikely(ret < n)) {
do {
rte_pktmbuf_free(m_table[ret]);
} while (++ret < n);
}
return 0;
}
/* Enqueue a single packet, and send burst if queue is filled */
static inline int
send_single_packet(struct lcore_conf *qconf,
struct rte_mbuf *m, uint16_t port)
{
uint16_t len;
len = qconf->tx_mbufs[port].len;
qconf->tx_mbufs[port].m_table[len] = m;
len++;
/* enough pkts to be sent */
if (unlikely(len == rx_burst_size)) {
send_burst(qconf, rx_burst_size, port);
len = 0;
}
qconf->tx_mbufs[port].len = len;
return 0;
}
#ifdef DO_RFC_1812_CHECKS
static inline int
is_valid_ipv4_pkt(struct rte_ipv4_hdr *pkt, uint32_t link_len, uint64_t ol_flags)
{
/* From http://www.rfc-editor.org/rfc/rfc1812.txt section 5.2.2 */
/*
</shell_result>
Script executed:
#!/bin/bash
# Check if there are other send_burst calls in TX context
echo "=== Other send_burst calls ==="
rg -n "send_burst" --type c -g "examples/l3fwd/**" -B 2 -A 2Repository: ovsrobot/dpdk
<shell_result>
Repository: ovsrobot/dpdk
Exit code: 0
stdout:
=== Other send_burst calls ===
examples/l3fwd/l3fwd.h-118-/* Send burst of packets on an output interface */
examples/l3fwd/l3fwd.h-119-static inline int
examples/l3fwd/l3fwd.h:120:send_burst(struct lcore_conf *qconf, uint16_t n, uint16_t port)
examples/l3fwd/l3fwd.h-121-{
examples/l3fwd/l3fwd.h-122- struct rte_mbuf **m_table;
--
examples/l3fwd/l3fwd.h-150- /* enough pkts to be sent */
examples/l3fwd/l3fwd.h-151- if (unlikely(len == rx_burst_size)) {
examples/l3fwd/l3fwd.h:152: send_burst(qconf, rx_burst_size, port);
examples/l3fwd/l3fwd.h-153- len = 0;
examples/l3fwd/l3fwd.h-154- }
--
examples/l3fwd/l3fwd_lpm.c-190- if (qconf->tx_mbufs[portid].len == 0)
examples/l3fwd/l3fwd_lpm.c-191- continue;
examples/l3fwd/l3fwd_lpm.c:192: send_burst(qconf,
examples/l3fwd/l3fwd_lpm.c-193- qconf->tx_mbufs[portid].len,
examples/l3fwd/l3fwd_lpm.c-194- portid);
--
examples/l3fwd/l3fwd_acl.c-1120- if (qconf->tx_mbufs[portid].len == 0)
examples/l3fwd/l3fwd_acl.c-1121- continue;
examples/l3fwd/l3fwd_acl.c:1122: send_burst(qconf,
examples/l3fwd/l3fwd_acl.c-1123- qconf->tx_mbufs[portid].len,
examples/l3fwd/l3fwd_acl.c-1124- portid);
--
examples/l3fwd/l3fwd_common.h-118- if (unlikely(len == MAX_PKT_BURST)) {
examples/l3fwd/l3fwd_common.h-119-
examples/l3fwd/l3fwd_common.h:120: send_burst(qconf, MAX_PKT_BURST, port);
examples/l3fwd/l3fwd_common.h-121-
examples/l3fwd/l3fwd_common.h-122- /* copy rest of the packets into the TX buffer. */
--
examples/l3fwd/l3fwd_fib.c-226- if (qconf->tx_mbufs[portid].len == 0)
examples/l3fwd/l3fwd_fib.c-227- continue;
examples/l3fwd/l3fwd_fib.c:228: send_burst(qconf,
examples/l3fwd/l3fwd_fib.c-229- qconf->tx_mbufs[portid].len,
examples/l3fwd/l3fwd_fib.c-230- portid);
--
examples/l3fwd/l3fwd_em.c-629- if (qconf->tx_mbufs[portid].len == 0)
examples/l3fwd/l3fwd_em.c-630- continue;
examples/l3fwd/l3fwd_em.c:631: send_burst(qconf,
examples/l3fwd/l3fwd_em.c-632- qconf->tx_mbufs[portid].len,
examples/l3fwd/l3fwd_em.c-633- portid);
</shell_result>
Fix TX buffering threshold to use tx_burst_size instead of rx_burst_size.
The send_single_packet function buffers TX packets and triggers transmission when the buffer reaches a threshold. This threshold should be tx_burst_size (a TX-specific configuration), not rx_burst_size (RX configuration). Since these are independently configurable values, using the wrong variable violates semantic correctness and can cause TX to flush at incorrect thresholds.
if (unlikely(len == rx_burst_size)) {
send_burst(qconf, rx_burst_size, port);
Should use tx_burst_size instead.
🤖 Prompt for AI Agents
In examples/l3fwd/l3fwd.h around lines 151-152, the TX buffering threshold uses
rx_burst_size instead of the TX-specific tx_burst_size; change the conditional
and the send_burst call to compare against and pass tx_burst_size so
transmission flushes at the correct TX-configured threshold.
| * Used as ring name, so upper limit is ring name size. | ||
| */ | ||
| static char buffer[sizeof(MP_NODE_RXQ_NAME) + 2]; | ||
| static char buffer[RTE_RING_NAMESIZE]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Script executed:
#!/bin/bash
# First, read the file to see the current state
echo "=== Reading common.h ==="
head -70 examples/server_node_efd/shared/common.h | tail -20
# Check the includes at the top
echo -e "\n=== Checking includes ==="
head -20 examples/server_node_efd/shared/common.h
# Check if rte_ring.h is included anywhere in the project
echo -e "\n=== Searching for rte_ring.h includes ==="
rg -n "rte_ring\.h" examples/server_node_efd/
# Search for RTE_RING_NAMESIZE usage in the file
echo -e "\n=== Checking RTE_RING_NAMESIZE usage ==="
rg -n "RTE_RING_NAMESIZE" examples/server_node_efd/shared/Repository: ovsrobot/dpdk
<shell_result>
Repository: ovsrobot/dpdk
Exit code: 0
stdout:
=== Reading common.h ===
/*
* Given the rx queue name template above, get the queue name
*/
static inline const char *
get_rx_queue_name(unsigned int id)
{
/*
* Buffer for return value. Size calculated by %u being replaced
* by maximum 3 digits (plus an extra byte for safety)
* Used as ring name, so upper limit is ring name size.
*/
static char buffer[RTE_RING_NAMESIZE];
snprintf(buffer, sizeof(buffer), MP_NODE_RXQ_NAME, id);
return buffer;
}
#define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1
=== Checking includes ===
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2016-2017 Intel Corporation
*/
#ifndef _COMMON_H_
#define _COMMON_H_
#include <rte_hash_crc.h>
#include <rte_hash.h>
#define MAX_NODES 16
/*
* Shared port info, including statistics information for display by server.
* Structure will be put in a memzone.
* - All port id values share one cache line as this data will be read-only
* during operation.
* - All rx statistic values share cache lines, as this data is written only
* by the server process. (rare reads by stats display)
* - The tx statistics have values for all ports per cache line, but the stats
* themselves are written by the nodes, so we have a distinct set, on different
=== Searching for rte_ring.h includes ===
examples/server_node_efd/efd_server/main.c:25:#include <rte_ring.h>
examples/server_node_efd/efd_server/init.c:24:#include <rte_ring.h>
examples/server_node_efd/efd_server/init.h:9: * #include <rte_ring.h>
examples/server_node_efd/efd_node/node.c:25:#include <rte_ring.h>
=== Checking RTE_RING_NAMESIZE usage ===
examples/server_node_efd/shared/common.h:63: static char buffer[RTE_RING_NAMESIZE];
</shell_result>
Script executed:
#!/bin/bash
# Find MP_NODE_RXQ_NAME definition
echo "=== Finding MP_NODE_RXQ_NAME definition ==="
rg -n "MP_NODE_RXQ_NAME" examples/server_node_efd/shared/ -B2 -A2
# Check full common.h file length to read it entirely
echo -e "\n=== File length ==="
wc -l examples/server_node_efd/shared/common.h
# Try to find if rte_ring.h is available in DPDK includes and what RTE_RING_NAMESIZE value is
echo -e "\n=== Searching for RTE_RING_NAMESIZE definition ==="
rg -n "define RTE_RING_NAMESIZE" --type=c --type=hRepository: ovsrobot/dpdk
<shell_result>
Repository: ovsrobot/dpdk
Exit code: 0
stdout:
=== Finding MP_NODE_RXQ_NAME definition ===
examples/server_node_efd/shared/common.h-46-
examples/server_node_efd/shared/common.h-47-/* define common names for structures shared between server and node */
examples/server_node_efd/shared/common.h:48:#define MP_NODE_RXQ_NAME "MProc_Node_%u_RX"
examples/server_node_efd/shared/common.h-49-#define PKTMBUF_POOL_NAME "MProc_pktmbuf_pool"
examples/server_node_efd/shared/common.h-50-#define MZ_SHARED_INFO "MProc_shared_info"
--
examples/server_node_efd/shared/common.h-63- static char buffer[RTE_RING_NAMESIZE];
examples/server_node_efd/shared/common.h-64-
examples/server_node_efd/shared/common.h:65: snprintf(buffer, sizeof(buffer), MP_NODE_RXQ_NAME, id);
examples/server_node_efd/shared/common.h-66- return buffer;
examples/server_node_efd/shared/common.h-67-}
=== File length ===
71 examples/server_node_efd/shared/common.h
=== Searching for RTE_RING_NAMESIZE definition ===
lib/ring/rte_ring_core.h:49:#define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
</shell_result>
Script executed:
#!/bin/bash
# Read entire common.h file
echo "=== Full common.h ==="
cat -n examples/server_node_efd/shared/common.h
# Check if rte_ring.h exists and includes rte_ring_core.h
echo -e "\n=== Checking rte_ring.h ==="
find . -name "rte_ring.h" -type f | head -5
# Look for RTE_RING_NAMESIZE full definition
echo -e "\n=== RTE_RING_NAMESIZE definition ==="
rg -n "define RTE_RING_NAMESIZE" -A2 lib/ring/
# Check if rte_hash.h or rte_hash_crc.h includes rte_ring
echo -e "\n=== Check if rte_hash.h includes rte_ring ==="
rg -n "#include.*rte_ring" lib/hash/ 2>/dev/null || echo "No rte_ring includes in hash lib"Repository: ovsrobot/dpdk
<shell_result>
Repository: ovsrobot/dpdk
Exit code: 0
stdout:
=== Full common.h ===
1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2016-2017 Intel Corporation
3 */
4
5 #ifndef _COMMON_H_
6 #define _COMMON_H_
7
8 #include <rte_hash_crc.h>
9 #include <rte_hash.h>
10
11 #define MAX_NODES 16
12 /*
13 * Shared port info, including statistics information for display by server.
14 * Structure will be put in a memzone.
15 * - All port id values share one cache line as this data will be read-only
16 * during operation.
17 * - All rx statistic values share cache lines, as this data is written only
18 * by the server process. (rare reads by stats display)
19 * - The tx statistics have values for all ports per cache line, but the stats
20 * themselves are written by the nodes, so we have a distinct set, on different
21 * cache lines for each node to use.
22 */
23 struct __rte_cache_aligned rx_stats {
24 uint64_t rx[RTE_MAX_ETHPORTS];
25 };
26
27 struct __rte_cache_aligned tx_stats {
28 uint64_t tx[RTE_MAX_ETHPORTS];
29 uint64_t tx_drop[RTE_MAX_ETHPORTS];
30 };
31
32 struct __rte_cache_aligned filter_stats {
33 uint64_t drop;
34 uint64_t passed;
35 };
36
37 struct shared_info {
38 uint8_t num_nodes;
39 uint16_t num_ports;
40 uint32_t num_flows;
41 uint16_t id[RTE_MAX_ETHPORTS];
42 struct rx_stats rx_stats;
43 struct tx_stats tx_stats[MAX_NODES];
44 struct filter_stats filter_stats[MAX_NODES];
45 };
46
47 /* define common names for structures shared between server and node */
48 #define MP_NODE_RXQ_NAME "MProc_Node_%u_RX"
49 #define PKTMBUF_POOL_NAME "MProc_pktmbuf_pool"
50 #define MZ_SHARED_INFO "MProc_shared_info"
51
52 /*
53 * Given the rx queue name template above, get the queue name
54 */
55 static inline const char *
56 get_rx_queue_name(unsigned int id)
57 {
58 /*
59 * Buffer for return value. Size calculated by %u being replaced
60 * by maximum 3 digits (plus an extra byte for safety)
61 * Used as ring name, so upper limit is ring name size.
62 */
63 static char buffer[RTE_RING_NAMESIZE];
64
65 snprintf(buffer, sizeof(buffer), MP_NODE_RXQ_NAME, id);
66 return buffer;
67 }
68
69 #define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1
70
71 #endif
=== Checking rte_ring.h ===
./lib/ring/rte_ring.h
=== RTE_RING_NAMESIZE definition ===
lib/ring/rte_ring_core.h:49:#define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
lib/ring/rte_ring_core.h-50- sizeof(RTE_RING_MZ_PREFIX) + 1)
lib/ring/rte_ring_core.h-51-
=== Check if rte_hash.h includes rte_ring ===
lib/hash/rte_cuckoo_hash.c:23:#include <rte_ring_elem.h>
</shell_result>
Script executed:
#!/bin/bash
# Check if rte_ring.h includes rte_ring_core.h
echo "=== rte_ring.h content (first 30 lines) ==="
head -30 lib/ring/rte_ring.h
# Check rte_hash.h to see if it includes rte_ring
echo -e "\n=== Checking rte_hash.h includes ==="
head -50 lib/hash/rte_hash.h | grep -i "include"
# Get actual RTE_RING_NAMESIZE value by checking RTE_MEMZONE_NAMESIZE
echo -e "\n=== RTE_MEMZONE_NAMESIZE definition ==="
rg -n "define RTE_MEMZONE_NAMESIZE" --type=h
# Check RTE_RING_MZ_PREFIX
echo -e "\n=== RTE_RING_MZ_PREFIX definition ==="
rg -n "define RTE_RING_MZ_PREFIX" --type=hRepository: ovsrobot/dpdk
<shell_result>
Repository: ovsrobot/dpdk
Exit code: 0
stdout:
=== rte_ring.h content (first 30 lines) ===
/* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2010-2020 Intel Corporation
* Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
* All rights reserved.
* Derived from FreeBSD's bufring.h
* Used as BSD-3 Licensed with permission from Kip Macy.
*/
#ifndef _RTE_RING_H_
#define _RTE_RING_H_
/**
* @file
* RTE Ring
*
* The Ring Manager is a fixed-size queue, implemented as a table of
* pointers. Head and tail pointers are modified atomically, allowing
* concurrent access to it. It has the following features:
*
* - FIFO (First In First Out)
* - Maximum size is fixed; the pointers are stored in a table.
* - Lockless implementation.
* - Multi- or single-consumer dequeue.
* - Multi- or single-producer enqueue.
* - Bulk dequeue.
* - Bulk enqueue.
* - Ability to select different sync modes for producer/consumer.
* - Dequeue start/finish (depending on consumer sync modes).
* - Enqueue start/finish (depending on producer sync mode).
=== Checking rte_hash.h includes ===
#include <stdint.h>
#include <stddef.h>
#include <rte_common.h>
#include <rte_rcu_qsbr.h>
=== RTE_MEMZONE_NAMESIZE definition ===
lib/eal/include/rte_memzone.h:50:#define RTE_MEMZONE_NAMESIZE 32 /**< Maximum length of memory zone name.*/
=== RTE_RING_MZ_PREFIX definition ===
lib/ring/rte_ring_core.h:47:#define RTE_RING_MZ_PREFIX "RG_"
</shell_result>
Script executed:
#!/bin/bash
# Double-check: does rte_ring.h include rte_ring_core.h?
echo "=== rte_ring.h includes ==="
grep -n "#include" lib/ring/rte_ring.h | head -20
# Verify if compilation would fail without the include
echo -e "\n=== Check if RTE_RING_NAMESIZE is available without rte_ring.h ==="
rg -n "RTE_RING_NAMESIZE" lib/ --type=h | grep -v "define RTE_RING_NAMESIZE" | head -5
# Calculate actual buffer size needed
echo -e "\n=== Buffer size calculation ==="
python3 << 'EOF'
template = "MProc_Node_%u_RX"
print(f"Template string: {template}")
print(f"Template length without format: {len(template)}")
max_uint = 4294967295
formatted = f"MProc_Node_{max_uint}_RX"
print(f"Max expansion: {formatted}")
print(f"Bytes needed (with null): {len(formatted) + 1}")
namesize = 32
print(f"\nRTE_RING_NAMESIZE = {namesize}")
print(f"Sufficient? {len(formatted) + 1 <= namesize}")
EOFRepository: ovsrobot/dpdk
<shell_result>
Repository: ovsrobot/dpdk
Script execution failed with error: Request timed out after 120000ms (requestId=7edd86a7-df2f-4615-bde4-e11dd23705e8)
</shell_result>
Based on my verification, I found critical issues with the review comment:
The missing <rte_ring.h> include will cause a compilation failure—the code cannot compile without it. The review comment's assertion that it "may work through transitive includes" is incorrect. The symbol RTE_RING_NAMESIZE is not provided by rte_hash.h or rte_hash_crc.h.
Key findings:
rte_hash.hincludes onlyrte_common.handrte_rcu_qsbr.h—no ring headersRTE_RING_NAMESIZEis defined inrte_ring_core.hand requiresrte_ring.hto be included- Without this include, the compiler will report an undefined symbol error at line 63
The buffer sizing analysis in the old comment is also outdated (it mentions "maximum 3 digits" when UINT_MAX actually requires 10 digits), but RTE_RING_NAMESIZE (28 bytes) is sufficient for the expanded template.
Add explicit include of <rte_ring.h> at line 9—compilation will fail without it.
The buffer size change to RTE_RING_NAMESIZE is correct and resolves potential overflow, but requires the proper header inclusion:
#include <rte_hash_crc.h>
#include <rte_hash.h>
+#include <rte_ring.h>Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In examples/server_node_efd/shared/common.h around lines 61 to 63, the code uses
RTE_RING_NAMESIZE but does not include the header that defines it; add an
explicit #include <rte_ring.h> (insert at the top with the other DPDK includes,
e.g., around line 9) so the symbol is defined and compilation succeeds, and
retain the buffer sized to RTE_RING_NAMESIZE to avoid overflow with larger
numeric templates.
NOTE: This is an auto submission for "[v3,1/1] net/mlx5: fix port down in link detection error branch".
See "http://patchwork.dpdk.org/project/dpdk/list/?series=36794" for details.
Summary by Sourcery
Refine burst size handling and link speed configuration in l3fwd-related examples, adjust multiple sample apps and helpers for safer buffer sizing and naming, and update mlx5 and other PMDs’ capabilities handling and error paths to align with newer hardware and API expectations.
New Features:
Bug Fixes:
Enhancements:
Documentation:
Summary by CodeRabbit
Release Notes
New Features
Documentation
Bug Fixes
Chores
✏️ Tip: You can customize this high-level summary in your review settings.