Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 May 2019 16:40:12 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r347784 - in stable/12/sys/dev/mlx5: . mlx5_core
Message-ID:  <201905161640.x4GGeCKB077067@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Thu May 16 16:40:12 2019
New Revision: 347784
URL: https://svnweb.freebsd.org/changeset/base/347784

Log:
  MFC r347319:
  Flush command workqueue when command completion is triggered in mlx5core.
  
  Avoid race for command completion when triggering a command completions event.
  Serialize operation by queueing all commands on the same work queue.
  This can happen when healthcare triggers.
  
  Sponsored by:	Mellanox Technologies

Modified:
  stable/12/sys/dev/mlx5/driver.h
  stable/12/sys/dev/mlx5/mlx5_core/mlx5_health.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/dev/mlx5/driver.h
==============================================================================
--- stable/12/sys/dev/mlx5/driver.h	Thu May 16 16:39:37 2019	(r347783)
+++ stable/12/sys/dev/mlx5/driver.h	Thu May 16 16:40:12 2019	(r347784)
@@ -515,6 +515,7 @@ struct mlx5_core_health {
 	struct work_struct		work;
 	struct delayed_work		recover_work;
 	unsigned int			last_reset_req;
+	struct work_struct		work_cmd_completion;
 };
 
 #ifdef RATELIMIT

Modified: stable/12/sys/dev/mlx5/mlx5_core/mlx5_health.c
==============================================================================
--- stable/12/sys/dev/mlx5/mlx5_core/mlx5_health.c	Thu May 16 16:39:37 2019	(r347783)
+++ stable/12/sys/dev/mlx5/mlx5_core/mlx5_health.c	Thu May 16 16:40:12 2019	(r347784)
@@ -135,8 +135,10 @@ static bool sensor_fw_synd_rfr(struct mlx5_core_dev *d
 	return rfr && synd;
 }
 
-static void mlx5_trigger_cmd_completions(struct mlx5_core_dev *dev)
+static void mlx5_trigger_cmd_completions(struct work_struct *work)
 {
+	struct mlx5_core_dev *dev =
+	    container_of(work, struct mlx5_core_dev, priv.health.work_cmd_completion);
 	unsigned long flags;
 	u64 vector;
 
@@ -271,7 +273,15 @@ void mlx5_enter_error_state(struct mlx5_core_dev *dev,
 			return;
 		if (!force)
 			mlx5_core_err(dev, "internal state error detected\n");
-		mlx5_trigger_cmd_completions(dev);
+
+		/*
+		 * Queue the command completion handler on the command
+		 * work queue to avoid racing with the real command
+		 * completion handler and then wait for it to
+		 * complete:
+		 */
+		queue_work(dev->cmd.wq, &dev->priv.health.work_cmd_completion);
+		flush_workqueue(dev->cmd.wq);
 	}
 
 	mutex_lock(&dev->intf_state_mutex);
@@ -693,6 +703,7 @@ int mlx5_health_init(struct mlx5_core_dev *dev)
 	spin_lock_init(&health->wq_lock);
 	INIT_WORK(&health->work, health_care);
 	INIT_WORK(&health->work_watchdog, health_watchdog);
+	INIT_WORK(&health->work_cmd_completion, mlx5_trigger_cmd_completions);
 	INIT_DELAYED_WORK(&health->recover_work, health_recover);
 
 	return 0;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905161640.x4GGeCKB077067>