Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 5 Dec 2018 13:46:39 +0000 (UTC)
From:      Slava Shwartsman <slavash@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r341566 - in head/sys/dev/mlx5: . mlx5_core
Message-ID:  <201812051346.wB5DkdqM081852@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: slavash
Date: Wed Dec  5 13:46:39 2018
New Revision: 341566
URL: https://svnweb.freebsd.org/changeset/base/341566

Log:
  mlx5: Fixes to allow command polling mode to exist alongside event mode.
  
  A command is either polling or event driven and the mode cannot change
  during execution of a command. Make sure the event handler only handle
  commands which are not polled. This is done by checking the command mode
  in the command handler before completing commands.
  
  Submitted by:   hselasky@
  Approved by:    hselasky (mentor)
  MFC after:      1 week
  Sponsored by:   Mellanox Technologies

Modified:
  head/sys/dev/mlx5/driver.h
  head/sys/dev/mlx5/mlx5_core/mlx5_cmd.c
  head/sys/dev/mlx5/mlx5_core/mlx5_eq.c
  head/sys/dev/mlx5/mlx5_core/mlx5_health.c

Modified: head/sys/dev/mlx5/driver.h
==============================================================================
--- head/sys/dev/mlx5/driver.h	Wed Dec  5 13:46:09 2018	(r341565)
+++ head/sys/dev/mlx5/driver.h	Wed Dec  5 13:46:39 2018	(r341566)
@@ -327,6 +327,11 @@ struct mlx5_traffic_counter {
 	u64         octets;
 };
 
+enum mlx5_cmd_mode {
+	MLX5_CMD_MODE_POLLING,
+	MLX5_CMD_MODE_EVENTS
+};
+
 struct mlx5_cmd_stats {
 	u64		sum;
 	u64		n;
@@ -370,8 +375,9 @@ struct mlx5_cmd {
 	struct workqueue_struct *wq;
 	struct semaphore sem;
 	struct semaphore pages_sem;
-	int	mode;
-	struct mlx5_cmd_work_ent *ent_arr[MLX5_MAX_COMMANDS];
+	enum mlx5_cmd_mode mode;
+	struct mlx5_cmd_work_ent * volatile ent_arr[MLX5_MAX_COMMANDS];
+	volatile enum mlx5_cmd_mode ent_mode[MLX5_MAX_COMMANDS];
 	struct mlx5_cmd_debug dbg;
 	struct cmd_msg_cache cache;
 	int checksum_disabled;
@@ -984,7 +990,7 @@ void mlx5_cq_completion(struct mlx5_core_dev *dev, u32
 void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type);
 void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type);
 struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn);
-void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vector);
+void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vector, enum mlx5_cmd_mode mode);
 void mlx5_cq_event(struct mlx5_core_dev *dev, u32 cqn, int event_type);
 int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
 		       int nent, u64 mask, const char *name, struct mlx5_uar *uar);

Modified: head/sys/dev/mlx5/mlx5_core/mlx5_cmd.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_core/mlx5_cmd.c	Wed Dec  5 13:46:09 2018	(r341565)
+++ head/sys/dev/mlx5/mlx5_core/mlx5_cmd.c	Wed Dec  5 13:46:39 2018	(r341566)
@@ -50,11 +50,6 @@ enum {
 };
 
 enum {
-	CMD_MODE_POLLING,
-	CMD_MODE_EVENTS
-};
-
-enum {
 	NUM_LONG_LISTS	  = 2,
 	NUM_MED_LISTS	  = 64,
 	LONG_LIST_SIZE	  = (2ULL * 1024 * 1024 * 1024 / PAGE_SIZE) * 8 + 16 +
@@ -160,6 +155,8 @@ static int alloc_ent(struct mlx5_cmd_work_ent *ent)
 		ent->busy = 1;
 		ent->idx = ret;
 		clear_bit(ent->idx, &cmd->bitmask);
+		cmd->ent_mode[ent->idx] =
+		    ent->polling ? MLX5_CMD_MODE_POLLING : MLX5_CMD_MODE_EVENTS;
 		cmd->ent_arr[ent->idx] = ent;
 	}
 	spin_unlock_irqrestore(&cmd->alloc_lock, flags);
@@ -172,6 +169,8 @@ static void free_ent(struct mlx5_cmd *cmd, int idx)
 	unsigned long flags;
 
 	spin_lock_irqsave(&cmd->alloc_lock, flags);
+	cmd->ent_arr[idx] = NULL;	/* safety clear */
+	cmd->ent_mode[idx] = MLX5_CMD_MODE_POLLING;	/* reset mode */
 	set_bit(idx, &cmd->bitmask);
 	spin_unlock_irqrestore(&cmd->alloc_lock, flags);
 }
@@ -786,7 +785,7 @@ static void cb_timeout_handler(struct work_struct *wor
         mlx5_core_warn(dev, "%s(0x%x) timeout. Will cause a leak of a command resource\n",
                        mlx5_command_str(msg_to_opcode(ent->in)),
                        msg_to_opcode(ent->in));
-        mlx5_cmd_comp_handler(dev, 1UL << ent->idx);
+        mlx5_cmd_comp_handler(dev, 1UL << ent->idx, MLX5_CMD_MODE_EVENTS);
 }
 
 static void complete_command(struct mlx5_cmd_work_ent *ent)
@@ -897,11 +896,12 @@ static void cmd_work_handler(struct work_struct *work)
 	mlx5_fwp_flush(cmd->cmd_page);
 	iowrite32be(1 << ent->idx, &dev->iseg->cmd_dbell);
 	mmiowb();
