Skip to content

Commit d451994

Browse files
gal-pressmankuba-moo
authored andcommitted
net/mlx5: Fix misidentification of write combining CQE during poll loop
The write combining completion poll loop uses usleep_range() which can sleep much longer than requested due to scheduler latency. Under load, we witnessed a 20ms+ delay until the process was rescheduled, causing the jiffies based timeout to expire while the thread is sleeping. The original do-while loop structure (poll, sleep, check timeout) would exit without a final poll when waking after timeout, missing a CQE that arrived during sleep. Instead of the open-coded while loop, use the kernel's poll_timeout_us() which always performs an additional check after the sleep expiration, and is less error-prone. Note: poll_timeout_us() doesn't accept a sleep range, by passing 10 sleep_us the sleep range effectively changes from 2-10 to 3-10 usecs. Fixes: d98995b ("net/mlx5: Reimplement write combining test") Signed-off-by: Gal Pressman <gal@nvidia.com> Reviewed-by: Jianbo Liu <jianbol@nvidia.com> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> Reviewed-by: Jacob Keller <Jacob.e.keller@intel.com> Link: https://patch.msgid.link/20260218072904.1764634-4-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent ae3cb71 commit d451994

1 file changed

Lines changed: 5 additions & 9 deletions

File tree

  • drivers/net/ethernet/mellanox/mlx5/core

drivers/net/ethernet/mellanox/mlx5/core/wc.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
33

44
#include <linux/io.h>
5+
#include <linux/iopoll.h>
56
#include <linux/mlx5/transobj.h>
67
#include "lib/clock.h"
78
#include "mlx5_core.h"
@@ -15,7 +16,7 @@
1516
#define TEST_WC_NUM_WQES 255
1617
#define TEST_WC_LOG_CQ_SZ (order_base_2(TEST_WC_NUM_WQES))
1718
#define TEST_WC_SQ_LOG_WQ_SZ TEST_WC_LOG_CQ_SZ
18-
#define TEST_WC_POLLING_MAX_TIME_JIFFIES msecs_to_jiffies(100)
19+
#define TEST_WC_POLLING_MAX_TIME_USEC (100 * USEC_PER_MSEC)
1920

2021
struct mlx5_wc_cq {
2122
/* data path - accessed per cqe */
@@ -359,7 +360,6 @@ static int mlx5_wc_poll_cq(struct mlx5_wc_sq *sq)
359360
static void mlx5_core_test_wc(struct mlx5_core_dev *mdev)
360361
{
361362
unsigned int offset = 0;
362-
unsigned long expires;
363363
struct mlx5_wc_sq *sq;
364364
int i, err;
365365

@@ -389,13 +389,9 @@ static void mlx5_core_test_wc(struct mlx5_core_dev *mdev)
389389

390390
mlx5_wc_post_nop(sq, &offset, true);
391391

392-
expires = jiffies + TEST_WC_POLLING_MAX_TIME_JIFFIES;
393-
do {
394-
err = mlx5_wc_poll_cq(sq);
395-
if (err)
396-
usleep_range(2, 10);
397-
} while (mdev->wc_state == MLX5_WC_STATE_UNINITIALIZED &&
398-
time_is_after_jiffies(expires));
392+
poll_timeout_us(mlx5_wc_poll_cq(sq),
393+
mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED, 10,
394+
TEST_WC_POLLING_MAX_TIME_USEC, false);
399395

400396
mlx5_wc_destroy_sq(sq);
401397

0 commit comments

Comments
 (0)