mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
net/mlx5e: Fix misidentification of ASO CQE during poll loop
The ASO 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 read_poll_timeout() which always performs an additional check after the sleep expiration, and is less error-prone. Note: read_poll_timeout() doesn't accept a sleep range, by passing 10 sleep_us the sleep range effectively changes from 2-10 to 3-10 usecs. Fixes:739cfa3451("net/mlx5: Make ASO poll CQ usable in atomic context") Fixes:7e3fce82d9("net/mlx5e: Overcome slow response for first macsec ASO WQE") 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-3-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
47bf2e8138
commit
ae3cb71e6c
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
||||
// Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/math64.h>
|
||||
#include "lib/aso.h"
|
||||
#include "en/tc/post_act.h"
|
||||
|
|
@ -115,7 +116,6 @@ mlx5e_tc_meter_modify(struct mlx5_core_dev *mdev,
|
|||
struct mlx5e_flow_meters *flow_meters;
|
||||
u8 cir_man, cir_exp, cbs_man, cbs_exp;
|
||||
struct mlx5_aso_wqe *aso_wqe;
|
||||
unsigned long expires;
|
||||
struct mlx5_aso *aso;
|
||||
u64 rate, burst;
|
||||
u8 ds_cnt;
|
||||
|
|
@ -187,12 +187,8 @@ mlx5e_tc_meter_modify(struct mlx5_core_dev *mdev,
|
|||
mlx5_aso_post_wqe(aso, true, &aso_wqe->ctrl);
|
||||
|
||||
/* With newer FW, the wait for the first ASO WQE is more than 2us, put the wait 10ms. */
|
||||
expires = jiffies + msecs_to_jiffies(10);
|
||||
do {
|
||||
err = mlx5_aso_poll_cq(aso, true);
|
||||
if (err)
|
||||
usleep_range(2, 10);
|
||||
} while (err && time_is_after_jiffies(expires));
|
||||
read_poll_timeout(mlx5_aso_poll_cq, err, !err, 10, 10 * USEC_PER_MSEC,
|
||||
false, aso, true);
|
||||
mutex_unlock(&flow_meters->aso_lock);
|
||||
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <linux/mlx5/mlx5_ifc.h>
|
||||
#include <linux/xarray.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/iopoll.h>
|
||||
|
||||
#include "en.h"
|
||||
#include "lib/aso.h"
|
||||
|
|
@ -1397,7 +1398,6 @@ static int macsec_aso_query(struct mlx5_core_dev *mdev, struct mlx5e_macsec *mac
|
|||
struct mlx5e_macsec_aso *aso;
|
||||
struct mlx5_aso_wqe *aso_wqe;
|
||||
struct mlx5_aso *maso;
|
||||
unsigned long expires;
|
||||
int err;
|
||||
|
||||
aso = &macsec->aso;
|
||||
|
|
@ -1411,12 +1411,8 @@ static int macsec_aso_query(struct mlx5_core_dev *mdev, struct mlx5e_macsec *mac
|
|||
macsec_aso_build_wqe_ctrl_seg(aso, &aso_wqe->aso_ctrl, NULL);
|
||||
|
||||
mlx5_aso_post_wqe(maso, false, &aso_wqe->ctrl);
|
||||
expires = jiffies + msecs_to_jiffies(10);
|
||||
do {
|
||||
err = mlx5_aso_poll_cq(maso, false);
|
||||
if (err)
|
||||
usleep_range(2, 10);
|
||||
} while (err && time_is_after_jiffies(expires));
|
||||
read_poll_timeout(mlx5_aso_poll_cq, err, !err, 10, 10 * USEC_PER_MSEC,
|
||||
false, maso, false);
|
||||
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user