svn commit: r347296 - head/sys/dev/mlx5/mlx5_en

Hans Petter Selasky hselasky at FreeBSD.org
Wed May 8 10:53:49 UTC 2019


Author: hselasky
Date: Wed May  8 10:53:47 2019
New Revision: 347296
URL: https://svnweb.freebsd.org/changeset/base/347296

Log:
  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

Modified:
  head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
  head/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c

Modified: head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c	Wed May  8 10:53:25 2019	(r347295)
+++ head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c	Wed May  8 10:53:47 2019	(r347296)
@@ -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;
 	}
 

Modified: head/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c	Wed May  8 10:53:25 2019	(r347295)
+++ head/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c	Wed May  8 10:53:47 2019	(r347296)
@@ -222,28 +222,31 @@ mlx5e_lro_update_hdr(struct mbuf *mb, struct mlx5_cqe6
 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;
+		if (gen == 0)
+			return (0);
+		dcp = *cp;
+		atomic_thread_fence_acq();
+	} while (gen != cp->clbr_gen);
 
-		/*
-		 * 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;
+	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;
 
-		res += cp->base_prev;
-		atomic_thread_fence_acq();
-	} while (gen == 0 || gen != cp->clbr_gen);
+	/*
+	 * 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);
 }
 


More information about the svn-src-all mailing list