Author: hselasky
Date: Wed May  8 11:07:20 2019
New Revision: 347319
URL: https://svnweb.freebsd.org/changeset/base/347319

Log:
  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.
  
  MFC after:    3 days
  Sponsored by: Mellanox Technologies

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

Modified: head/sys/dev/mlx5/driver.h
==============================================================================
--- head/sys/dev/mlx5/driver.h  Wed May  8 11:07:00 2019        (r347318)
+++ head/sys/dev/mlx5/driver.h  Wed May  8 11:07:20 2019        (r347319)
@@ -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: head/sys/dev/mlx5/mlx5_core/mlx5_health.c
==============================================================================
--- head/sys/dev/mlx5/mlx5_core/mlx5_health.c   Wed May  8 11:07:00 2019        
(r347318)
+++ head/sys/dev/mlx5/mlx5_core/mlx5_health.c   Wed May  8 11:07:20 2019        
(r347319)
@@ -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;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to