1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-11 14:10:34 +00:00

Correct check for the calibration generation in mlx5en(4).

If generation is cleared due to hardware clock failure, check for it before
the divisor is used.  Actually clear generation when failure occurs.

While there, stop doing the calculations inside the generation loop.  Since
all members of mlx5e_clbr_point are used for calculations, get the
local copy of the structure and use it after generation stabilized.

Submitted by:	kib@
MFC after:	3 days
Sponsored by:	Mellanox Technologies
This commit is contained in:
Hans Petter Selasky 2019-05-08 10:53:47 +00:00
parent 752b8aabfa
commit 945f398487
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=347296
2 changed files with 26 additions and 19 deletions

View File

@ -833,11 +833,15 @@ mlx5e_calibration_callout(void *arg)
next->clbr_hw_prev = curr->clbr_hw_curr;
next->clbr_hw_curr = mlx5e_hw_clock(priv);
if (((next->clbr_hw_curr - curr->clbr_hw_prev) >> MLX5E_TSTMP_PREC) ==
if (((next->clbr_hw_curr - curr->clbr_hw_curr) >> MLX5E_TSTMP_PREC) ==
0) {
if_printf(priv->ifp, "HW failed tstmp frozen %#jx %#jx,"
"disabling\n", next->clbr_hw_curr, curr->clbr_hw_prev);
priv->clbr_done = 0;
if (priv->clbr_done != 0) {
if_printf(priv->ifp, "HW failed tstmp frozen %#jx %#jx,"
"disabling\n",
next->clbr_hw_curr, curr->clbr_hw_prev);
priv->clbr_done = 0;
}
atomic_store_rel_int(&curr->clbr_gen, 0);
return;
}

View File

@ -222,28 +222,31 @@ mlx5e_lro_update_hdr(struct mbuf *mb, struct mlx5_cqe64 *cqe)
static uint64_t
mlx5e_mbuf_tstmp(struct mlx5e_priv *priv, uint64_t hw_tstmp)
{
struct mlx5e_clbr_point *cp;
struct mlx5e_clbr_point *cp, dcp;
uint64_t a1, a2, res;
u_int gen;
do {
cp = &priv->clbr_points[priv->clbr_curr];
gen = atomic_load_acq_int(&cp->clbr_gen);
a1 = (hw_tstmp - cp->clbr_hw_prev) >> MLX5E_TSTMP_PREC;
a2 = (cp->base_curr - cp->base_prev) >> MLX5E_TSTMP_PREC;
res = (a1 * a2) << MLX5E_TSTMP_PREC;
/*
* Divisor cannot be zero because calibration callback
* checks for the condition and disables timestamping
* if clock halted.
*/
res /= (cp->clbr_hw_curr - cp->clbr_hw_prev) >>
MLX5E_TSTMP_PREC;
res += cp->base_prev;
if (gen == 0)
return (0);
dcp = *cp;
atomic_thread_fence_acq();
} while (gen == 0 || gen != cp->clbr_gen);
} while (gen != cp->clbr_gen);
a1 = (hw_tstmp - dcp.clbr_hw_prev) >> MLX5E_TSTMP_PREC;
a2 = (dcp.base_curr - dcp.base_prev) >> MLX5E_TSTMP_PREC;
res = (a1 * a2) << MLX5E_TSTMP_PREC;
/*
* Divisor cannot be zero because calibration callback
* checks for the condition and disables timestamping
* if clock halted.
*/
res /= (dcp.clbr_hw_curr - dcp.clbr_hw_prev) >> MLX5E_TSTMP_PREC;
res += dcp.base_prev;
return (res);
}