-	/* if not in polling don't use ent after this point*/
-	if (cmd->mode == CMD_MODE_POLLING || poll_cmd) {
+
+	/* if not in polling don't use ent after this point */
+	if (poll_cmd) {
 		poll_timeout(ent);
 		/* make sure we read the descriptor after ownership is SW */
-		mlx5_cmd_comp_handler(dev, 1U << ent->idx);
+		mlx5_cmd_comp_handler(dev, 1U << ent->idx, MLX5_CMD_MODE_POLLING);
 	}
 }
 
@@ -938,15 +938,13 @@ static const char *deliv_status_to_str(u8 status)
 static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)
 {
 	int timeout = msecs_to_jiffies(MLX5_CMD_TIMEOUT_MSEC);
-	struct mlx5_cmd *cmd = &dev->cmd;
 	int err;
 
-	if (cmd->mode == CMD_MODE_POLLING || ent->polling) {
+	if (ent->polling) {
 		wait_for_completion(&ent->done);
-		err = ent->ret;
 	} else if (!wait_for_completion_timeout(&ent->done, timeout)) {
                 ent->ret = -ETIMEDOUT;
-                mlx5_cmd_comp_handler(dev, 1UL << ent->idx);
+                mlx5_cmd_comp_handler(dev, 1UL << ent->idx, MLX5_CMD_MODE_EVENTS);
         }
 
         err = ent->ret;
@@ -988,7 +986,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, 
 	if (IS_ERR(ent))
 		return PTR_ERR(ent);
 
-	ent->polling = force_polling;
+	ent->polling = force_polling || (cmd->mode == MLX5_CMD_MODE_POLLING);
 
 	if (!callback)
 		init_completion(&ent->done);
@@ -1158,12 +1156,12 @@ static void mlx5_cmd_change_mod(struct mlx5_core_dev *
 
 void mlx5_cmd_use_events(struct mlx5_core_dev *dev)
 {
-        mlx5_cmd_change_mod(dev, CMD_MODE_EVENTS);
+        mlx5_cmd_change_mod(dev, MLX5_CMD_MODE_EVENTS);
 }
 
 void mlx5_cmd_use_polling(struct mlx5_core_dev *dev)
 {
-        mlx5_cmd_change_mod(dev, CMD_MODE_POLLING);
+        mlx5_cmd_change_mod(dev, MLX5_CMD_MODE_POLLING);
 }
 
 static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg)
@@ -1179,7 +1177,8 @@ static void free_msg(struct mlx5_core_dev *dev, struct
 	}
 }
 
-void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vector_flags)
+void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vector_flags,
+    enum mlx5_cmd_mode cmd_mode)
 {
 	struct mlx5_cmd *cmd = &dev->cmd;
 	struct mlx5_cmd_work_ent *ent;
@@ -1193,7 +1192,13 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, 
 	while (vector != 0) {
 		i = ffs(vector) - 1;
 		vector &= ~(1U << i);
+		/* check command mode */
+		if (cmd->ent_mode[i] != cmd_mode)
+			continue;
 		ent = cmd->ent_arr[i];
+		/* check if command was already handled */
+		if (ent == NULL)
+			continue;
                 if (ent->callback)
                         cancel_delayed_work(&ent->cb_timeout_work);
 		ent->ts2 = ktime_get_ns();
@@ -1545,7 +1550,7 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev)
 
 	mlx5_core_dbg(dev, "descriptor at dma 0x%llx\n", (unsigned long long)(cmd->dma));
 
-	cmd->mode = CMD_MODE_POLLING;
+	cmd->mode = MLX5_CMD_MODE_POLLING;
 
 	err = create_msg_cache(dev);
 	if (err) {

Modified: head/sys/dev/mlx5/mlx5_core/mlx5_eq.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_core/mlx5_eq.c	Wed Dec  5 13:46:09 2018	(r341565)
+++ head/sys/dev/mlx5/mlx5_core/mlx5_eq.c	Wed Dec  5 13:46:39 2018	(r341566)
@@ -254,8 +254,10 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, stru
 			break;
 
 		case MLX5_EVENT_TYPE_CMD:
-			if (dev->state != MLX5_DEVICE_STATE_INTERNAL_ERROR)
-				mlx5_cmd_comp_handler(dev, be32_to_cpu(eqe->data.cmd.vector));
+			if (dev->state != MLX5_DEVICE_STATE_INTERNAL_ERROR) {
+				mlx5_cmd_comp_handler(dev, be32_to_cpu(eqe->data.cmd.vector),
+				    MLX5_CMD_MODE_EVENTS);
+			}
 			break;
 
 		case MLX5_EVENT_TYPE_PORT_CHANGE:

Modified: head/sys/dev/mlx5/mlx5_core/mlx5_health.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_core/mlx5_health.c	Wed Dec  5 13:46:09 2018	(r341565)
+++ head/sys/dev/mlx5/mlx5_core/mlx5_health.c	Wed Dec  5 13:46:39 2018	(r341566)
@@ -141,7 +141,7 @@ static void mlx5_trigger_cmd_completions(struct mlx5_c
 	spin_unlock_irqrestore(&dev->cmd.alloc_lock, flags);
 
 	mlx5_core_dbg(dev, "vector 0x%jx\n", (uintmax_t)vector);
-	mlx5_cmd_comp_handler(dev, vector);
+	mlx5_cmd_comp_handler(dev, vector, MLX5_CMD_MODE_EVENTS);
 	return;
 
 no_trig:



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